pc.c 225 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317
  1. // $Id: pc.c 101 2004-12-13 7:23:07 PM Celestia $
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6. #include <time.h>
  7. #include "socket.h" // [Valaris]
  8. #include "timer.h"
  9. #include "db.h"
  10. #include "malloc.h"
  11. #include "map.h"
  12. #include "chrif.h"
  13. #include "clif.h"
  14. #include "intif.h"
  15. #include "pc.h"
  16. #include "npc.h"
  17. #include "mob.h"
  18. #include "pet.h"
  19. #include "itemdb.h"
  20. #include "script.h"
  21. #include "battle.h"
  22. #include "skill.h"
  23. #include "party.h"
  24. #include "guild.h"
  25. #include "chat.h"
  26. #include "trade.h"
  27. #include "storage.h"
  28. #include "vending.h"
  29. #include "nullpo.h"
  30. #include "atcommand.h"
  31. #include "log.h"
  32. #include "showmsg.h"
  33. #ifndef TXT_ONLY // mail system [Valaris]
  34. #include "mail.h"
  35. #endif
  36. #ifdef MEMWATCH
  37. #include "memwatch.h"
  38. #endif
  39. #define PVP_CALCRANK_INTERVAL 1000 // PVP順位計算の間隔
  40. #define STATE_BLIND 0x10
  41. static int max_weight_base[MAX_PC_CLASS];
  42. static int hp_coefficient[MAX_PC_CLASS];
  43. static int hp_coefficient2[MAX_PC_CLASS];
  44. static int hp_sigma_val[MAX_PC_CLASS][MAX_LEVEL];
  45. static int sp_coefficient[MAX_PC_CLASS];
  46. static int aspd_base[MAX_PC_CLASS][20];
  47. static char job_bonus[3][MAX_PC_CLASS][MAX_LEVEL];
  48. static int exp_table[14][MAX_LEVEL];
  49. static char statp[255][7];
  50. // h-files are for declarations, not for implementations... [Shinomori]
  51. struct skill_tree_entry skill_tree[3][MAX_PC_CLASS][100];
  52. // timer for night.day implementation
  53. int day_timer_tid;
  54. int night_timer_tid;
  55. static int atkmods[3][20]; // 武器ATKサイズ修正(size_fix.txt)
  56. static int refinebonus[5][3]; // 精?ボ?ナステ?ブル(refine_db.txt)
  57. static int percentrefinery[5][10]; // 精?成功率(refine_db.txt)
  58. static int dirx[8]={0,-1,-1,-1,0,1,1,1};
  59. static int diry[8]={1,1,0,-1,-1,-1,0,1};
  60. static unsigned int equip_pos[11]={0x0080,0x0008,0x0040,0x0004,0x0001,0x0200,0x0100,0x0010,0x0020,0x0002,0x8000};
  61. //static struct dbt *gm_account_db;
  62. static struct gm_account *gm_account = NULL;
  63. static int GM_num = 0;
  64. int pc_isGM(struct map_session_data *sd) {
  65. // struct gm_account *p;
  66. int i;
  67. nullpo_retr(0, sd);
  68. if(sd->bl.type!=BL_PC )
  69. return 0;
  70. /* p = numdb_search(gm_account_db, sd->status.account_id);
  71. if (p == NULL)
  72. return 0;
  73. return p->level;*/
  74. //For console [Wizputer]
  75. if ( sd->fd == 0 )
  76. return 99;
  77. for(i = 0; i < GM_num; i++)
  78. if (gm_account[i].account_id == sd->status.account_id)
  79. return gm_account[i].level;
  80. return 0;
  81. }
  82. int pc_iskiller(struct map_session_data *src, struct map_session_data *target) {
  83. nullpo_retr(0, src);
  84. if(src->bl.type!=BL_PC )
  85. return 0;
  86. if (src->special_state.killer)
  87. return 1;
  88. if(target->bl.type!=BL_PC )
  89. return 0;
  90. if (target->special_state.killable)
  91. return 1;
  92. return 0;
  93. }
  94. int pc_set_gm_level(int account_id, int level) {
  95. int i;
  96. for (i = 0; i < GM_num; i++) {
  97. if (account_id == gm_account[i].account_id) {
  98. gm_account[i].level = level;
  99. return 0;
  100. }
  101. }
  102. GM_num++;
  103. gm_account = aRealloc(gm_account, sizeof(struct gm_account) * GM_num);
  104. gm_account[GM_num - 1].account_id = account_id;
  105. gm_account[GM_num - 1].level = level;
  106. return 0;
  107. }
  108. int pc_getrefinebonus(int lv, int type) {
  109. if (lv >= 0 && lv < 5 && type >= 0 && type < 3)
  110. return refinebonus[lv][type];
  111. return 0;
  112. }
  113. static int distance(int x0, int y0, int x1, int y1) {
  114. int dx, dy;
  115. dx = abs(x0-x1);
  116. dy = abs(y0-y1);
  117. return dx>dy ? dx : dy;
  118. }
  119. static int pc_invincible_timer(int tid,unsigned int tick,int id,int data) {
  120. struct map_session_data *sd;
  121. if( (sd=(struct map_session_data *)map_id2sd(id)) == NULL || sd->bl.type!=BL_PC )
  122. return 1;
  123. if(sd->invincible_timer != tid){
  124. if(battle_config.error_log)
  125. printf("invincible_timer %d != %d\n",sd->invincible_timer,tid);
  126. return 0;
  127. }
  128. sd->invincible_timer=-1;
  129. return 0;
  130. }
  131. int pc_setinvincibletimer(struct map_session_data *sd,int val) {
  132. nullpo_retr(0, sd);
  133. if(sd->invincible_timer != -1)
  134. delete_timer(sd->invincible_timer,pc_invincible_timer);
  135. sd->invincible_timer = add_timer(gettick()+val,pc_invincible_timer,sd->bl.id,0);
  136. return 0;
  137. }
  138. int pc_delinvincibletimer(struct map_session_data *sd) {
  139. nullpo_retr(0, sd);
  140. if(sd->invincible_timer != -1) {
  141. delete_timer(sd->invincible_timer,pc_invincible_timer);
  142. sd->invincible_timer = -1;
  143. }
  144. return 0;
  145. }
  146. static int pc_spiritball_timer(int tid,unsigned int tick,int id,int data) {
  147. struct map_session_data *sd;
  148. if( (sd=(struct map_session_data *)map_id2sd(id)) == NULL || sd->bl.type!=BL_PC )
  149. return 1;
  150. if(sd->spirit_timer[0] != tid){
  151. if(battle_config.error_log)
  152. printf("spirit_timer %d != %d\n",sd->spirit_timer[0],tid);
  153. return 0;
  154. }
  155. if(sd->spiritball <= 0) {
  156. if(battle_config.error_log)
  157. printf("Spiritballs are already 0 when pc_spiritball_timer gets called");
  158. sd->spiritball = 0;
  159. return 0;
  160. }
  161. sd->spiritball--;
  162. memcpy( &sd->spirit_timer[0], &sd->spirit_timer[1], sizeof(sd->spirit_timer[0]) * sd->spiritball );
  163. sd->spirit_timer[sd->spiritball]=-1;
  164. clif_spiritball(sd);
  165. return 0;
  166. }
  167. int pc_addspiritball(struct map_session_data *sd,int interval,int max) {
  168. nullpo_retr(0, sd);
  169. if(max > MAX_SKILL_LEVEL)
  170. max = MAX_SKILL_LEVEL;
  171. if(sd->spiritball < 0)
  172. sd->spiritball = 0;
  173. if(sd->spiritball >= max) {
  174. if(sd->spirit_timer[0] != -1)
  175. delete_timer(sd->spirit_timer[0],pc_spiritball_timer);
  176. memcpy( &sd->spirit_timer[0], &sd->spirit_timer[1], sizeof(sd->spirit_timer[0]) * (sd->spiritball - 1));
  177. } else
  178. sd->spiritball++;
  179. sd->spirit_timer[sd->spiritball-1] = add_timer(gettick()+interval,pc_spiritball_timer,sd->bl.id,0);
  180. clif_spiritball(sd);
  181. return 0;
  182. }
  183. int pc_delspiritball(struct map_session_data *sd,int count,int type) {
  184. int i;
  185. nullpo_retr(0, sd);
  186. if(sd->spiritball <= 0) {
  187. sd->spiritball = 0;
  188. return 0;
  189. }
  190. if(count > sd->spiritball)
  191. count = sd->spiritball;
  192. sd->spiritball -= count;
  193. if(count > MAX_SKILL_LEVEL)
  194. count = MAX_SKILL_LEVEL;
  195. for(i=0;i<count;i++) {
  196. if(sd->spirit_timer[i] != -1) {
  197. delete_timer(sd->spirit_timer[i],pc_spiritball_timer);
  198. sd->spirit_timer[i] = -1;
  199. }
  200. }
  201. for(i=count;i<MAX_SKILL_LEVEL;i++) {
  202. sd->spirit_timer[i-count] = sd->spirit_timer[i];
  203. sd->spirit_timer[i] = -1;
  204. }
  205. if(!type)
  206. clif_spiritball(sd);
  207. return 0;
  208. }
  209. int pc_setrestartvalue(struct map_session_data *sd,int type) {
  210. //?生や養子の場合の元の職業を算出する
  211. struct pc_base_job s_class;
  212. nullpo_retr(0, sd);
  213. s_class = pc_calc_base_job(sd->status.class_);
  214. //-----------------------
  215. // 死亡した
  216. if(sd->special_state.restart_full_recover || // オシリスカ?ド
  217. sd->state.snovice_flag == 4) { // [Celest]
  218. sd->status.hp=sd->status.max_hp;
  219. sd->status.sp=sd->status.max_sp;
  220. if (sd->state.snovice_flag == 4) {
  221. sd->state.snovice_flag = 0;
  222. skill_status_change_start(&sd->bl,SkillStatusChangeTable[MO_STEELBODY],1,0,0,0,skill_get_time(MO_STEELBODY,1),0 );
  223. }
  224. }
  225. else {
  226. if(s_class.job == 0 && battle_config.restart_hp_rate < 50) { //ノビは半分回復
  227. sd->status.hp=(sd->status.max_hp)/2;
  228. }
  229. else {
  230. if(battle_config.restart_hp_rate <= 0)
  231. sd->status.hp = 1;
  232. else {
  233. sd->status.hp = sd->status.max_hp * battle_config.restart_hp_rate /100;
  234. if(sd->status.hp <= 0)
  235. sd->status.hp = 1;
  236. }
  237. }
  238. if(battle_config.restart_sp_rate > 0) {
  239. int sp = sd->status.max_sp * battle_config.restart_sp_rate /100;
  240. if(sd->status.sp < sp)
  241. sd->status.sp = sp;
  242. }
  243. }
  244. if(type&1)
  245. clif_updatestatus(sd,SP_HP);
  246. if(type&1)
  247. clif_updatestatus(sd,SP_SP);
  248. /* removed exp penalty on spawn [Valaris] */
  249. if(type&2 && sd->status.class_ != 0 && battle_config.zeny_penalty > 0 && !map[sd->bl.m].flag.nozenypenalty) {
  250. int zeny = (int)((double)sd->status.zeny * (double)battle_config.zeny_penalty / 10000.);
  251. if(zeny < 1) zeny = 1;
  252. sd->status.zeny -= zeny;
  253. if(sd->status.zeny < 0) sd->status.zeny = 0;
  254. clif_updatestatus(sd,SP_ZENY);
  255. }
  256. return 0;
  257. }
  258. /*==========================================
  259. * 自分をロックしているMOBの?を?える(foreachclient)
  260. *------------------------------------------
  261. */
  262. static int pc_counttargeted_sub(struct block_list *bl,va_list ap)
  263. {
  264. int id,*c,target_lv;
  265. struct block_list *src;
  266. nullpo_retr(0, bl);
  267. nullpo_retr(0, ap);
  268. id=va_arg(ap,int);
  269. nullpo_retr(0, c=va_arg(ap,int *));
  270. src=va_arg(ap,struct block_list *);
  271. target_lv=va_arg(ap,int);
  272. if(id == bl->id || (src && id == src->id)) return 0;
  273. if(bl->type == BL_PC) {
  274. struct map_session_data *sd=(struct map_session_data *)bl;
  275. if( sd && sd->attacktarget == id && sd->attacktimer != -1 && sd->attacktarget_lv >= target_lv)
  276. (*c)++;
  277. }
  278. else if(bl->type == BL_MOB) {
  279. struct mob_data *md = (struct mob_data *)bl;
  280. if(md && md->target_id == id && md->timer != -1 && md->state.state == MS_ATTACK && md->target_lv >= target_lv)
  281. (*c)++;
  282. //printf("md->target_lv:%d, target_lv:%d\n",((struct mob_data *)bl)->target_lv,target_lv);
  283. }
  284. return 0;
  285. }
  286. int pc_counttargeted(struct map_session_data *sd,struct block_list *src,int target_lv)
  287. {
  288. int c=0;
  289. map_foreachinarea(pc_counttargeted_sub, sd->bl.m,
  290. sd->bl.x-AREA_SIZE,sd->bl.y-AREA_SIZE,
  291. sd->bl.x+AREA_SIZE,sd->bl.y+AREA_SIZE,0,sd->bl.id,&c,src,target_lv);
  292. return c;
  293. }
  294. /*==========================================
  295. * ロ?カルプロトタイプ宣言 (必要な物のみ)
  296. *------------------------------------------
  297. */
  298. static int pc_walktoxy_sub(struct map_session_data *);
  299. /*==========================================
  300. * saveに必要なステ?タス修正を行なう
  301. *------------------------------------------
  302. */
  303. int pc_makesavestatus(struct map_session_data *sd)
  304. {
  305. int i;
  306. nullpo_retr(0, sd);
  307. // 秒フ色は色?弊害が多いので保存?象にはしない
  308. if(!battle_config.save_clothcolor)
  309. sd->status.clothes_color=0;
  310. // 死亡?態だったのでhpを1、位置をセ?ブ場所に?更
  311. if(pc_isdead(sd)){
  312. pc_setrestartvalue(sd,0);
  313. memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point));
  314. } else {
  315. memcpy(sd->status.last_point.map,sd->mapname,24);
  316. sd->status.last_point.x = sd->bl.x;
  317. sd->status.last_point.y = sd->bl.y;
  318. }
  319. // セ?ブ禁止マップだったので指定位置に移動
  320. if(map[sd->bl.m].flag.nosave){
  321. struct map_data *m=&map[sd->bl.m];
  322. if(strcmp(m->save.map,"SavePoint")==0)
  323. memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point));
  324. else
  325. memcpy(&sd->status.last_point,&m->save,sizeof(sd->status.last_point));
  326. }
  327. //マナ?ポイントがプラスだった場合0に
  328. if(battle_config.muting_players && sd->status.manner > 0)
  329. sd->status.manner = 0;
  330. // Make sure all the skills are in the correct condition
  331. // before persisting to the backend.. [MouseJstr]
  332. for(i=0;i<MAX_SKILL;i++){
  333. if(sd->status.skill[i].flag == 13){
  334. sd->status.skill[i].id=0;
  335. sd->status.skill[i].lv=0;
  336. sd->status.skill[i].flag=0;
  337. }
  338. }
  339. return 0;
  340. }
  341. /*==========================================
  342. * 接?暫フ初期化
  343. *------------------------------------------
  344. */
  345. int pc_setnewpc(struct map_session_data *sd, int account_id, int char_id, int login_id1, int client_tick, int sex, int fd) {
  346. nullpo_retr(0, sd);
  347. sd->bl.id = account_id;
  348. sd->char_id = char_id;
  349. sd->login_id1 = login_id1;
  350. sd->login_id2 = 0; // at this point, we can not know the value :(
  351. sd->client_tick = client_tick;
  352. sd->sex = sex;
  353. sd->state.auth = 0;
  354. sd->bl.type = BL_PC;
  355. sd->canact_tick = sd->canmove_tick = gettick();
  356. sd->canlog_tick = gettick();
  357. sd->state.waitingdisconnect = 0;
  358. return 0;
  359. }
  360. int pc_equippoint(struct map_session_data *sd,int n)
  361. {
  362. int ep = 0;
  363. //?生や養子の場合の元の職業を算出する
  364. struct pc_base_job s_class;
  365. nullpo_retr(0, sd);
  366. s_class = pc_calc_base_job(sd->status.class_);
  367. if(sd->inventory_data[n]) {
  368. ep = sd->inventory_data[n]->equip;
  369. if(sd->inventory_data[n]->look == 1 || sd->inventory_data[n]->look == 2 || sd->inventory_data[n]->look == 6) {
  370. if(ep == 2 && (pc_checkskill(sd,AS_LEFT) > 0 || s_class.job == 12))
  371. return 34;
  372. }
  373. }
  374. return ep;
  375. }
  376. int pc_setinventorydata(struct map_session_data *sd)
  377. {
  378. int i,id;
  379. nullpo_retr(0, sd);
  380. for(i=0;i<MAX_INVENTORY;i++) {
  381. id = sd->status.inventory[i].nameid;
  382. sd->inventory_data[i] = itemdb_search(id);
  383. }
  384. return 0;
  385. }
  386. int pc_calcweapontype(struct map_session_data *sd)
  387. {
  388. nullpo_retr(0, sd);
  389. if(sd->weapontype1 != 0 && sd->weapontype2 == 0)
  390. sd->status.weapon = sd->weapontype1;
  391. if(sd->weapontype1 == 0 && sd->weapontype2 != 0)// 左手武器 Only
  392. sd->status.weapon = sd->weapontype2;
  393. else if(sd->weapontype1 == 1 && sd->weapontype2 == 1)// ?短?
  394. sd->status.weapon = 0x11;
  395. else if(sd->weapontype1 == 2 && sd->weapontype2 == 2)// ??手?
  396. sd->status.weapon = 0x12;
  397. else if(sd->weapontype1 == 6 && sd->weapontype2 == 6)// ??手斧
  398. sd->status.weapon = 0x13;
  399. else if( (sd->weapontype1 == 1 && sd->weapontype2 == 2) ||
  400. (sd->weapontype1 == 2 && sd->weapontype2 == 1) ) // 短? - ?手?
  401. sd->status.weapon = 0x14;
  402. else if( (sd->weapontype1 == 1 && sd->weapontype2 == 6) ||
  403. (sd->weapontype1 == 6 && sd->weapontype2 == 1) ) // 短? - 斧
  404. sd->status.weapon = 0x15;
  405. else if( (sd->weapontype1 == 2 && sd->weapontype2 == 6) ||
  406. (sd->weapontype1 == 6 && sd->weapontype2 == 2) ) // ?手? - 斧
  407. sd->status.weapon = 0x16;
  408. else
  409. sd->status.weapon = sd->weapontype1;
  410. return 0;
  411. }
  412. int pc_setequipindex(struct map_session_data *sd)
  413. {
  414. int i,j;
  415. nullpo_retr(0, sd);
  416. for(i=0;i<11;i++)
  417. sd->equip_index[i] = -1;
  418. for(i=0;i<MAX_INVENTORY;i++) {
  419. if(sd->status.inventory[i].nameid <= 0)
  420. continue;
  421. if(sd->status.inventory[i].equip) {
  422. for(j=0;j<11;j++)
  423. if(sd->status.inventory[i].equip & equip_pos[j])
  424. sd->equip_index[j] = i;
  425. if(sd->status.inventory[i].equip & 0x0002) {
  426. if(sd->inventory_data[i])
  427. sd->weapontype1 = sd->inventory_data[i]->look;
  428. else
  429. sd->weapontype1 = 0;
  430. }
  431. if(sd->status.inventory[i].equip & 0x0020) {
  432. if(sd->inventory_data[i]) {
  433. if(sd->inventory_data[i]->type == 4) {
  434. if(sd->status.inventory[i].equip == 0x0020)
  435. sd->weapontype2 = sd->inventory_data[i]->look;
  436. else
  437. sd->weapontype2 = 0;
  438. }
  439. else
  440. sd->weapontype2 = 0;
  441. }
  442. else
  443. sd->weapontype2 = 0;
  444. }
  445. }
  446. }
  447. pc_calcweapontype(sd);
  448. return 0;
  449. }
  450. int pc_isequip(struct map_session_data *sd,int n)
  451. {
  452. struct item_data *item;
  453. struct status_change *sc_data;
  454. //?生や養子の場合の元の職業を算出する
  455. nullpo_retr(0, sd);
  456. item = sd->inventory_data[n];
  457. sc_data = battle_get_sc_data(&sd->bl);
  458. //s_class = pc_calc_base_job(sd->status.class);
  459. if( battle_config.gm_allequip>0 && pc_isGM(sd)>=battle_config.gm_allequip )
  460. return 1;
  461. if(item == NULL)
  462. return 0;
  463. if(item->sex != 2 && sd->status.sex != item->sex)
  464. return 0;
  465. if(item->elv > 0 && sd->status.base_level < item->elv)
  466. return 0;
  467. // -- moonsoul (below statement substituted for commented out version further below
  468. // as it allows all advanced classes to equip items their normal versions
  469. // could equip)
  470. //
  471. if(((sd->status.class_==13 || sd->status.class_==4014) && ((1<<7)&item->class_) == 0) || // have mounted classes use unmounted equipment [Valaris]
  472. ((sd->status.class_==21 || sd->status.class_==4022) && ((1<<14)&item->class_) == 0))
  473. return 0;
  474. if(sd->status.class_!=13 && sd->status.class_!=4014 && sd->status.class_!=21 && sd->status.class_!=4022)
  475. if((sd->status.class_<=4000 && ((1<<sd->status.class_)&item->class_) == 0) || (sd->status.class_>4000 && sd->status.class_<4023 && ((1<<(sd->status.class_-4001))&item->class_) == 0) ||
  476. (sd->status.class_>=4023 && ((1<<(sd->status.class_-4023))&item->class_) == 0))
  477. return 0;
  478. // if(((1<<sd->status.class_)&item->class_) == 0)
  479. // return 0;
  480. if(map[sd->bl.m].flag.pvp && (item->flag.no_equip==1 || item->flag.no_equip==3))
  481. return 0;
  482. if(map[sd->bl.m].flag.gvg && (item->flag.no_equip==2 || item->flag.no_equip==3))
  483. return 0;
  484. if(item->equip & 0x0002 && sc_data && sc_data[SC_STRIPWEAPON].timer != -1)
  485. return 0;
  486. if(item->equip & 0x0020 && sc_data && sc_data[SC_STRIPSHIELD].timer != -1)
  487. return 0;
  488. if(item->equip & 0x0010 && sc_data && sc_data[SC_STRIPARMOR].timer != -1)
  489. return 0;
  490. if(item->equip & 0x0100 && sc_data && sc_data[SC_STRIPHELM].timer != -1)
  491. return 0;
  492. return 1;
  493. }
  494. //装備破壊
  495. int pc_break_equip(struct map_session_data *sd, unsigned short where)
  496. {
  497. struct item_data* item;
  498. int i;
  499. int sc;
  500. char output[255];
  501. if(sd == NULL)
  502. return -1;
  503. if(sd->unbreakable_equip & where)
  504. return 0;
  505. switch (where) {
  506. case EQP_WEAPON:
  507. sc = SC_CP_WEAPON;
  508. break;
  509. case EQP_ARMOR:
  510. sc = SC_CP_ARMOR;
  511. break;
  512. case EQP_SHIELD:
  513. sc = SC_CP_SHIELD;
  514. break;
  515. case EQP_HELM:
  516. sc = SC_CP_HELM;
  517. break;
  518. default:
  519. return 0;
  520. }
  521. if( sd->sc_data && sd->sc_data[sc].timer != -1 )
  522. return 0;
  523. for (i=0;i<MAX_INVENTORY;i++) {
  524. if (sd->status.inventory[i].equip & where) {
  525. item=sd->inventory_data[i];
  526. sd->status.inventory[i].attribute = 1;
  527. pc_unequipitem(sd,i,0);
  528. sprintf(output, "%s has broken.",item->jname);
  529. clif_emotion(&sd->bl,23);
  530. clif_displaymessage(sd->fd, output);
  531. clif_equiplist(sd);
  532. break;
  533. }
  534. }
  535. return 0;
  536. }
  537. /*==========================================
  538. * Weapon Breaking [Valaris]
  539. *------------------------------------------
  540. */
  541. int pc_breakweapon(struct map_session_data *sd)
  542. {
  543. struct item_data* item;
  544. char output[255];
  545. int i;
  546. if(sd==NULL)
  547. return -1;
  548. if(sd->unbreakable>=rand()%100)
  549. return 0;
  550. if(sd->sc_count && sd->sc_data[SC_CP_WEAPON].timer != -1)
  551. return 0;
  552. for(i=0;i<MAX_INVENTORY;i++){
  553. if(sd->status.inventory[i].equip && sd->status.inventory[i].equip & 0x0002 && !sd->status.inventory[i].attribute==1){
  554. item=sd->inventory_data[i];
  555. sd->status.inventory[i].attribute=1;
  556. pc_unequipitem(sd,i,3);
  557. sprintf(output, "%s has broken.",item->jname);
  558. clif_emotion(&sd->bl,23);
  559. clif_displaymessage(sd->fd, output);
  560. clif_equiplist(sd);
  561. return 1;
  562. }
  563. }
  564. return 0;
  565. }
  566. /*==========================================
  567. * Armor Breaking [Valaris]
  568. *------------------------------------------
  569. */
  570. int pc_breakarmor(struct map_session_data *sd)
  571. {
  572. struct item_data* item;
  573. char output[255];
  574. int i;
  575. if(sd==NULL)
  576. return -1;
  577. if(sd->unbreakable>=rand()%100)
  578. return 0;
  579. if(sd->sc_count && sd->sc_data[SC_CP_ARMOR].timer != -1)
  580. return 0;
  581. for(i=0;i<MAX_INVENTORY;i++){
  582. if(sd->status.inventory[i].equip && sd->status.inventory[i].equip & 0x0010 && !sd->status.inventory[i].attribute==1){
  583. item=sd->inventory_data[i];
  584. sd->status.inventory[i].attribute=1;
  585. pc_unequipitem(sd,i,3);
  586. sprintf(output, "%s has broken.",item->jname);
  587. clif_emotion(&sd->bl,23);
  588. clif_displaymessage(sd->fd, output);
  589. clif_equiplist(sd);
  590. }
  591. }
  592. return 0;
  593. }
  594. /*==========================================
  595. * session idに問題無し
  596. * char鯖から送られてきたステ?タスを設定
  597. *------------------------------------------
  598. */
  599. int pc_authok(int id, int login_id2, time_t connect_until_time, struct mmo_charstatus *st)
  600. {
  601. struct map_session_data *sd = NULL;
  602. struct party *p;
  603. struct guild *g;
  604. int i;
  605. unsigned long tick = gettick();
  606. sd = map_id2sd(id);
  607. nullpo_retr(1, sd);
  608. // check if double login occured
  609. if(sd->new_fd){
  610. // 2重login状態だったので、両方落す
  611. clif_authfail_fd(sd->fd,2); // same id
  612. clif_authfail_fd(sd->new_fd,8); // same id
  613. return 1;
  614. }
  615. sd->login_id2 = login_id2;
  616. memcpy(&sd->status, st, sizeof(*st));
  617. if (sd->status.sex != sd->sex) {
  618. clif_authfail_fd(sd->fd, 0);
  619. return 1;
  620. }
  621. memset(&sd->state, 0, sizeof(sd->state));
  622. // 基本的な初期化
  623. sd->state.connect_new = 1;
  624. sd->bl.prev = sd->bl.next = NULL;
  625. sd->weapontype1 = sd->weapontype2 = 0;
  626. sd->view_class = sd->status.class_;
  627. sd->speed = DEFAULT_WALK_SPEED;
  628. sd->state.dead_sit = 0;
  629. sd->dir = 0;
  630. sd->head_dir = 0;
  631. sd->state.auth = 1;
  632. sd->walktimer = -1;
  633. sd->next_walktime = -1;
  634. sd->attacktimer = -1;
  635. sd->followtimer = -1; // [MouseJstr]
  636. sd->skilltimer = -1;
  637. sd->skillitem = -1;
  638. sd->skillitemlv = -1;
  639. sd->invincible_timer = -1;
  640. sd->deal_locked = 0;
  641. sd->trade_partner = 0;
  642. sd->inchealhptick = 0;
  643. sd->inchealsptick = 0;
  644. sd->hp_sub = 0;
  645. sd->sp_sub = 0;
  646. sd->inchealspirithptick = 0;
  647. sd->inchealspiritsptick = 0;
  648. sd->canact_tick = tick;
  649. sd->canmove_tick = tick;
  650. sd->canregen_tick = tick;
  651. sd->attackabletime = tick;
  652. sd->doridori_counter = 0;
  653. sd->change_level = pc_readglobalreg(sd,"jobchange_level");
  654. #ifndef TXT_ONLY // mail system [Valaris]
  655. if(battle_config.mail_system)
  656. sd->mail_counter = 0;
  657. #endif
  658. sd->spiritball = 0;
  659. for(i = 0; i < MAX_SKILL_LEVEL; i++)
  660. sd->spirit_timer[i] = -1;
  661. for(i = 0; i < MAX_SKILLTIMERSKILL; i++)
  662. sd->skilltimerskill[i].timer = -1;
  663. sd->timerskill_count=0;
  664. memset(&sd->dev,0,sizeof(struct square));
  665. for(i = 0; i < 5; i++) {
  666. sd->dev.val1[i] = 0;
  667. sd->dev.val2[i] = 0;
  668. }
  669. // アカウント??の送信要求
  670. intif_request_accountreg(sd);
  671. // アイテムチェック
  672. pc_setinventorydata(sd);
  673. pc_checkitem(sd);
  674. // pet
  675. sd->petDB = NULL;
  676. sd->pd = NULL;
  677. sd->pet_hungry_timer = -1;
  678. memset(&sd->pet, 0, sizeof(struct s_pet));
  679. // ステ?タス異常の初期化
  680. for(i = 0; i < MAX_STATUSCHANGE; i++) {
  681. sd->sc_data[i].timer=-1;
  682. sd->sc_data[i].val1 = sd->sc_data[i].val2 = sd->sc_data[i].val3 = sd->sc_data[i].val4 = 0;
  683. }
  684. sd->sc_count=0;
  685. if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) &&
  686. (pc_isGM(sd) >= get_atcommand_level(AtCommand_Hide)))
  687. sd->status.option &= (OPTION_MASK | OPTION_HIDE);
  688. else
  689. sd->status.option &= OPTION_MASK;
  690. // スキルユニット?係の初期化
  691. memset(sd->skillunit, 0, sizeof(sd->skillunit));
  692. memset(sd->skillunittick, 0, sizeof(sd->skillunittick));
  693. // パ?ティ??係の初期化
  694. sd->party_sended = 0;
  695. sd->party_invite = 0;
  696. sd->party_x = -1;
  697. sd->party_y = -1;
  698. sd->party_hp = -1;
  699. // ギルド?係の初期化
  700. sd->guild_sended = 0;
  701. sd->guild_invite = 0;
  702. sd->guild_alliance = 0;
  703. // イベント?係の初期化
  704. memset(sd->eventqueue, 0, sizeof(sd->eventqueue));
  705. for(i = 0; i < MAX_EVENTTIMER; i++)
  706. sd->eventtimer[i] = -1;
  707. sd->eventcount=0;
  708. // 位置の設定
  709. if (pc_setpos(sd,sd->status.last_point.map, sd->status.last_point.x, sd->status.last_point.y, 0) != 0) {
  710. if(battle_config.error_log) {
  711. char buf[32];
  712. sprintf(buf, "Last_point_map %s not found\n", sd->status.last_point.map);
  713. ShowError (buf);
  714. }
  715. }
  716. // pet
  717. if (sd->status.pet_id > 0)
  718. intif_request_petdata(sd->status.account_id, sd->status.char_id, sd->status.pet_id);
  719. // パ?ティ、ギルドデ?タの要求
  720. if (sd->status.party_id > 0 && (p = party_search(sd->status.party_id)) == NULL)
  721. party_request_info(sd->status.party_id);
  722. if (sd->status.guild_id > 0 && (g = guild_search(sd->status.guild_id)) == NULL)
  723. guild_request_info(sd->status.guild_id);
  724. // pvpの設定
  725. sd->pvp_rank = 0;
  726. sd->pvp_point = 0;
  727. sd->pvp_timer = -1;
  728. // 通知
  729. clif_authok(sd);
  730. map_addnickdb(sd);
  731. if (map_charid2nick(sd->status.char_id) == NULL)
  732. map_addchariddb(sd->status.char_id, sd->status.name);
  733. //スパノビ用死にカウンタ?のスクリプト??からの?み出しとsdへのセット
  734. sd->die_counter = pc_readglobalreg(sd,"PC_DIE_COUNTER");
  735. // Automated script events
  736. sd->state.event_death = pc_readglobalreg(sd,"PCDieEvent");
  737. sd->state.event_kill = pc_readglobalreg(sd,"PCKillEvent");
  738. sd->state.event_disconnect = pc_readglobalreg(sd,"PCLogoffEvent");
  739. sd->state.event_onconnect = pc_readglobalreg(sd,"PCLoginEvent");
  740. if (night_flag == 1 && !map[sd->bl.m].flag.indoors) {
  741. char tmpstr[1024];
  742. strcpy(tmpstr, msg_txt(500)); // Actually, it's the night...
  743. clif_wis_message(sd->fd, wisp_server_name, tmpstr, strlen(tmpstr)+1);
  744. if (battle_config.night_darkness_level > 0)
  745. clif_specialeffect(&sd->bl, 474 + battle_config.night_darkness_level, 0);
  746. else
  747. //clif_specialeffect(&sd->bl, 483, 0); // default darkness level
  748. sd->opt2 |= STATE_BLIND;
  749. }
  750. // ステ?タス初期計算など
  751. pc_calcstatus(sd,1);
  752. if (pc_isGM(sd))
  753. sprintf(tmp_output,"GM Character '"CL_WHITE"%s"CL_RESET"' logged in. (Acc. ID: '"CL_WHITE"%d"CL_RESET"', GM Level '"CL_WHITE"%d"CL_RESET"').\n", sd->status.name, sd->status.account_id, pc_isGM(sd));
  754. else
  755. sprintf(tmp_output,"Character '"CL_WHITE"%s"CL_RESET"' logged in. (Account ID: '"CL_WHITE"%d"CL_RESET"').\n", sd->status.name, sd->status.account_id);
  756. ShowInfo(tmp_output);
  757. if (sd->state.event_onconnect) {
  758. struct npc_data *npc;
  759. //printf("pc: OnPCLogin event done. (%d events)\n", npc_event_doall("OnPCLogin") );
  760. if ((npc = npc_name2id("PCLoginEvent"))) {
  761. run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCLoginNPC
  762. ShowStatus("Event '"CL_WHITE"PCLoginEvent"CL_RESET"' executed.\n");
  763. }
  764. }
  765. // Send friends list
  766. clif_friends_list_send(sd);
  767. // Message of the Dayの送信
  768. {
  769. char buf[256];
  770. FILE *fp;
  771. if ((fp = fopen(motd_txt, "r")) != NULL) {
  772. while (fgets(buf, sizeof(buf)-1, fp) != NULL) {
  773. int i;
  774. for(i=0; buf[i]; i++) {
  775. if (buf[i] == '\r' || buf[i]== '\n') {
  776. buf[i] = 0;
  777. break;
  778. }
  779. }
  780. if (battle_config.motd_type)
  781. clif_disp_onlyself(sd,buf,strlen(buf));
  782. else
  783. clif_displaymessage(sd->fd, buf);
  784. }
  785. fclose(fp);
  786. }
  787. else if(battle_config.error_log) {
  788. sprintf(tmp_output, "In function pc_atuhok() -> File '"CL_WHITE"%s"CL_RESET"' not found.\n", motd_txt);
  789. ShowWarning(tmp_output);
  790. }
  791. }
  792. #ifndef TXT_ONLY
  793. if(battle_config.mail_system)
  794. mail_check(sd,1); // check mail at login [Valaris]
  795. #endif
  796. // message of the limited time of the account
  797. if (connect_until_time != 0) { // don't display if it's unlimited or unknow value
  798. char tmpstr[1024];
  799. strftime(tmpstr, sizeof(tmpstr) - 1, msg_txt(501), localtime(&connect_until_time)); // "Your account time limit is: %d-%m-%Y %H:%M:%S."
  800. clif_wis_message(sd->fd, wisp_server_name, tmpstr, strlen(tmpstr)+1);
  801. }
  802. return 0;
  803. }
  804. /*==========================================
  805. * session idに問題ありなので後始末
  806. *------------------------------------------
  807. */
  808. int pc_authfail(int id) {
  809. struct map_session_data *sd;
  810. sd = map_id2sd(id);
  811. if (sd == NULL)
  812. return 1;
  813. if(sd->new_fd){
  814. // 2重login状態だったので、新しい接続のみ落す
  815. clif_authfail_fd(sd->new_fd,0);
  816. sd->new_fd=0;
  817. return 0;
  818. }
  819. clif_authfail_fd(sd->fd, 0);
  820. return 0;
  821. }
  822. static int pc_calc_skillpoint(struct map_session_data* sd)
  823. {
  824. int i,skill,skill_point=0;
  825. nullpo_retr(0, sd);
  826. for(i=1;i<MAX_SKILL;i++){
  827. if( (skill = pc_checkskill(sd,i)) > 0) {
  828. if(!(skill_get_inf2(i)&0x01) || battle_config.quest_skill_learn) {
  829. if(!sd->status.skill[i].flag)
  830. skill_point += skill;
  831. else if(sd->status.skill[i].flag > 2 && sd->status.skill[i].flag != 13) {
  832. skill_point += (sd->status.skill[i].flag - 2);
  833. }
  834. }
  835. }
  836. }
  837. return skill_point;
  838. }
  839. /*==========================================
  840. * ?えられるスキルの計算
  841. *------------------------------------------
  842. */
  843. int pc_calc_skilltree(struct map_session_data *sd)
  844. {
  845. int i,id=0,flag;
  846. int c=0, s=0;
  847. //?生や養子の場合の元の職業を算出する
  848. struct pc_base_job s_class;
  849. nullpo_retr(0, sd);
  850. s_class = pc_calc_base_job(sd->status.class_);
  851. c = s_class.job;
  852. //s = (s_class.upper==1) ? 1 : 0 ; //?生以外は通常のスキル?
  853. s = s_class.upper;
  854. c = pc_calc_skilltree_normalize_job(c, sd);
  855. for(i=0;i<MAX_SKILL;i++){
  856. // if(skill_get_inf2(i) & 0x01)
  857. // continue;
  858. if (sd->status.skill[i].flag != 13)
  859. sd->status.skill[i].id=0;
  860. if (sd->status.skill[i].flag && sd->status.skill[i].flag != 13){ // cardスキルなら、
  861. sd->status.skill[i].lv=(sd->status.skill[i].flag==1)?0:sd->status.skill[i].flag-2; // 本?のlvに
  862. sd->status.skill[i].flag=0; // flagは0にしておく
  863. }
  864. }
  865. if (battle_config.gm_allskill > 0 && pc_isGM(sd) >= battle_config.gm_allskill){
  866. // 全てのスキル
  867. for(i=1;i<158;i++)
  868. sd->status.skill[i].id=i;
  869. for(i=210;i<291;i++)
  870. sd->status.skill[i].id=i;
  871. for(i=304;i<337;i++){
  872. if(i==331) continue;
  873. sd->status.skill[i].id=i;
  874. }
  875. if(battle_config.enable_upper_class){ //confで無?でなければ?み?む
  876. for(i=355;i<MAX_SKILL;i++)
  877. sd->status.skill[i].id=i;
  878. }
  879. }else{
  880. do {
  881. flag=0;
  882. for(i=0;(id=skill_tree[s][c][i].id)>0;i++){
  883. int j,f=1;
  884. if(!battle_config.skillfree) {
  885. for(j=0;j<5;j++) {
  886. if( skill_tree[s][c][i].need[j].id &&
  887. pc_checkskill(sd,skill_tree[s][c][i].need[j].id) <
  888. skill_tree[s][c][i].need[j].lv)
  889. f=0;
  890. break;
  891. }
  892. }
  893. if(f && sd->status.skill[id].id==0 ){
  894. sd->status.skill[id].id=id;
  895. flag=1;
  896. }
  897. }
  898. } while(flag);
  899. }
  900. // if(battle_config.etc_log)
  901. // printf("calc skill_tree\n");
  902. return 0;
  903. }
  904. int pc_calc_skilltree_normalize_job(int c, struct map_session_data *sd) {
  905. //if((battle_config.skillup_limit) && ((c >= 0 && c < 23) || (c >= 4001 && c < 4023) || (c >= 4023 && c < 4045))) {
  906. if (battle_config.skillup_limit && c >= 0 && c < 23) {
  907. int skill_point = pc_calc_skillpoint(sd);
  908. if(skill_point < 9)
  909. c = 0;
  910. //else if((sd->status.skill_point >= sd->status.job_level && skill_point < 58) && ((c > 6 && c < 23) || (c > 4007 && c < 4023) || (c > 4029 && c < 4045))) {
  911. //else if ((sd->status.skill_point >= sd->status.job_level && skill_point < 58) && (c > 6 && c < 23)) {
  912. else if ((sd->status.skill_point >= sd->status.job_level && skill_point < sd->change_level+8) && (c > 6 && c < 23)) {
  913. switch(c) {
  914. case 7:
  915. case 13:
  916. case 14:
  917. case 21:
  918. c = 1;
  919. break;
  920. case 8:
  921. case 15:
  922. c = 4;
  923. break;
  924. case 9:
  925. case 16:
  926. c = 2;
  927. break;
  928. case 10:
  929. case 18:
  930. c = 5;
  931. break;
  932. case 11:
  933. case 19:
  934. case 20:
  935. c = 3;
  936. break;
  937. case 12:
  938. case 17:
  939. c = 6;
  940. break;
  941. #if 0
  942. case 4008:
  943. case 4014:
  944. case 4015:
  945. case 4022:
  946. c = 4002;
  947. break;
  948. case 4009:
  949. case 4016:
  950. c = 4005;
  951. break;
  952. case 4010:
  953. case 4017:
  954. c = 4003;
  955. break;
  956. case 4011:
  957. case 4019:
  958. c = 4006;
  959. break;
  960. case 4012:
  961. case 4020:
  962. case 4021:
  963. c = 4004;
  964. break;
  965. case 4013:
  966. case 4018:
  967. c = 4007;
  968. break;
  969. case 4030:
  970. case 4036:
  971. case 4037:
  972. case 4044:
  973. c = 4024;
  974. break;
  975. case 4031:
  976. case 4038:
  977. c = 4027;
  978. break;
  979. case 4032:
  980. case 4039:
  981. c = 4025;
  982. break;
  983. case 4033:
  984. case 4040:
  985. c = 4028;
  986. break;
  987. case 4034:
  988. case 4041:
  989. case 4042:
  990. c = 4026;
  991. break;
  992. case 4035:
  993. case 4043:
  994. c = 4029;
  995. break;
  996. #endif
  997. }
  998. }
  999. }
  1000. return c;
  1001. }
  1002. /*==========================================
  1003. * 重量アイコンの確認
  1004. *------------------------------------------
  1005. */
  1006. int pc_checkweighticon(struct map_session_data *sd)
  1007. {
  1008. int flag=0;
  1009. nullpo_retr(0, sd);
  1010. if(sd->weight*2 >= sd->max_weight)
  1011. flag=1;
  1012. if(sd->weight*10 >= sd->max_weight*9)
  1013. flag=2;
  1014. if(flag==1){
  1015. if(sd->sc_data[SC_WEIGHT50].timer==-1)
  1016. skill_status_change_start(&sd->bl,SC_WEIGHT50,0,0,0,0,0,0);
  1017. }else{
  1018. skill_status_change_end(&sd->bl,SC_WEIGHT50,-1);
  1019. }
  1020. if(flag==2){
  1021. if(sd->sc_data[SC_WEIGHT90].timer==-1)
  1022. skill_status_change_start(&sd->bl,SC_WEIGHT90,0,0,0,0,0,0);
  1023. }else{
  1024. skill_status_change_end(&sd->bl,SC_WEIGHT90,-1);
  1025. }
  1026. return 0;
  1027. }
  1028. /*==========================================
  1029. * パラメ?タ計算
  1030. * first==0の斬A計算?象のパラメ?タが呼び出し前から
  1031. * ? 化した場合自動でsendするが、
  1032. * 能動的に?化させたパラメ?タは自前でsendするように
  1033. *------------------------------------------
  1034. */
  1035. int pc_calcstatus(struct map_session_data* sd,int first)
  1036. {
  1037. int b_speed,b_max_hp,b_max_sp,b_hp,b_sp,b_weight,b_max_weight,b_paramb[6],b_parame[6],b_hit,b_flee;
  1038. int b_aspd,b_watk,b_def,b_watk2,b_def2,b_flee2,b_critical,b_attackrange,b_matk1,b_matk2,b_mdef,b_mdef2,b_class;
  1039. int b_base_atk;
  1040. struct skill b_skill[MAX_SKILL];
  1041. int i,bl,index;
  1042. int skill,aspd_rate,wele,wele_,def_ele,refinedef=0;
  1043. int pele=0,pdef_ele=0;
  1044. int str,dstr,dex;
  1045. struct pc_base_job s_class;
  1046. nullpo_retr(0, sd);
  1047. //?生や養子の場合の元の職業を算出する
  1048. s_class = pc_calc_base_job(sd->status.class_);
  1049. b_speed = sd->speed;
  1050. b_max_hp = sd->status.max_hp;
  1051. b_max_sp = sd->status.max_sp;
  1052. b_hp = sd->status.hp;
  1053. b_sp = sd->status.sp;
  1054. b_weight = sd->weight;
  1055. b_max_weight = sd->max_weight;
  1056. memcpy(b_paramb,&sd->paramb,sizeof(b_paramb));
  1057. memcpy(b_parame,&sd->paramc,sizeof(b_parame));
  1058. memcpy(b_skill,&sd->status.skill,sizeof(b_skill));
  1059. b_hit = sd->hit;
  1060. b_flee = sd->flee;
  1061. b_aspd = sd->aspd;
  1062. b_watk = sd->watk;
  1063. b_def = sd->def;
  1064. b_watk2 = sd->watk2;
  1065. b_def2 = sd->def2;
  1066. b_flee2 = sd->flee2;
  1067. b_critical = sd->critical;
  1068. b_attackrange = sd->attackrange;
  1069. b_matk1 = sd->matk1;
  1070. b_matk2 = sd->matk2;
  1071. b_mdef = sd->mdef;
  1072. b_mdef2 = sd->mdef2;
  1073. b_class = sd->view_class;
  1074. sd->view_class = sd->status.class_;
  1075. b_base_atk = sd->base_atk;
  1076. pc_calc_skilltree(sd); // スキルツリ?の計算
  1077. sd->max_weight = max_weight_base[s_class.job]+sd->status.str*300;
  1078. if(first&1) {
  1079. sd->weight=0;
  1080. for(i=0;i<MAX_INVENTORY;i++){
  1081. if(sd->status.inventory[i].nameid==0 || sd->inventory_data[i] == NULL)
  1082. continue;
  1083. sd->weight += sd->inventory_data[i]->weight*sd->status.inventory[i].amount;
  1084. }
  1085. sd->cart_max_weight=battle_config.max_cart_weight;
  1086. sd->cart_weight=0;
  1087. sd->cart_max_num=MAX_CART;
  1088. sd->cart_num=0;
  1089. for(i=0;i<MAX_CART;i++){
  1090. if(sd->status.cart[i].nameid==0)
  1091. continue;
  1092. sd->cart_weight+=itemdb_weight(sd->status.cart[i].nameid)*sd->status.cart[i].amount;
  1093. sd->cart_num++;
  1094. }
  1095. }
  1096. memset(sd->paramb,0,sizeof(sd->paramb));
  1097. memset(sd->parame,0,sizeof(sd->parame));
  1098. sd->hit = 0;
  1099. sd->flee = 0;
  1100. sd->flee2 = 0;
  1101. sd->critical = 0;
  1102. sd->aspd = 0;
  1103. sd->watk = 0;
  1104. sd->def = 0;
  1105. sd->mdef = 0;
  1106. sd->watk2 = 0;
  1107. sd->def2 = 0;
  1108. sd->mdef2 = 0;
  1109. sd->status.max_hp = 0;
  1110. sd->status.max_sp = 0;
  1111. sd->attackrange = 0;
  1112. sd->attackrange_ = 0;
  1113. sd->atk_ele = 0;
  1114. sd->def_ele = 0;
  1115. sd->star =0;
  1116. sd->overrefine =0;
  1117. sd->matk1 =0;
  1118. sd->matk2 =0;
  1119. sd->speed = DEFAULT_WALK_SPEED ;
  1120. sd->hprate=battle_config.hp_rate;
  1121. sd->sprate=battle_config.sp_rate;
  1122. sd->castrate=100;
  1123. sd->delayrate=100;
  1124. sd->dsprate=100;
  1125. sd->base_atk=0;
  1126. sd->arrow_atk=0;
  1127. sd->arrow_ele=0;
  1128. sd->arrow_hit=0;
  1129. sd->arrow_range=0;
  1130. sd->nhealhp=sd->nhealsp=sd->nshealhp=sd->nshealsp=sd->nsshealhp=sd->nsshealsp=0;
  1131. memset(sd->addele,0,sizeof(sd->addele));
  1132. memset(sd->addrace,0,sizeof(sd->addrace));
  1133. memset(sd->addsize,0,sizeof(sd->addsize));
  1134. memset(sd->addele_,0,sizeof(sd->addele_));
  1135. memset(sd->addrace_,0,sizeof(sd->addrace_));
  1136. memset(sd->addsize_,0,sizeof(sd->addsize_));
  1137. memset(sd->subele,0,sizeof(sd->subele));
  1138. memset(sd->subrace,0,sizeof(sd->subrace));
  1139. memset(sd->addeff,0,sizeof(sd->addeff));
  1140. memset(sd->addeff2,0,sizeof(sd->addeff2));
  1141. memset(sd->reseff,0,sizeof(sd->reseff));
  1142. memset(&sd->special_state,0,sizeof(sd->special_state));
  1143. memset(sd->weapon_coma_ele,0,sizeof(sd->weapon_coma_ele));
  1144. memset(sd->weapon_coma_race,0,sizeof(sd->weapon_coma_race));
  1145. memset(sd->weapon_atk,0,sizeof(sd->weapon_atk));
  1146. memset(sd->weapon_atk_rate,0,sizeof(sd->weapon_atk_rate));
  1147. sd->watk_ = 0; //二刀流用(?)
  1148. sd->watk_2 = 0;
  1149. sd->atk_ele_ = 0;
  1150. sd->star_ = 0;
  1151. sd->overrefine_ = 0;
  1152. sd->aspd_rate = 100;
  1153. sd->speed_rate = 100;
  1154. sd->hprecov_rate = 100;
  1155. sd->sprecov_rate = 100;
  1156. sd->critical_def = 0;
  1157. sd->double_rate = 0;
  1158. sd->near_attack_def_rate = sd->long_attack_def_rate = 0;
  1159. sd->atk_rate = sd->matk_rate = 100;
  1160. sd->ignore_def_ele = sd->ignore_def_race = 0;
  1161. sd->ignore_def_ele_ = sd->ignore_def_race_ = 0;
  1162. sd->ignore_mdef_ele = sd->ignore_mdef_race = 0;
  1163. sd->arrow_cri = 0;
  1164. sd->magic_def_rate = sd->misc_def_rate = 0;
  1165. memset(sd->arrow_addele,0,sizeof(sd->arrow_addele));
  1166. memset(sd->arrow_addrace,0,sizeof(sd->arrow_addrace));
  1167. memset(sd->arrow_addsize,0,sizeof(sd->arrow_addsize));
  1168. memset(sd->arrow_addeff,0,sizeof(sd->arrow_addeff));
  1169. memset(sd->arrow_addeff2,0,sizeof(sd->arrow_addeff2));
  1170. memset(sd->magic_addele,0,sizeof(sd->magic_addele));
  1171. memset(sd->magic_addrace,0,sizeof(sd->magic_addrace));
  1172. memset(sd->magic_subrace,0,sizeof(sd->magic_subrace));
  1173. sd->perfect_hit = 0;
  1174. sd->critical_rate = sd->hit_rate = sd->flee_rate = sd->flee2_rate = 100;
  1175. sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100;
  1176. sd->def_ratio_atk_ele = sd->def_ratio_atk_ele_ = 0;
  1177. sd->def_ratio_atk_race = sd->def_ratio_atk_race_ = 0;
  1178. sd->get_zeny_num = 0;
  1179. sd->add_damage_class_count = sd->add_damage_class_count_ = sd->add_magic_damage_class_count = 0;
  1180. sd->add_def_class_count = sd->add_mdef_class_count = 0;
  1181. sd->monster_drop_item_count = 0;
  1182. memset(sd->add_damage_classrate,0,sizeof(sd->add_damage_classrate));
  1183. memset(sd->add_damage_classrate_,0,sizeof(sd->add_damage_classrate_));
  1184. memset(sd->add_magic_damage_classrate,0,sizeof(sd->add_magic_damage_classrate));
  1185. memset(sd->add_def_classrate,0,sizeof(sd->add_def_classrate));
  1186. memset(sd->add_mdef_classrate,0,sizeof(sd->add_mdef_classrate));
  1187. memset(sd->monster_drop_race,0,sizeof(sd->monster_drop_race));
  1188. memset(sd->monster_drop_itemrate,0,sizeof(sd->monster_drop_itemrate));
  1189. sd->speed_add_rate = sd->aspd_add_rate = 100;
  1190. sd->double_add_rate = sd->perfect_hit_add = sd->get_zeny_add_num = 0;
  1191. sd->splash_range = sd->splash_add_range = 0;
  1192. sd->autospell_id = sd->autospell_lv = sd->autospell_rate = 0;
  1193. sd->hp_drain_rate = sd->hp_drain_per = sd->sp_drain_rate = sd->sp_drain_per = 0;
  1194. sd->hp_drain_rate_ = sd->hp_drain_per_ = sd->sp_drain_rate_ = sd->sp_drain_per_ = 0;
  1195. sd->short_weapon_damage_return = sd->long_weapon_damage_return = 0;
  1196. sd->magic_damage_return = 0; //AppleGirl Was Here
  1197. sd->random_attack_increase_add = sd->random_attack_increase_per = 0;
  1198. sd->hp_drain_value = sd->hp_drain_value_ = sd->sp_drain_value = sd->sp_drain_value_ = 0;
  1199. sd->unbreakable_equip = 0;
  1200. if(!sd->disguiseflag && sd->disguise) {
  1201. sd->disguise=0;
  1202. clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
  1203. clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
  1204. clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
  1205. clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
  1206. clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
  1207. clif_clearchar(&sd->bl, 9);
  1208. pc_setpos(sd, sd->mapname, sd->bl.x, sd->bl.y, 3);
  1209. }
  1210. for(i=0;i<10;i++) {
  1211. index = sd->equip_index[i];
  1212. if(index < 0)
  1213. continue;
  1214. if(i == 9 && sd->equip_index[8] == index)
  1215. continue;
  1216. if(i == 5 && sd->equip_index[4] == index)
  1217. continue;
  1218. if(i == 6 && (sd->equip_index[5] == index || sd->equip_index[4] == index))
  1219. continue;
  1220. if(sd->inventory_data[index]) {
  1221. if(sd->inventory_data[index]->type == 4) {
  1222. if(sd->status.inventory[index].card[0]!=0x00ff && sd->status.inventory[index].card[0]!=0x00fe && sd->status.inventory[index].card[0]!=(short)0xff00) {
  1223. int j;
  1224. for(j=0;j<sd->inventory_data[index]->slot;j++){ // カ?ド
  1225. int c=sd->status.inventory[index].card[j];
  1226. if(c>0){
  1227. if(i == 8 && sd->status.inventory[index].equip == 0x20)
  1228. sd->state.lr_flag = 1;
  1229. run_script(itemdb_equipscript(c),0,sd->bl.id,0);
  1230. sd->state.lr_flag = 0;
  1231. }
  1232. }
  1233. }
  1234. }
  1235. else if(sd->inventory_data[index]->type==5){ // 防具
  1236. if(sd->status.inventory[index].card[0]!=0x00ff && sd->status.inventory[index].card[0]!=0x00fe && sd->status.inventory[index].card[0]!=(short)0xff00) {
  1237. int j;
  1238. for(j=0;j<sd->inventory_data[index]->slot;j++){ // カ?ド
  1239. int c=sd->status.inventory[index].card[j];
  1240. if(c>0)
  1241. run_script(itemdb_equipscript(c),0,sd->bl.id,0);
  1242. }
  1243. }
  1244. }
  1245. }
  1246. }
  1247. wele = sd->atk_ele;
  1248. wele_ = sd->atk_ele_;
  1249. def_ele = sd->def_ele;
  1250. if(sd->status.pet_id > 0) {
  1251. struct pet_data *pd=sd->pd;
  1252. if((pd && battle_config.pet_status_support==1) && (battle_config.pet_equip_required==0 || (battle_config.pet_equip_required && pd->equip > 0))) {
  1253. if(sd->status.pet_id > 0 && sd->petDB && sd->pet.intimate > 0)
  1254. run_script(sd->petDB->script,0,sd->bl.id,0);
  1255. pele = sd->atk_ele;
  1256. pdef_ele = sd->def_ele;
  1257. sd->atk_ele = sd->def_ele = 0;
  1258. }
  1259. }
  1260. memcpy(sd->paramcard,sd->parame,sizeof(sd->paramcard));
  1261. // ?備品によるステ?タス?化はここで?行
  1262. for(i=0;i<10;i++) {
  1263. index = sd->equip_index[i];
  1264. if(index < 0)
  1265. continue;
  1266. if(i == 9 && sd->equip_index[8] == index)
  1267. continue;
  1268. if(i == 5 && sd->equip_index[4] == index)
  1269. continue;
  1270. if(i == 6 && (sd->equip_index[5] == index || sd->equip_index[4] == index))
  1271. continue;
  1272. if(sd->inventory_data[index]) {
  1273. sd->def += sd->inventory_data[index]->def;
  1274. if(sd->inventory_data[index]->type == 4) {
  1275. int r,wlv = sd->inventory_data[index]->wlv;
  1276. if(i == 8 && sd->status.inventory[index].equip == 0x20) {
  1277. //二刀流用デ?タ入力
  1278. sd->watk_ += sd->inventory_data[index]->atk;
  1279. sd->watk_2 = (r=sd->status.inventory[index].refine)* // 精?攻?力
  1280. refinebonus[wlv][0];
  1281. if( (r-=refinebonus[wlv][2])>0 ) // 過?精?ボ?ナス
  1282. sd->overrefine_ = r*refinebonus[wlv][1];
  1283. if(sd->status.inventory[index].card[0]==0x00ff){ // 製造武器
  1284. sd->star_ = (sd->status.inventory[index].card[1]>>8); // 星のかけら
  1285. wele_= (sd->status.inventory[index].card[1]&0x0f); // ? 性
  1286. }
  1287. sd->attackrange_ += sd->inventory_data[index]->range;
  1288. sd->state.lr_flag = 1;
  1289. run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0);
  1290. sd->state.lr_flag = 0;
  1291. }
  1292. else { //二刀流武器以外
  1293. sd->watk += sd->inventory_data[index]->atk;
  1294. sd->watk2 += (r=sd->status.inventory[index].refine)* // 精?攻?力
  1295. refinebonus[wlv][0];
  1296. if( (r-=refinebonus[wlv][2])>0 ) // 過?精?ボ?ナス
  1297. sd->overrefine += r*refinebonus[wlv][1];
  1298. if(sd->status.inventory[index].card[0]==0x00ff){ // 製造武器
  1299. sd->star += (sd->status.inventory[index].card[1]>>8); // 星のかけら
  1300. wele = (sd->status.inventory[index].card[1]&0x0f); // ? 性
  1301. }
  1302. sd->attackrange += sd->inventory_data[index]->range;
  1303. run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0);
  1304. }
  1305. }
  1306. else if(sd->inventory_data[index]->type == 5) {
  1307. sd->watk += sd->inventory_data[index]->atk;
  1308. refinedef += sd->status.inventory[index].refine*refinebonus[0][0];
  1309. run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0);
  1310. }
  1311. }
  1312. }
  1313. if(sd->equip_index[10] >= 0){ // 矢
  1314. index = sd->equip_index[10];
  1315. if(sd->inventory_data[index]){ //まだ?性が入っていない
  1316. sd->state.lr_flag = 2;
  1317. run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0);
  1318. sd->state.lr_flag = 0;
  1319. sd->arrow_atk += sd->inventory_data[index]->atk;
  1320. }
  1321. }
  1322. sd->def += (refinedef+50)/100;
  1323. if(sd->attackrange < 1) sd->attackrange = 1;
  1324. if(sd->attackrange_ < 1) sd->attackrange_ = 1;
  1325. if(sd->attackrange < sd->attackrange_)
  1326. sd->attackrange = sd->attackrange_;
  1327. if(sd->status.weapon == 11)
  1328. sd->attackrange += sd->arrow_range;
  1329. if(wele > 0)
  1330. sd->atk_ele = wele;
  1331. if(wele_ > 0)
  1332. sd->atk_ele_ = wele_;
  1333. if(def_ele > 0)
  1334. sd->def_ele = def_ele;
  1335. if(battle_config.pet_status_support) {
  1336. if(pele > 0 && !sd->atk_ele)
  1337. sd->atk_ele = pele;
  1338. if(pdef_ele > 0 && !sd->def_ele)
  1339. sd->def_ele = pdef_ele;
  1340. }
  1341. sd->double_rate += sd->double_add_rate;
  1342. sd->perfect_hit += sd->perfect_hit_add;
  1343. sd->get_zeny_num += sd->get_zeny_add_num;
  1344. sd->splash_range += sd->splash_add_range;
  1345. if(sd->speed_add_rate != 100)
  1346. sd->speed_rate += sd->speed_add_rate - 100;
  1347. if(sd->aspd_add_rate != 100)
  1348. sd->aspd_rate += sd->aspd_add_rate - 100;
  1349. // 武器ATKサイズ補正 (右手)
  1350. sd->atkmods[0] = atkmods[0][sd->weapontype1];
  1351. sd->atkmods[1] = atkmods[1][sd->weapontype1];
  1352. sd->atkmods[2] = atkmods[2][sd->weapontype1];
  1353. //武器ATKサイズ補正 (左手)
  1354. sd->atkmods_[0] = atkmods[0][sd->weapontype2];
  1355. sd->atkmods_[1] = atkmods[1][sd->weapontype2];
  1356. sd->atkmods_[2] = atkmods[2][sd->weapontype2];
  1357. // jobボ?ナス分
  1358. for(i=0;i<sd->status.job_level && i<MAX_LEVEL;i++){
  1359. if(job_bonus[s_class.upper][s_class.job][i])
  1360. sd->paramb[job_bonus[s_class.upper][s_class.job][i]-1]++;
  1361. }
  1362. if( (skill=pc_checkskill(sd,MC_INCCARRY))>0 ) // skill can be used with an item now, thanks to orn [Valaris]
  1363. sd->max_weight += skill*2000;
  1364. if( (skill=pc_checkskill(sd,AC_OWL))>0 ) // ふくろうの目
  1365. sd->paramb[4] += skill;
  1366. if((skill=pc_checkskill(sd,BS_HILTBINDING))>0) { // Hilt binding gives +1 str +4 atk
  1367. sd->paramb[0] ++;
  1368. sd->base_atk += 4;
  1369. }
  1370. if((skill=pc_checkskill(sd,SA_DRAGONOLOGY))>0 ){ // Dragonology increases +1 int every 2 levels
  1371. sd->paramb[3] += (skill+1)*0.5;
  1372. }
  1373. // New guild skills - Celest
  1374. if (sd->status.guild_id > 0 && !(first&4)) {
  1375. struct guild *g;
  1376. if ((g = guild_search(sd->status.guild_id)) && strcmp(sd->status.name,g->master)==0) {
  1377. if (!sd->state.leadership_flag && guild_checkskill(g, GD_LEADERSHIP)>0) {
  1378. skill_unitsetting(&sd->bl,GD_LEADERSHIP,1,sd->bl.x,sd->bl.y,0);
  1379. }
  1380. if (!sd->state.glorywounds_flag && guild_checkskill(g, GD_GLORYWOUNDS)>0) {
  1381. skill_unitsetting(&sd->bl,GD_GLORYWOUNDS,1,sd->bl.x,sd->bl.y,0);
  1382. }
  1383. if (!sd->state.soulcold_flag && guild_checkskill(g, GD_SOULCOLD)>0) {
  1384. skill_unitsetting(&sd->bl,GD_SOULCOLD,1,sd->bl.x,sd->bl.y,0);
  1385. }
  1386. if (!sd->state.hawkeyes_flag && guild_checkskill(g, GD_HAWKEYES)>0) {
  1387. skill_unitsetting(&sd->bl,GD_HAWKEYES,1,sd->bl.x,sd->bl.y,0);
  1388. }
  1389. }
  1390. else if (g) {
  1391. if (sd->sc_count && sd->sc_data[SC_BATTLEORDERS].timer != -1) {
  1392. sd->paramb[0]+= 5;
  1393. sd->paramb[3]+= 5;
  1394. sd->paramb[4]+= 5;
  1395. }
  1396. if (sd->state.leadership_flag)
  1397. sd->paramb[0] += 2;
  1398. if (sd->state.glorywounds_flag)
  1399. sd->paramb[2] += 2;
  1400. if (sd->state.soulcold_flag)
  1401. sd->paramb[1] += 2;
  1402. if (sd->state.hawkeyes_flag)
  1403. sd->paramb[4] += 2;
  1404. }
  1405. }
  1406. // ステ?タス?化による基本パラメ?タ補正
  1407. if(sd->sc_count){
  1408. if(sd->sc_data[SC_CONCENTRATE].timer!=-1 && sd->sc_data[SC_QUAGMIRE].timer == -1){ // 集中力向上
  1409. sd->paramb[1]+= (sd->status.agi+sd->paramb[1]+sd->parame[1]-sd->paramcard[1])*(2+sd->sc_data[SC_CONCENTRATE].val1)/100;
  1410. sd->paramb[4]+= (sd->status.dex+sd->paramb[4]+sd->parame[4]-sd->paramcard[4])*(2+sd->sc_data[SC_CONCENTRATE].val1)/100;
  1411. }
  1412. if(sd->sc_data[SC_INCREASEAGI].timer!=-1 && sd->sc_data[SC_QUAGMIRE].timer == -1 && sd->sc_data[SC_DONTFORGETME].timer == -1){ // 速度?加
  1413. sd->paramb[1]+= 2+sd->sc_data[SC_INCREASEAGI].val1;
  1414. sd->speed -= sd->speed *25/100;
  1415. }
  1416. if(sd->sc_data[SC_DECREASEAGI].timer!=-1) // 速度減少(agiはbattle.cで)
  1417. sd->speed = sd->speed *125/100;
  1418. if(sd->sc_data[SC_CLOAKING].timer!=-1) {
  1419. sd->critical_rate += 100; // critical increases
  1420. sd->speed = sd->speed * (sd->sc_data[SC_CLOAKING].val3-sd->sc_data[SC_CLOAKING].val1*3) /100;
  1421. }
  1422. if(sd->sc_data[SC_CHASEWALK].timer!=-1) {
  1423. sd->speed = sd->speed * sd->sc_data[SC_CHASEWALK].val3 /100; // slow down by chasewalk
  1424. if(sd->sc_data[SC_CHASEWALK].val4)
  1425. sd->paramb[0] += (1<<(sd->sc_data[SC_CHASEWALK].val1-1)); // increases strength after 10 seconds
  1426. }
  1427. if(sd->sc_data[SC_SLOWDOWN].timer!=-1)
  1428. sd->speed = sd->speed*150/100;
  1429. if(sd->sc_data[SC_SPEEDUP0].timer!=-1)
  1430. sd->speed -= sd->speed*25/100;
  1431. if(sd->sc_data[SC_BLESSING].timer!=-1){ // ブレッシング
  1432. sd->paramb[0]+= sd->sc_data[SC_BLESSING].val1;
  1433. sd->paramb[3]+= sd->sc_data[SC_BLESSING].val1;
  1434. sd->paramb[4]+= sd->sc_data[SC_BLESSING].val1;
  1435. }
  1436. if(sd->sc_data[SC_GLORIA].timer!=-1) // グロリア
  1437. sd->paramb[5]+= 30;
  1438. if(sd->sc_data[SC_LOUD].timer!=-1 && sd->sc_data[SC_QUAGMIRE].timer == -1) // ラウドボイス
  1439. sd->paramb[0]+= 4;
  1440. if(sd->sc_data[SC_QUAGMIRE].timer!=-1){ // クァグマイア
  1441. //int agib = (sd->status.agi+sd->paramb[1]+sd->parame[1])*(sd->sc_data[SC_QUAGMIRE].val1*10)/100;
  1442. //int dexb = (sd->status.dex+sd->paramb[4]+sd->parame[4])*(sd->sc_data[SC_QUAGMIRE].val1*10)/100;
  1443. //sd->paramb[1]-= agib > 50 ? 50 : agib;
  1444. //sd->paramb[4]-= dexb > 50 ? 50 : dexb;
  1445. sd->paramb[1]-= sd->sc_data[SC_QUAGMIRE].val1*5;
  1446. sd->paramb[4]-= sd->sc_data[SC_QUAGMIRE].val1*5;
  1447. sd->speed = sd->speed*3/2;
  1448. }
  1449. if(sd->sc_data[SC_TRUESIGHT].timer!=-1){ // トゥル?サイト
  1450. sd->paramb[0]+= 5;
  1451. sd->paramb[1]+= 5;
  1452. sd->paramb[2]+= 5;
  1453. sd->paramb[3]+= 5;
  1454. sd->paramb[4]+= 5;
  1455. sd->paramb[5]+= 5;
  1456. }
  1457. if(sd->sc_data[SC_MARIONETTE].timer!=-1){
  1458. struct map_session_data *psd = map_id2sd(sd->sc_data[SC_MARIONETTE2].val3);
  1459. if (psd) { // if partner is found
  1460. sd->paramb[0]-= sd->status.str/2; // bonuses not included
  1461. sd->paramb[1]-= sd->status.agi/2;
  1462. sd->paramb[2]-= sd->status.vit/2;
  1463. sd->paramb[3]-= sd->status.int_/2;
  1464. sd->paramb[4]-= sd->status.dex/2;
  1465. sd->paramb[5]-= sd->status.luk/2;
  1466. }
  1467. }
  1468. else if(sd->sc_data[SC_MARIONETTE2].timer!=-1){
  1469. struct map_session_data *psd = map_id2sd(sd->sc_data[SC_MARIONETTE2].val3);
  1470. if (psd) { // if partner is found
  1471. sd->paramb[0] += sd->status.str+psd->status.str/2 > 99 ? 99-sd->status.str : psd->status.str/2;
  1472. sd->paramb[1] += sd->status.agi+psd->status.agi/2 > 99 ? 99-sd->status.agi : psd->status.agi/2;
  1473. sd->paramb[2] += sd->status.vit+psd->status.vit/2 > 99 ? 99-sd->status.vit : psd->status.vit/2;
  1474. sd->paramb[3] += sd->status.int_+psd->status.int_/2 > 99 ? 99-sd->status.int_ : psd->status.int_/2;
  1475. sd->paramb[4] += sd->status.dex+psd->status.dex/2 > 99 ? 99-sd->status.dex : psd->status.dex/2;
  1476. sd->paramb[5] += sd->status.luk+psd->status.luk/2 > 99 ? 99-sd->status.luk : psd->status.luk/2;
  1477. }
  1478. }
  1479. }
  1480. //1度も死んでないJob70スパノビに+10
  1481. if(s_class.job == 23 && sd->die_counter == 0 && sd->status.job_level >= 70){
  1482. sd->paramb[0]+= 15;
  1483. sd->paramb[1]+= 15;
  1484. sd->paramb[2]+= 15;
  1485. sd->paramb[3]+= 15;
  1486. sd->paramb[4]+= 15;
  1487. sd->paramb[5]+= 15;
  1488. }
  1489. sd->paramc[0]=sd->status.str+sd->paramb[0]+sd->parame[0];
  1490. sd->paramc[1]=sd->status.agi+sd->paramb[1]+sd->parame[1];
  1491. sd->paramc[2]=sd->status.vit+sd->paramb[2]+sd->parame[2];
  1492. sd->paramc[3]=sd->status.int_+sd->paramb[3]+sd->parame[3];
  1493. sd->paramc[4]=sd->status.dex+sd->paramb[4]+sd->parame[4];
  1494. sd->paramc[5]=sd->status.luk+sd->paramb[5]+sd->parame[5];
  1495. for(i=0;i<6;i++)
  1496. if(sd->paramc[i] < 0) sd->paramc[i] = 0;
  1497. if(sd->status.weapon == 11 || sd->status.weapon == 13 || sd->status.weapon == 14) {
  1498. str = sd->paramc[4];
  1499. dex = sd->paramc[0];
  1500. }
  1501. else {
  1502. str = sd->paramc[0];
  1503. dex = sd->paramc[4];
  1504. }
  1505. dstr = str/10;
  1506. sd->base_atk += str + dstr*dstr + dex/5 + sd->paramc[5]/5;
  1507. sd->matk1 += sd->paramc[3]+(sd->paramc[3]/5)*(sd->paramc[3]/5);
  1508. sd->matk2 += sd->paramc[3]+(sd->paramc[3]/7)*(sd->paramc[3]/7);
  1509. if(sd->matk1 < sd->matk2) {
  1510. int temp = sd->matk2;
  1511. sd->matk2 = sd->matk1;
  1512. sd->matk1 = temp;
  1513. }
  1514. sd->hit += sd->paramc[4] + sd->status.base_level;
  1515. sd->flee += sd->paramc[1] + sd->status.base_level;
  1516. sd->def2 += sd->paramc[2];
  1517. sd->mdef2 += sd->paramc[3];
  1518. sd->flee2 += sd->paramc[5]+10;
  1519. sd->critical += (sd->paramc[5]*3)+10;
  1520. if(sd->base_atk < 1)
  1521. sd->base_atk = 1;
  1522. if(sd->critical_rate != 100)
  1523. sd->critical = (sd->critical*sd->critical_rate)/100;
  1524. if(sd->critical < 10) sd->critical = 10;
  1525. if(sd->hit_rate != 100)
  1526. sd->hit = (sd->hit*sd->hit_rate)/100;
  1527. if(sd->hit < 1) sd->hit = 1;
  1528. if(sd->flee_rate != 100)
  1529. sd->flee = (sd->flee*sd->flee_rate)/100;
  1530. if(sd->flee < 1) sd->flee = 1;
  1531. if(sd->flee2_rate != 100)
  1532. sd->flee2 = (sd->flee2*sd->flee2_rate)/100;
  1533. if(sd->flee2 < 10) sd->flee2 = 10;
  1534. if(sd->def_rate != 100)
  1535. sd->def = (sd->def*sd->def_rate)/100;
  1536. if(sd->def < 0) sd->def = 0;
  1537. if(sd->def2_rate != 100)
  1538. sd->def2 = (sd->def2*sd->def2_rate)/100;
  1539. if(sd->def2 < 1) sd->def2 = 1;
  1540. if(sd->mdef_rate != 100)
  1541. sd->mdef = (sd->mdef*sd->mdef_rate)/100;
  1542. if(sd->mdef < 0) sd->mdef = 0;
  1543. if(sd->mdef2_rate != 100)
  1544. sd->mdef2 = (sd->mdef2*sd->mdef2_rate)/100;
  1545. if(sd->mdef2 < 1) sd->mdef2 = 1;
  1546. // 二刀流 ASPD 修正
  1547. if (sd->status.weapon <= 16)
  1548. sd->aspd += aspd_base[s_class.job][sd->status.weapon]-(sd->paramc[1]*4+sd->paramc[4])*aspd_base[s_class.job][sd->status.weapon]/1000;
  1549. else
  1550. sd->aspd += (
  1551. (aspd_base[s_class.job][sd->weapontype1]-(sd->paramc[1]*4+sd->paramc[4])*aspd_base[s_class.job][sd->weapontype1]/1000) +
  1552. (aspd_base[s_class.job][sd->weapontype2]-(sd->paramc[1]*4+sd->paramc[4])*aspd_base[s_class.job][sd->weapontype2]/1000)
  1553. ) * 140 / 200;
  1554. aspd_rate = sd->aspd_rate;
  1555. //攻?速度?加
  1556. if((skill=pc_checkskill(sd,AC_VULTURE))>0){ // ワシの目
  1557. sd->hit += skill;
  1558. if(sd->status.weapon == 11)
  1559. sd->attackrange += skill;
  1560. }
  1561. if( (skill=pc_checkskill(sd,BS_WEAPONRESEARCH))>0) // 武器?究の命中率?加
  1562. sd->hit += skill*2;
  1563. if(sd->status.option&2 && (skill = pc_checkskill(sd,RG_TUNNELDRIVE))>0 ) // トンネルドライブ // トンネルドライブ
  1564. sd->speed += (1.2*DEFAULT_WALK_SPEED - skill*9);
  1565. if (pc_iscarton(sd) && (skill=pc_checkskill(sd,MC_PUSHCART))>0) // カ?トによる速度低下
  1566. sd->speed += (10-skill) * (DEFAULT_WALK_SPEED * 0.1);
  1567. else if (pc_isriding(sd)) { // ペコペコ?りによる速度?加
  1568. sd->speed -= (0.25 * DEFAULT_WALK_SPEED);
  1569. sd->max_weight += 10000;
  1570. }
  1571. if((skill=pc_checkskill(sd,CR_TRUST))>0) { // フェイス
  1572. sd->status.max_hp += skill*200;
  1573. sd->subele[6] += skill*5;
  1574. }
  1575. if((skill=pc_checkskill(sd,BS_SKINTEMPER))>0) {
  1576. sd->subele[0] += skill;
  1577. sd->subele[3] += skill*5;
  1578. }
  1579. if((skill=pc_checkskill(sd,SA_ADVANCEDBOOK))>0 )
  1580. aspd_rate -= skill*0.5;
  1581. bl=sd->status.base_level;
  1582. sd->status.max_hp += (3500 + bl*hp_coefficient2[s_class.job] + hp_sigma_val[s_class.job][(bl > 0)? bl-1:0])/100 * (100 + sd->paramc[2])/100 + (sd->parame[2] - sd->paramcard[2]);
  1583. if (s_class.upper==1) // [MouseJstr]
  1584. sd->status.max_hp = sd->status.max_hp * 130/100;
  1585. else if (s_class.upper==2)
  1586. sd->status.max_hp = sd->status.max_hp * 70/100;
  1587. if(sd->hprate!=100)
  1588. sd->status.max_hp = sd->status.max_hp*sd->hprate/100;
  1589. if(sd->sc_count && sd->sc_data[SC_BERSERK].timer!=-1){ // バ?サ?ク
  1590. sd->status.max_hp = sd->status.max_hp * 3;
  1591. // sd->status.hp = sd->status.hp * 3;
  1592. if(sd->status.max_hp > battle_config.max_hp) // removed negative max hp bug by Valaris
  1593. sd->status.max_hp = battle_config.max_hp;
  1594. if(sd->status.hp > battle_config.max_hp) // removed negative max hp bug by Valaris
  1595. sd->status.hp = battle_config.max_hp;
  1596. }
  1597. if(s_class.job == 23 && sd->status.base_level >= 99){
  1598. sd->status.max_hp = sd->status.max_hp + 2000;
  1599. }
  1600. if(sd->status.max_hp > battle_config.max_hp) // removed negative max hp bug by Valaris
  1601. sd->status.max_hp = battle_config.max_hp;
  1602. if(sd->status.max_hp <= 0) sd->status.max_hp = 1; // end
  1603. // 最大SP計算
  1604. sd->status.max_sp += ((sp_coefficient[s_class.job] * bl) + 1000)/100 * (100 + sd->paramc[3])/100 + (sd->parame[3] - sd->paramcard[3]);
  1605. if (s_class.upper==1) // [MouseJstr]
  1606. sd->status.max_sp = sd->status.max_sp * 130/100;
  1607. else if (s_class.upper==2)
  1608. sd->status.max_sp = sd->status.max_sp * 70/100;
  1609. if(sd->sprate!=100)
  1610. sd->status.max_sp = sd->status.max_sp*sd->sprate/100;
  1611. if((skill=pc_checkskill(sd,HP_MEDITATIO))>0) // メディテイティオ
  1612. sd->status.max_sp += sd->status.max_sp*skill/100;
  1613. if((skill=pc_checkskill(sd,HW_SOULDRAIN))>0) /* ソウルドレイン */
  1614. sd->status.max_sp += sd->status.max_sp*2*skill/100;
  1615. if(sd->status.max_sp < 0 || sd->status.max_sp > battle_config.max_sp)
  1616. sd->status.max_sp = battle_config.max_sp;
  1617. //自然回復HP
  1618. sd->nhealhp = 1 + (sd->paramc[2]/5) + (sd->status.max_hp/200);
  1619. if((skill=pc_checkskill(sd,SM_RECOVERY)) > 0) { /* HP回復力向上 */
  1620. sd->nshealhp = skill*5 + (sd->status.max_hp*skill/500);
  1621. if(sd->nshealhp > 0x7fff) sd->nshealhp = 0x7fff;
  1622. }
  1623. //自然回復SP
  1624. sd->nhealsp = 1 + (sd->paramc[3]/6) + (sd->status.max_sp/100);
  1625. if(sd->paramc[3] >= 120)
  1626. sd->nhealsp += ((sd->paramc[3]-120)>>1) + 4;
  1627. if((skill=pc_checkskill(sd,MG_SRECOVERY)) > 0) { /* SP回復力向上 */
  1628. sd->nshealsp = skill*3 + (sd->status.max_sp*skill/500);
  1629. if(sd->nshealsp > 0x7fff) sd->nshealsp = 0x7fff;
  1630. }
  1631. if((skill = pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0) {
  1632. sd->nsshealhp = skill*4 + (sd->status.max_hp*skill/500);
  1633. sd->nsshealsp = skill*2 + (sd->status.max_sp*skill/500);
  1634. if(sd->nsshealhp > 0x7fff) sd->nsshealhp = 0x7fff;
  1635. if(sd->nsshealsp > 0x7fff) sd->nsshealsp = 0x7fff;
  1636. }
  1637. if(sd->hprecov_rate != 100) {
  1638. sd->nhealhp = sd->nhealhp*sd->hprecov_rate/100;
  1639. if(sd->nhealhp < 1) sd->nhealhp = 1;
  1640. }
  1641. if(sd->sprecov_rate != 100) {
  1642. sd->nhealsp = sd->nhealsp*sd->sprecov_rate/100;
  1643. if(sd->nhealsp < 1) sd->nhealsp = 1;
  1644. }
  1645. /* if((skill=pc_checkskill(sd,HP_MEDITATIO)) > 0) { // f?fffBfefCfefBfI,I'SPR,A*,I',E`,。ゥZ((c)。ョR「カn~.ゥォ,E',(c),(c),e'
  1646. sd->nhealsp += 3*skill*(sd->status.max_sp)/100;
  1647. if(sd->nhealsp > 0x7fff) sd->nhealsp = 0x7fff;
  1648. } Increase natural SP regen instead of colossal SP Recovery effect [DracoRPG]*/
  1649. // 種族耐性(これでいいの? ディバインプロテクションと同じ?理がいるかも)
  1650. if( (skill=pc_checkskill(sd,SA_DRAGONOLOGY))>0 ){ // ドラゴノロジ?
  1651. skill = skill*4;
  1652. sd->addrace[9]+=skill;
  1653. sd->addrace_[9]+=skill;
  1654. sd->subrace[9]+=skill;
  1655. sd->magic_addrace[9]+=skill;
  1656. sd->magic_subrace[9]-=skill;
  1657. }
  1658. //Flee上昇
  1659. if( (skill=pc_checkskill(sd,TF_MISS))>0 ){ // 回避率?加
  1660. if(sd->status.class_==6||sd->status.class_==4007 || sd->status.class_==23){
  1661. sd->flee += skill*3;
  1662. }
  1663. if(sd->status.class_==12||sd->status.class_==17||sd->status.class_==4013||sd->status.class_==4018)
  1664. sd->flee += skill*4;
  1665. if(sd->status.class_==12||sd->status.class_==4013)
  1666. sd->speed -= sd->speed *(skill*1.5)/100;
  1667. }
  1668. if( (skill=pc_checkskill(sd,MO_DODGE))>0 ) // 見切り
  1669. sd->flee += (skill*3)>>1;
  1670. // スキルやステ?タス異常による?りのパラメ?タ補正
  1671. if(sd->sc_count){
  1672. // ATK/DEF?化形
  1673. if(sd->sc_data[SC_ANGELUS].timer!=-1) // エンジェラス
  1674. sd->def2 = sd->def2*(110+5*sd->sc_data[SC_ANGELUS].val1)/100;
  1675. if(sd->sc_data[SC_IMPOSITIO].timer!=-1) {// インポシティオマヌス
  1676. sd->watk += sd->sc_data[SC_IMPOSITIO].val1*5;
  1677. index = sd->equip_index[8];
  1678. if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4)
  1679. sd->watk_ += sd->sc_data[SC_IMPOSITIO].val1*5;
  1680. }
  1681. if(sd->sc_data[SC_PROVOKE].timer!=-1){ // プロボック
  1682. sd->def2 = sd->def2*(100-6*sd->sc_data[SC_PROVOKE].val1)/100;
  1683. sd->base_atk = sd->base_atk*(100+2*sd->sc_data[SC_PROVOKE].val1)/100;
  1684. sd->watk = sd->watk*(100+2*sd->sc_data[SC_PROVOKE].val1)/100;
  1685. index = sd->equip_index[8];
  1686. if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4)
  1687. sd->watk_ = sd->watk_*(100+2*sd->sc_data[SC_PROVOKE].val1)/100;
  1688. }
  1689. if(sd->sc_data[SC_ENDURE].timer!=-1)
  1690. sd->mdef2 += sd->sc_data[SC_ENDURE].val1;
  1691. if(sd->sc_data[SC_MINDBREAKER].timer!=-1){ // プロボック
  1692. sd->mdef2 = sd->mdef2*(100-6*sd->sc_data[SC_MINDBREAKER].val1)/100;
  1693. sd->matk1 = sd->matk1*(100+2*sd->sc_data[SC_MINDBREAKER].val1)/100;
  1694. sd->matk2 = sd->matk2*(100+2*sd->sc_data[SC_MINDBREAKER].val1)/100;
  1695. }
  1696. if(sd->sc_data[SC_POISON].timer!=-1) // 毒?態
  1697. sd->def2 = sd->def2*75/100;
  1698. if(sd->sc_data[SC_DRUMBATTLE].timer!=-1){ // ?太鼓の響き
  1699. sd->watk += sd->sc_data[SC_DRUMBATTLE].val2;
  1700. sd->def += sd->sc_data[SC_DRUMBATTLE].val3;
  1701. index = sd->equip_index[8];
  1702. if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4)
  1703. sd->watk_ += sd->sc_data[SC_DRUMBATTLE].val2;
  1704. }
  1705. if(sd->sc_data[SC_NIBELUNGEN].timer!=-1) { // ニ?ベルングの指輪
  1706. index = sd->equip_index[9];
  1707. /*if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 3)
  1708. sd->watk += sd->sc_data[SC_NIBELUNGEN].val3;
  1709. index = sd->equip_index[8];
  1710. if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 3)
  1711. sd->watk_ += sd->sc_data[SC_NIBELUNGEN].val3;
  1712. index = sd->equip_index[9];*/
  1713. if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 4)
  1714. sd->watk2 += sd->sc_data[SC_NIBELUNGEN].val3;
  1715. index = sd->equip_index[8];
  1716. if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 4)
  1717. sd->watk_2 += sd->sc_data[SC_NIBELUNGEN].val3;
  1718. }
  1719. if(sd->sc_data[SC_VOLCANO].timer!=-1 && sd->def_ele==3){ // ボルケ?ノ
  1720. sd->watk += sd->sc_data[SC_VIOLENTGALE].val3;
  1721. }
  1722. if(sd->sc_data[SC_SIGNUMCRUCIS].timer!=-1)
  1723. sd->def = sd->def * (100 - sd->sc_data[SC_SIGNUMCRUCIS].val2)/100;
  1724. if(sd->sc_data[SC_ETERNALCHAOS].timer!=-1) // エタ?ナルカオス
  1725. sd->def=0;
  1726. if(sd->sc_data[SC_CONCENTRATION].timer!=-1){ //コンセントレ?ション
  1727. sd->watk = sd->watk * (100 + 5*sd->sc_data[SC_CONCENTRATION].val1)/100;
  1728. index = sd->equip_index[8];
  1729. if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4)
  1730. sd->watk_ = sd->watk * (100 + 5*sd->sc_data[SC_CONCENTRATION].val1)/100;
  1731. sd->def = sd->def * (100 - 5*sd->sc_data[SC_CONCENTRATION].val1)/100;
  1732. }
  1733. if(sd->sc_data[SC_MAGICPOWER].timer!=-1){ //魔法力?幅
  1734. sd->matk1 = sd->matk1*(100+5*sd->sc_data[SC_MAGICPOWER].val1)/100;
  1735. sd->matk2 = sd->matk2*(100+5*sd->sc_data[SC_MAGICPOWER].val1)/100;
  1736. }
  1737. if(sd->sc_data[SC_ATKPOT].timer!=-1)
  1738. sd->watk += sd->sc_data[SC_ATKPOT].val1;
  1739. if(sd->sc_data[SC_MATKPOT].timer!=-1){
  1740. sd->matk1 += sd->sc_data[SC_MATKPOT].val1;
  1741. sd->matk2 += sd->sc_data[SC_MATKPOT].val1;
  1742. }
  1743. // ASPD/移動速度?化系
  1744. if(sd->sc_data[SC_TWOHANDQUICKEN].timer != -1 && sd->sc_data[SC_QUAGMIRE].timer == -1 && sd->sc_data[SC_DONTFORGETME].timer == -1) // 2HQ
  1745. aspd_rate -= 30;
  1746. if(sd->sc_data[SC_ADRENALINE].timer != -1 && sd->sc_data[SC_TWOHANDQUICKEN].timer == -1 &&
  1747. sd->sc_data[SC_QUAGMIRE].timer == -1 && sd->sc_data[SC_DONTFORGETME].timer == -1) { // アドレナリンラッシュ
  1748. if(sd->sc_data[SC_ADRENALINE].val2 || !battle_config.party_skill_penalty)
  1749. aspd_rate -= 30;
  1750. else
  1751. aspd_rate -= 25;
  1752. }
  1753. if(sd->sc_data[SC_SPEARSQUICKEN].timer != -1 && sd->sc_data[SC_ADRENALINE].timer == -1 &&
  1754. sd->sc_data[SC_TWOHANDQUICKEN].timer == -1 && sd->sc_data[SC_QUAGMIRE].timer == -1 && sd->sc_data[SC_DONTFORGETME].timer == -1) // スピアクィッケン
  1755. aspd_rate -= sd->sc_data[SC_SPEARSQUICKEN].val2;
  1756. if(sd->sc_data[SC_ASSNCROS].timer!=-1 && // 夕陽のアサシンクロス
  1757. sd->sc_data[SC_TWOHANDQUICKEN].timer==-1 && sd->sc_data[SC_ADRENALINE].timer==-1 && sd->sc_data[SC_SPEARSQUICKEN].timer==-1 &&
  1758. sd->sc_data[SC_DONTFORGETME].timer == -1)
  1759. aspd_rate -= 5+sd->sc_data[SC_ASSNCROS].val1+sd->sc_data[SC_ASSNCROS].val2+sd->sc_data[SC_ASSNCROS].val3;
  1760. if(sd->sc_data[SC_DONTFORGETME].timer!=-1){ // 私を忘れないで
  1761. aspd_rate += sd->sc_data[SC_DONTFORGETME].val1*3 + sd->sc_data[SC_DONTFORGETME].val2 + (sd->sc_data[SC_DONTFORGETME].val3>>16);
  1762. sd->speed= sd->speed*(100+sd->sc_data[SC_DONTFORGETME].val1*2 + sd->sc_data[SC_DONTFORGETME].val2 + (sd->sc_data[SC_DONTFORGETME].val3&0xffff))/100;
  1763. }
  1764. if( sd->sc_data[i=SC_SPEEDPOTION3].timer!=-1 ||
  1765. sd->sc_data[i=SC_SPEEDPOTION2].timer!=-1 ||
  1766. sd->sc_data[i=SC_SPEEDPOTION1].timer!=-1 ||
  1767. sd->sc_data[i=SC_SPEEDPOTION0].timer!=-1) // ? 速ポ?ション
  1768. aspd_rate -= sd->sc_data[i].val2;
  1769. if(sd->sc_data[SC_WINDWALK].timer!=-1 && sd->sc_data[SC_INCREASEAGI].timer==-1) //ウィンドウォ?ク暫ヘLv*2%減算
  1770. sd->speed -= sd->speed *(sd->sc_data[SC_WINDWALK].val1*2)/100;
  1771. if(sd->sc_data[SC_CARTBOOST].timer!=-1) // カ?トブ?スト
  1772. sd->speed -= (DEFAULT_WALK_SPEED * 20)/100;
  1773. if(sd->sc_data[SC_BERSERK].timer!=-1) //バ?サ?ク中はIAと同じぐらい速い?
  1774. sd->speed -= sd->speed *25/100;
  1775. if(sd->sc_data[SC_WEDDING].timer!=-1) //結婚中は?くのが?い
  1776. sd->speed = 2*DEFAULT_WALK_SPEED;
  1777. // HIT/FLEE?化系
  1778. if(sd->sc_data[SC_WHISTLE].timer!=-1){ // 口笛
  1779. sd->flee += sd->flee * (sd->sc_data[SC_WHISTLE].val1
  1780. +sd->sc_data[SC_WHISTLE].val2+(sd->sc_data[SC_WHISTLE].val3>>16))/100;
  1781. sd->flee2+= (sd->sc_data[SC_WHISTLE].val1+sd->sc_data[SC_WHISTLE].val2+(sd->sc_data[SC_WHISTLE].val3&0xffff)) * 10;
  1782. }
  1783. if(sd->sc_data[SC_HUMMING].timer!=-1) // ハミング
  1784. sd->hit += (sd->sc_data[SC_HUMMING].val1*2+sd->sc_data[SC_HUMMING].val2
  1785. +sd->sc_data[SC_HUMMING].val3) * sd->hit/100;
  1786. if(sd->sc_data[SC_VIOLENTGALE].timer!=-1 && sd->def_ele==4){ // バイオレントゲイル
  1787. sd->flee += sd->flee*sd->sc_data[SC_VIOLENTGALE].val3/100;
  1788. }
  1789. if(sd->sc_data[SC_BLIND].timer!=-1){ // 暗?
  1790. sd->hit -= sd->hit*25/100;
  1791. sd->flee -= sd->flee*25/100;
  1792. }
  1793. if(sd->sc_data[SC_WINDWALK].timer!=-1) // ウィンドウォ?ク
  1794. sd->flee += sd->flee*(sd->sc_data[SC_WINDWALK].val2)/100;
  1795. if(sd->sc_data[SC_SPIDERWEB].timer!=-1) //スパイダ?ウェブ
  1796. sd->flee -= sd->flee*50/100;
  1797. if(sd->sc_data[SC_TRUESIGHT].timer!=-1) //トゥル?サイト
  1798. sd->hit += 3*(sd->sc_data[SC_TRUESIGHT].val1);
  1799. if(sd->sc_data[SC_CONCENTRATION].timer!=-1) //コンセントレ?ション
  1800. sd->hit += (10*(sd->sc_data[SC_CONCENTRATION].val1));
  1801. // 耐性
  1802. if(sd->sc_data[SC_SIEGFRIED].timer!=-1){ // 不死身のジ?クフリ?ド
  1803. sd->subele[1] += sd->sc_data[SC_SIEGFRIED].val2; // 水
  1804. sd->subele[2] += sd->sc_data[SC_SIEGFRIED].val2; // 水
  1805. sd->subele[3] += sd->sc_data[SC_SIEGFRIED].val2; // 火
  1806. sd->subele[4] += sd->sc_data[SC_SIEGFRIED].val2; // 水
  1807. sd->subele[5] += sd->sc_data[SC_SIEGFRIED].val2; // 水
  1808. sd->subele[6] += sd->sc_data[SC_SIEGFRIED].val2; // 水
  1809. sd->subele[7] += sd->sc_data[SC_SIEGFRIED].val2; // 水
  1810. sd->subele[8] += sd->sc_data[SC_SIEGFRIED].val2; // 水
  1811. sd->subele[9] += sd->sc_data[SC_SIEGFRIED].val2; // 水
  1812. }
  1813. if(sd->sc_data[SC_PROVIDENCE].timer!=-1){ // プロヴィデンス
  1814. sd->subele[6] += sd->sc_data[SC_PROVIDENCE].val2; // ? 聖?性
  1815. sd->subrace[6] += sd->sc_data[SC_PROVIDENCE].val2; // ? ?魔
  1816. }
  1817. // その他
  1818. if(sd->sc_data[SC_APPLEIDUN].timer!=-1){ // イドゥンの林檎
  1819. sd->status.max_hp += ((5+sd->sc_data[SC_APPLEIDUN].val1*2+((sd->sc_data[SC_APPLEIDUN].val2+1)>>1)
  1820. +sd->sc_data[SC_APPLEIDUN].val3/10) * sd->status.max_hp)/100;
  1821. if(sd->status.max_hp < 0 || sd->status.max_hp > battle_config.max_hp)
  1822. sd->status.max_hp = battle_config.max_hp;
  1823. }
  1824. if(sd->sc_data[SC_DELUGE].timer!=-1 && sd->def_ele==1){ // デリュ?ジ
  1825. sd->status.max_hp += sd->status.max_hp*sd->sc_data[SC_DELUGE].val3/100;
  1826. if(sd->status.max_hp < 0 || sd->status.max_hp > battle_config.max_hp)
  1827. sd->status.max_hp = battle_config.max_hp;
  1828. }
  1829. if(sd->sc_data[SC_SERVICE4U].timer!=-1) { // サ?ビスフォ?ユ?
  1830. sd->status.max_sp += sd->status.max_sp*(10+sd->sc_data[SC_SERVICE4U].val1+sd->sc_data[SC_SERVICE4U].val2
  1831. +sd->sc_data[SC_SERVICE4U].val3)/100;
  1832. if(sd->status.max_sp < 0 || sd->status.max_sp > battle_config.max_sp)
  1833. sd->status.max_sp = battle_config.max_sp;
  1834. sd->dsprate-=(10+sd->sc_data[SC_SERVICE4U].val1*3+sd->sc_data[SC_SERVICE4U].val2
  1835. +sd->sc_data[SC_SERVICE4U].val3);
  1836. if(sd->dsprate<0)sd->dsprate=0;
  1837. }
  1838. if(sd->sc_data[SC_FORTUNE].timer!=-1) // 幸運のキス
  1839. sd->critical += (10+sd->sc_data[SC_FORTUNE].val1+sd->sc_data[SC_FORTUNE].val2
  1840. +sd->sc_data[SC_FORTUNE].val3)*10;
  1841. if(sd->sc_data[SC_EXPLOSIONSPIRITS].timer!=-1){ // 爆裂波動
  1842. if(s_class.job==23)
  1843. sd->critical += sd->sc_data[SC_EXPLOSIONSPIRITS].val1*100;
  1844. else
  1845. sd->critical += sd->sc_data[SC_EXPLOSIONSPIRITS].val2;
  1846. }
  1847. if(sd->sc_data[SC_STEELBODY].timer!=-1){ // 金剛
  1848. sd->def = 90;
  1849. sd->mdef = 90;
  1850. aspd_rate += 25;
  1851. sd->speed = (sd->speed * 125) / 100;
  1852. }
  1853. if(sd->sc_data[SC_DEFENDER].timer != -1) {
  1854. sd->aspd += (550 - sd->sc_data[SC_DEFENDER].val1*50);
  1855. // removed as of 12/14's patch [celest]
  1856. //sd->speed = (sd->speed * (155 - sd->sc_data[SC_DEFENDER].val1*5)) / 100;
  1857. }
  1858. if(sd->sc_data[SC_ENCPOISON].timer != -1)
  1859. sd->addeff[4] += sd->sc_data[SC_ENCPOISON].val2;
  1860. if( sd->sc_data[SC_DANCING].timer!=-1 ){ // 演奏/ダンス使用中
  1861. sd->speed = (double)sd->speed * (6.- 0.4 * pc_checkskill(sd, ((s_class.job == 19) ? BA_MUSICALLESSON : DC_DANCINGLESSON)));
  1862. //sd->speed*=4;
  1863. sd->nhealsp = 0;
  1864. sd->nshealsp = 0;
  1865. sd->nsshealsp = 0;
  1866. }
  1867. if(sd->sc_data[SC_CURSE].timer!=-1)
  1868. sd->speed += 450;
  1869. if(sd->sc_data[SC_TRUESIGHT].timer!=-1) //トゥル?サイト
  1870. sd->critical += sd->critical*(sd->sc_data[SC_TRUESIGHT].val1)/100;
  1871. /* if(sd->sc_data[SC_VOLCANO].timer!=-1) // エンチャントポイズン(?性はbattle.cで)
  1872. sd->addeff[2]+=sd->sc_data[SC_VOLCANO].val2;//% of granting
  1873. if(sd->sc_data[SC_DELUGE].timer!=-1) // エンチャントポイズン(?性はbattle.cで)
  1874. sd->addeff[0]+=sd->sc_data[SC_DELUGE].val2;//% of granting
  1875. */
  1876. if(sd->sc_data[SC_BERSERK].timer!=-1) { //All Def/MDef reduced to 0 while in Berserk [DracoRPG]
  1877. sd->def = sd->def2 = 0;
  1878. sd->mdef = sd->mdef2 = 0;
  1879. sd->flee -= sd->flee*50/100;
  1880. aspd_rate -= 30;
  1881. //sd->base_atk *= 3;
  1882. }
  1883. if(sd->sc_data[SC_KEEPING].timer!=-1)
  1884. sd->def = 100;
  1885. if(sd->sc_data[SC_BARRIER].timer!=-1)
  1886. sd->mdef = 100;
  1887. }
  1888. if(sd->speed_rate != 100)
  1889. sd->speed = sd->speed*sd->speed_rate/100;
  1890. if(sd->speed < 1) sd->speed = 1;
  1891. if(aspd_rate != 100)
  1892. sd->aspd = sd->aspd*aspd_rate/100;
  1893. if(pc_isriding(sd)) // 騎兵修練
  1894. sd->aspd = sd->aspd*(100 + 10*(5 - pc_checkskill(sd,KN_CAVALIERMASTERY)))/ 100;
  1895. if(sd->aspd < battle_config.max_aspd) sd->aspd = battle_config.max_aspd;
  1896. sd->amotion = sd->aspd;
  1897. sd->dmotion = 800-sd->paramc[1]*4;
  1898. if(sd->dmotion<400)
  1899. sd->dmotion = 400;
  1900. if(sd->skilltimer != -1 && (skill = pc_checkskill(sd,SA_FREECAST)) > 0) {
  1901. sd->prev_speed = sd->speed;
  1902. sd->speed = sd->speed*(175 - skill*5)/100;
  1903. }
  1904. if(sd->status.hp>sd->status.max_hp)
  1905. sd->status.hp=sd->status.max_hp;
  1906. if(sd->status.sp>sd->status.max_sp)
  1907. sd->status.sp=sd->status.max_sp;
  1908. if(first&4)
  1909. return 0;
  1910. if(first&3) {
  1911. clif_updatestatus(sd,SP_SPEED);
  1912. clif_updatestatus(sd,SP_MAXHP);
  1913. clif_updatestatus(sd,SP_MAXSP);
  1914. if(first&1) {
  1915. clif_updatestatus(sd,SP_HP);
  1916. clif_updatestatus(sd,SP_SP);
  1917. }
  1918. return 0;
  1919. }
  1920. if(b_class != sd->view_class) {
  1921. clif_changelook(&sd->bl,LOOK_BASE,sd->view_class);
  1922. #if PACKETVER < 4
  1923. clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
  1924. clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
  1925. #else
  1926. clif_changelook(&sd->bl,LOOK_WEAPON,0);
  1927. #endif
  1928. }
  1929. if( memcmp(b_skill,sd->status.skill,sizeof(sd->status.skill)) || b_attackrange != sd->attackrange)
  1930. clif_skillinfoblock(sd); // スキル送信
  1931. if(b_speed != sd->speed)
  1932. clif_updatestatus(sd,SP_SPEED);
  1933. if(b_weight != sd->weight)
  1934. clif_updatestatus(sd,SP_WEIGHT);
  1935. if(b_max_weight != sd->max_weight) {
  1936. clif_updatestatus(sd,SP_MAXWEIGHT);
  1937. pc_checkweighticon(sd);
  1938. }
  1939. for(i=0;i<6;i++)
  1940. if(b_paramb[i] + b_parame[i] != sd->paramb[i] + sd->parame[i])
  1941. clif_updatestatus(sd,SP_STR+i);
  1942. if(b_hit != sd->hit)
  1943. clif_updatestatus(sd,SP_HIT);
  1944. if(b_flee != sd->flee)
  1945. clif_updatestatus(sd,SP_FLEE1);
  1946. if(b_aspd != sd->aspd)
  1947. clif_updatestatus(sd,SP_ASPD);
  1948. if(b_watk != sd->watk || b_base_atk != sd->base_atk)
  1949. clif_updatestatus(sd,SP_ATK1);
  1950. if(b_def != sd->def)
  1951. clif_updatestatus(sd,SP_DEF1);
  1952. if(b_watk2 != sd->watk2)
  1953. clif_updatestatus(sd,SP_ATK2);
  1954. if(b_def2 != sd->def2)
  1955. clif_updatestatus(sd,SP_DEF2);
  1956. if(b_flee2 != sd->flee2)
  1957. clif_updatestatus(sd,SP_FLEE2);
  1958. if(b_critical != sd->critical)
  1959. clif_updatestatus(sd,SP_CRITICAL);
  1960. if(b_matk1 != sd->matk1)
  1961. clif_updatestatus(sd,SP_MATK1);
  1962. if(b_matk2 != sd->matk2)
  1963. clif_updatestatus(sd,SP_MATK2);
  1964. if(b_mdef != sd->mdef)
  1965. clif_updatestatus(sd,SP_MDEF1);
  1966. if(b_mdef2 != sd->mdef2)
  1967. clif_updatestatus(sd,SP_MDEF2);
  1968. if(b_attackrange != sd->attackrange)
  1969. clif_updatestatus(sd,SP_ATTACKRANGE);
  1970. if(b_max_hp != sd->status.max_hp)
  1971. clif_updatestatus(sd,SP_MAXHP);
  1972. if(b_max_sp != sd->status.max_sp)
  1973. clif_updatestatus(sd,SP_MAXSP);
  1974. if(b_hp != sd->status.hp)
  1975. clif_updatestatus(sd,SP_HP);
  1976. if(b_sp != sd->status.sp)
  1977. clif_updatestatus(sd,SP_SP);
  1978. /* if(before.cart_num != before.cart_num || before.cart_max_num != before.cart_max_num ||
  1979. before.cart_weight != before.cart_weight || before.cart_max_weight != before.cart_max_weight )
  1980. clif_updatestatus(sd,SP_CARTINFO);*/
  1981. //if(sd->status.hp<sd->status.max_hp>>2 && pc_checkskill(sd,SM_AUTOBERSERK)>0 &&
  1982. if(sd->status.hp<sd->status.max_hp>>2 && sd->sc_data[SC_AUTOBERSERK].timer != -1 &&
  1983. (sd->sc_data[SC_PROVOKE].timer==-1 || sd->sc_data[SC_PROVOKE].val2==0 ) && !pc_isdead(sd))
  1984. // オ?トバ?サ?ク?動
  1985. skill_status_change_start(&sd->bl,SC_PROVOKE,10,1,0,0,0,0);
  1986. return 0;
  1987. }
  1988. /*==========================================
  1989. * For quick calculating [Celest]
  1990. *------------------------------------------
  1991. */
  1992. int pc_calcspeed (struct map_session_data *sd)
  1993. {
  1994. int b_speed, skill;
  1995. struct pc_base_job s_class;
  1996. nullpo_retr(0, sd);
  1997. s_class = pc_calc_base_job(sd->status.class_);
  1998. b_speed = sd->speed;
  1999. sd->speed = DEFAULT_WALK_SPEED ;
  2000. if(sd->sc_count){
  2001. if(sd->sc_data[SC_INCREASEAGI].timer!=-1 && sd->sc_data[SC_QUAGMIRE].timer == -1 && sd->sc_data[SC_DONTFORGETME].timer == -1){ // 速度?加
  2002. sd->speed -= sd->speed *25/100;
  2003. }
  2004. if(sd->sc_data[SC_DECREASEAGI].timer!=-1) {
  2005. sd->speed = sd->speed *125/100;
  2006. }
  2007. if(sd->sc_data[SC_CLOAKING].timer!=-1) {
  2008. sd->speed = sd->speed * (sd->sc_data[SC_CLOAKING].val3-sd->sc_data[SC_CLOAKING].val1*3) /100;
  2009. }
  2010. if(sd->sc_data[SC_CHASEWALK].timer!=-1) {
  2011. sd->speed = sd->speed * sd->sc_data[SC_CHASEWALK].val3 /100;
  2012. }
  2013. if(sd->sc_data[SC_QUAGMIRE].timer!=-1){
  2014. sd->speed = sd->speed*3/2;
  2015. }
  2016. if(sd->sc_data[SC_WINDWALK].timer!=-1 && sd->sc_data[SC_INCREASEAGI].timer==-1) {
  2017. sd->speed -= sd->speed *(sd->sc_data[SC_WINDWALK].val1*2)/100;
  2018. }
  2019. if(sd->sc_data[SC_CARTBOOST].timer!=-1) {
  2020. sd->speed -= (DEFAULT_WALK_SPEED * 20)/100;
  2021. }
  2022. if(sd->sc_data[SC_BERSERK].timer!=-1) {
  2023. sd->speed -= sd->speed *25/100;
  2024. }
  2025. if(sd->sc_data[SC_WEDDING].timer!=-1) {
  2026. sd->speed = 2*DEFAULT_WALK_SPEED;
  2027. }
  2028. if(sd->sc_data[SC_DONTFORGETME].timer!=-1){
  2029. sd->speed= sd->speed*(100+sd->sc_data[SC_DONTFORGETME].val1*2 + sd->sc_data[SC_DONTFORGETME].val2 + (sd->sc_data[SC_DONTFORGETME].val3&0xffff))/100;
  2030. }
  2031. if(sd->sc_data[SC_STEELBODY].timer!=-1){
  2032. sd->speed = (sd->speed * 125) / 100;
  2033. }
  2034. if(sd->sc_data[SC_DEFENDER].timer != -1) {
  2035. // removed as of 12/14's patch [celest]
  2036. //sd->speed = (sd->speed * (155 - sd->sc_data[SC_DEFENDER].val1*5)) / 100;
  2037. }
  2038. if( sd->sc_data[SC_DANCING].timer!=-1 ){
  2039. sd->speed = (double)sd->speed * (6.- 0.4 * pc_checkskill(sd, ((s_class.job == 19) ? BA_MUSICALLESSON : DC_DANCINGLESSON)));
  2040. }
  2041. if(sd->sc_data[SC_CURSE].timer!=-1)
  2042. sd->speed += 450;
  2043. if(sd->sc_data[SC_SLOWDOWN].timer!=-1)
  2044. sd->speed = sd->speed*150/100;
  2045. if(sd->sc_data[SC_SPEEDUP0].timer!=-1)
  2046. sd->speed -= sd->speed*25/100;
  2047. }
  2048. if(sd->status.option&2 && (skill = pc_checkskill(sd,RG_TUNNELDRIVE))>0 )
  2049. sd->speed += (1.2*DEFAULT_WALK_SPEED - skill*9);
  2050. if (pc_iscarton(sd) && (skill=pc_checkskill(sd,MC_PUSHCART))>0)
  2051. sd->speed += (10-skill) * (DEFAULT_WALK_SPEED * 0.1);
  2052. else if (pc_isriding(sd)) {
  2053. sd->speed -= (0.25 * DEFAULT_WALK_SPEED);
  2054. }
  2055. if((skill=pc_checkskill(sd,TF_MISS))>0)
  2056. if(s_class.job==12)
  2057. sd->speed -= sd->speed *(skill*1.5)/100;
  2058. if(sd->speed_rate != 100)
  2059. sd->speed = sd->speed*sd->speed_rate/100;
  2060. if(sd->speed < 1) sd->speed = 1;
  2061. if(sd->skilltimer != -1 && (skill = pc_checkskill(sd,SA_FREECAST)) > 0) {
  2062. sd->prev_speed = sd->speed;
  2063. sd->speed = sd->speed*(175 - skill*5)/100;
  2064. }
  2065. if(b_speed != sd->speed)
  2066. clif_updatestatus(sd,SP_SPEED);
  2067. return 0;
  2068. }
  2069. /*==========================================
  2070. * ? 備品による能力等のボ?ナス設定
  2071. *------------------------------------------
  2072. */
  2073. int pc_bonus(struct map_session_data *sd,int type,int val)
  2074. {
  2075. nullpo_retr(0, sd);
  2076. switch(type){
  2077. case SP_STR:
  2078. case SP_AGI:
  2079. case SP_VIT:
  2080. case SP_INT:
  2081. case SP_DEX:
  2082. case SP_LUK:
  2083. if(sd->state.lr_flag != 2)
  2084. sd->parame[type-SP_STR]+=val;
  2085. break;
  2086. case SP_ATK1:
  2087. if(!sd->state.lr_flag)
  2088. sd->watk+=val;
  2089. else if(sd->state.lr_flag == 1)
  2090. sd->watk_+=val;
  2091. break;
  2092. case SP_ATK2:
  2093. if(!sd->state.lr_flag)
  2094. sd->watk2+=val;
  2095. else if(sd->state.lr_flag == 1)
  2096. sd->watk_2+=val;
  2097. break;
  2098. case SP_BASE_ATK:
  2099. if(sd->state.lr_flag != 2)
  2100. sd->base_atk+=val;
  2101. break;
  2102. case SP_MATK1:
  2103. if(sd->state.lr_flag != 2)
  2104. sd->matk1 += val;
  2105. break;
  2106. case SP_MATK2:
  2107. if(sd->state.lr_flag != 2)
  2108. sd->matk2 += val;
  2109. break;
  2110. case SP_MATK:
  2111. if(sd->state.lr_flag != 2) {
  2112. sd->matk1 += val;
  2113. sd->matk2 += val;
  2114. }
  2115. break;
  2116. case SP_DEF1:
  2117. if(sd->state.lr_flag != 2)
  2118. sd->def+=val;
  2119. break;
  2120. case SP_MDEF1:
  2121. if(sd->state.lr_flag != 2)
  2122. sd->mdef+=val;
  2123. break;
  2124. case SP_MDEF2:
  2125. if(sd->state.lr_flag != 2)
  2126. sd->mdef+=val;
  2127. break;
  2128. case SP_HIT:
  2129. if(sd->state.lr_flag != 2)
  2130. sd->hit+=val;
  2131. else
  2132. sd->arrow_hit+=val;
  2133. break;
  2134. case SP_FLEE1:
  2135. if(sd->state.lr_flag != 2)
  2136. sd->flee+=val;
  2137. break;
  2138. case SP_FLEE2:
  2139. if(sd->state.lr_flag != 2)
  2140. sd->flee2+=val*10;
  2141. break;
  2142. case SP_CRITICAL:
  2143. if(sd->state.lr_flag != 2)
  2144. sd->critical+=val*10;
  2145. else
  2146. sd->arrow_cri += val*10;
  2147. break;
  2148. case SP_ATKELE:
  2149. if(!sd->state.lr_flag)
  2150. sd->atk_ele=val;
  2151. else if(sd->state.lr_flag == 1)
  2152. sd->atk_ele_=val;
  2153. else if(sd->state.lr_flag == 2)
  2154. sd->arrow_ele=val;
  2155. break;
  2156. case SP_DEFELE:
  2157. if(sd->state.lr_flag != 2)
  2158. sd->def_ele=val;
  2159. break;
  2160. case SP_MAXHP:
  2161. if(sd->state.lr_flag != 2)
  2162. sd->status.max_hp+=val;
  2163. break;
  2164. case SP_MAXSP:
  2165. if(sd->state.lr_flag != 2)
  2166. sd->status.max_sp+=val;
  2167. break;
  2168. case SP_CASTRATE:
  2169. if(sd->state.lr_flag != 2)
  2170. sd->castrate+=val;
  2171. break;
  2172. case SP_MAXHPRATE:
  2173. if(sd->state.lr_flag != 2)
  2174. sd->hprate+=val;
  2175. break;
  2176. case SP_MAXSPRATE:
  2177. if(sd->state.lr_flag != 2)
  2178. sd->sprate+=val;
  2179. break;
  2180. case SP_SPRATE:
  2181. if(sd->state.lr_flag != 2)
  2182. sd->dsprate+=val;
  2183. break;
  2184. case SP_ATTACKRANGE:
  2185. if(!sd->state.lr_flag)
  2186. sd->attackrange += val;
  2187. else if(sd->state.lr_flag == 1)
  2188. sd->attackrange_ += val;
  2189. else if(sd->state.lr_flag == 2)
  2190. sd->arrow_range += val;
  2191. break;
  2192. case SP_ADD_SPEED:
  2193. if(sd->state.lr_flag != 2)
  2194. sd->speed -= val;
  2195. break;
  2196. case SP_SPEED_RATE:
  2197. if(sd->state.lr_flag != 2) {
  2198. if(sd->speed_rate > 100-val)
  2199. sd->speed_rate = 100-val;
  2200. }
  2201. break;
  2202. case SP_SPEED_ADDRATE:
  2203. if(sd->state.lr_flag != 2)
  2204. sd->speed_add_rate = sd->speed_add_rate * (100-val)/100;
  2205. break;
  2206. case SP_ASPD:
  2207. if(sd->state.lr_flag != 2)
  2208. sd->aspd -= val*10;
  2209. break;
  2210. case SP_ASPD_RATE:
  2211. if(sd->state.lr_flag != 2) {
  2212. if(sd->aspd_rate > 100-val)
  2213. sd->aspd_rate = 100-val;
  2214. }
  2215. break;
  2216. case SP_ASPD_ADDRATE:
  2217. if(sd->state.lr_flag != 2)
  2218. sd->aspd_add_rate = sd->aspd_add_rate * (100-val)/100;
  2219. break;
  2220. case SP_HP_RECOV_RATE:
  2221. if(sd->state.lr_flag != 2)
  2222. sd->hprecov_rate += val;
  2223. break;
  2224. case SP_SP_RECOV_RATE:
  2225. if(sd->state.lr_flag != 2)
  2226. sd->sprecov_rate += val;
  2227. break;
  2228. case SP_CRITICAL_DEF:
  2229. if(sd->state.lr_flag != 2)
  2230. sd->critical_def += val;
  2231. break;
  2232. case SP_NEAR_ATK_DEF:
  2233. if(sd->state.lr_flag != 2)
  2234. sd->near_attack_def_rate += val;
  2235. break;
  2236. case SP_LONG_ATK_DEF:
  2237. if(sd->state.lr_flag != 2)
  2238. sd->long_attack_def_rate += val;
  2239. break;
  2240. case SP_DOUBLE_RATE:
  2241. if(sd->state.lr_flag == 0 && sd->double_rate < val)
  2242. sd->double_rate = val;
  2243. break;
  2244. case SP_DOUBLE_ADD_RATE:
  2245. if(sd->state.lr_flag == 0)
  2246. sd->double_add_rate += val;
  2247. break;
  2248. case SP_MATK_RATE:
  2249. if(sd->state.lr_flag != 2)
  2250. sd->matk_rate += val;
  2251. break;
  2252. case SP_IGNORE_DEF_ELE:
  2253. if(!sd->state.lr_flag)
  2254. sd->ignore_def_ele |= 1<<val;
  2255. else if(sd->state.lr_flag == 1)
  2256. sd->ignore_def_ele_ |= 1<<val;
  2257. break;
  2258. case SP_IGNORE_DEF_RACE:
  2259. if(!sd->state.lr_flag)
  2260. sd->ignore_def_race |= 1<<val;
  2261. else if(sd->state.lr_flag == 1)
  2262. sd->ignore_def_race_ |= 1<<val;
  2263. break;
  2264. case SP_ATK_RATE:
  2265. if(sd->state.lr_flag != 2)
  2266. sd->atk_rate += val;
  2267. break;
  2268. case SP_MAGIC_ATK_DEF:
  2269. if(sd->state.lr_flag != 2)
  2270. sd->magic_def_rate += val;
  2271. break;
  2272. case SP_MISC_ATK_DEF:
  2273. if(sd->state.lr_flag != 2)
  2274. sd->misc_def_rate += val;
  2275. break;
  2276. case SP_IGNORE_MDEF_ELE:
  2277. if(sd->state.lr_flag != 2)
  2278. sd->ignore_mdef_ele |= 1<<val;
  2279. break;
  2280. case SP_IGNORE_MDEF_RACE:
  2281. if(sd->state.lr_flag != 2)
  2282. sd->ignore_mdef_race |= 1<<val;
  2283. break;
  2284. case SP_PERFECT_HIT_RATE:
  2285. if(sd->state.lr_flag != 2 && sd->perfect_hit < val)
  2286. sd->perfect_hit = val;
  2287. break;
  2288. case SP_PERFECT_HIT_ADD_RATE:
  2289. if(sd->state.lr_flag != 2)
  2290. sd->perfect_hit_add += val;
  2291. break;
  2292. case SP_CRITICAL_RATE:
  2293. if(sd->state.lr_flag != 2)
  2294. sd->critical_rate+=val;
  2295. break;
  2296. case SP_GET_ZENY_NUM:
  2297. if(sd->state.lr_flag != 2 && sd->get_zeny_num < val)
  2298. sd->get_zeny_num = val;
  2299. break;
  2300. case SP_ADD_GET_ZENY_NUM:
  2301. if(sd->state.lr_flag != 2)
  2302. sd->get_zeny_add_num += val;
  2303. break;
  2304. case SP_DEF_RATIO_ATK_ELE:
  2305. if(!sd->state.lr_flag)
  2306. sd->def_ratio_atk_ele |= 1<<val;
  2307. else if(sd->state.lr_flag == 1)
  2308. sd->def_ratio_atk_ele_ |= 1<<val;
  2309. break;
  2310. case SP_DEF_RATIO_ATK_RACE:
  2311. if(!sd->state.lr_flag)
  2312. sd->def_ratio_atk_race |= 1<<val;
  2313. else if(sd->state.lr_flag == 1)
  2314. sd->def_ratio_atk_race_ |= 1<<val;
  2315. break;
  2316. case SP_HIT_RATE:
  2317. if(sd->state.lr_flag != 2)
  2318. sd->hit_rate += val;
  2319. break;
  2320. case SP_FLEE_RATE:
  2321. if(sd->state.lr_flag != 2)
  2322. sd->flee_rate += val;
  2323. break;
  2324. case SP_FLEE2_RATE:
  2325. if(sd->state.lr_flag != 2)
  2326. sd->flee2_rate += val;
  2327. break;
  2328. case SP_DEF_RATE:
  2329. if(sd->state.lr_flag != 2)
  2330. sd->def_rate += val;
  2331. break;
  2332. case SP_DEF2_RATE:
  2333. if(sd->state.lr_flag != 2)
  2334. sd->def2_rate += val;
  2335. break;
  2336. case SP_MDEF_RATE:
  2337. if(sd->state.lr_flag != 2)
  2338. sd->mdef_rate += val;
  2339. break;
  2340. case SP_MDEF2_RATE:
  2341. if(sd->state.lr_flag != 2)
  2342. sd->mdef2_rate += val;
  2343. break;
  2344. case SP_RESTART_FULL_RECORVER:
  2345. if(sd->state.lr_flag != 2)
  2346. sd->special_state.restart_full_recover = 1;
  2347. break;
  2348. case SP_NO_CASTCANCEL:
  2349. if(sd->state.lr_flag != 2)
  2350. sd->special_state.no_castcancel = 1;
  2351. break;
  2352. case SP_NO_CASTCANCEL2:
  2353. if(sd->state.lr_flag != 2)
  2354. sd->special_state.no_castcancel2 = 1;
  2355. break;
  2356. case SP_NO_SIZEFIX:
  2357. if(sd->state.lr_flag != 2)
  2358. sd->special_state.no_sizefix = 1;
  2359. break;
  2360. case SP_NO_MAGIC_DAMAGE:
  2361. if(sd->state.lr_flag != 2)
  2362. sd->special_state.no_magic_damage = 1;
  2363. break;
  2364. case SP_NO_WEAPON_DAMAGE:
  2365. if(sd->state.lr_flag != 2)
  2366. sd->special_state.no_weapon_damage = 1;
  2367. break;
  2368. case SP_NO_GEMSTONE:
  2369. if(sd->state.lr_flag != 2)
  2370. sd->special_state.no_gemstone = 1;
  2371. break;
  2372. case SP_INFINITE_ENDURE:
  2373. if(sd->state.lr_flag != 2)
  2374. sd->special_state.infinite_endure = 1;
  2375. break;
  2376. case SP_UNBREAKABLE_WEAPON:
  2377. if(sd->state.lr_flag != 2)
  2378. sd->unbreakable_equip |= EQP_WEAPON;
  2379. break;
  2380. case SP_UNBREAKABLE_ARMOR:
  2381. if(sd->state.lr_flag != 2)
  2382. sd->unbreakable_equip |= EQP_ARMOR;
  2383. break;
  2384. case SP_UNBREAKABLE_HELM:
  2385. if(sd->state.lr_flag != 2)
  2386. sd->unbreakable_equip |= EQP_HELM;
  2387. break;
  2388. case SP_UNBREAKABLE_SHIELD:
  2389. if(sd->state.lr_flag != 2)
  2390. sd->unbreakable_equip |= EQP_SHIELD;
  2391. break;
  2392. case SP_SPLASH_RANGE:
  2393. if(sd->state.lr_flag != 2 && sd->splash_range < val)
  2394. sd->splash_range = val;
  2395. break;
  2396. case SP_SPLASH_ADD_RANGE:
  2397. if(sd->state.lr_flag != 2)
  2398. sd->splash_add_range += val;
  2399. break;
  2400. case SP_SHORT_WEAPON_DAMAGE_RETURN:
  2401. if(sd->state.lr_flag != 2)
  2402. sd->short_weapon_damage_return += val;
  2403. break;
  2404. case SP_LONG_WEAPON_DAMAGE_RETURN:
  2405. if(sd->state.lr_flag != 2)
  2406. sd->long_weapon_damage_return += val;
  2407. break;
  2408. case SP_MAGIC_DAMAGE_RETURN: //AppleGirl Was Here
  2409. if(sd->state.lr_flag != 2)
  2410. sd->magic_damage_return += val;
  2411. break;
  2412. case SP_ALL_STATS: // [Valaris]
  2413. if(sd->state.lr_flag!=2) {
  2414. sd->parame[SP_STR-SP_STR]+=val;
  2415. sd->parame[SP_AGI-SP_STR]+=val;
  2416. sd->parame[SP_VIT-SP_STR]+=val;
  2417. sd->parame[SP_INT-SP_STR]+=val;
  2418. sd->parame[SP_DEX-SP_STR]+=val;
  2419. sd->parame[SP_LUK-SP_STR]+=val;
  2420. clif_updatestatus(sd,13);
  2421. clif_updatestatus(sd,14);
  2422. clif_updatestatus(sd,15);
  2423. clif_updatestatus(sd,16);
  2424. clif_updatestatus(sd,17);
  2425. clif_updatestatus(sd,18);
  2426. }
  2427. break;
  2428. case SP_AGI_VIT: // [Valaris]
  2429. if(sd->state.lr_flag!=2) {
  2430. sd->parame[SP_AGI-SP_STR]+=val;
  2431. sd->parame[SP_VIT-SP_STR]+=val;
  2432. clif_updatestatus(sd,14);
  2433. clif_updatestatus(sd,15);
  2434. }
  2435. break;
  2436. case SP_AGI_DEX_STR: // [Valaris]
  2437. if(sd->state.lr_flag!=2) {
  2438. sd->parame[SP_AGI-SP_STR]+=val;
  2439. sd->parame[SP_DEX-SP_STR]+=val;
  2440. sd->parame[SP_STR-SP_STR]+=val;
  2441. clif_updatestatus(sd,14);
  2442. clif_updatestatus(sd,17);
  2443. clif_updatestatus(sd,13);
  2444. }
  2445. break;
  2446. case SP_PERFECT_HIDE: // [Valaris]
  2447. if(sd->state.lr_flag!=2) {
  2448. sd->perfect_hiding=1;
  2449. }
  2450. break;
  2451. case SP_DISGUISE: // Disguise script for items [Valaris]
  2452. if(sd->state.lr_flag!=2 && sd->disguiseflag==0) {
  2453. if(pc_isriding(sd)) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris]
  2454. clif_displaymessage(sd->fd, "Cannot wear disguise when riding a Peco.");
  2455. break;
  2456. }
  2457. sd->disguise=val;
  2458. clif_clearchar(&sd->bl, 9);
  2459. pc_setpos(sd, sd->mapname, sd->bl.x, sd->bl.y, 3);
  2460. }
  2461. break;
  2462. case SP_UNBREAKABLE:
  2463. if(sd->state.lr_flag!=2) {
  2464. sd->unbreakable += val;
  2465. }
  2466. break;
  2467. case SP_CLASSCHANGE: // [Valaris]
  2468. if(sd->state.lr_flag !=2){
  2469. sd->classchange=val;
  2470. }
  2471. break;
  2472. case SP_LONG_ATK_RATE:
  2473. if(sd->status.weapon == 11 && sd->state.lr_flag != 2)
  2474. sd->atk_rate += val;
  2475. break;
  2476. case SP_DELAYRATE:
  2477. if(sd->state.lr_flag != 2)
  2478. sd->delayrate+=val;
  2479. break;
  2480. default:
  2481. if(battle_config.error_log)
  2482. printf("pc_bonus: unknown type %d %d !\n",type,val);
  2483. break;
  2484. }
  2485. return 0;
  2486. }
  2487. /*==========================================
  2488. * ? 備品による能力等のボ?ナス設定
  2489. *------------------------------------------
  2490. */
  2491. int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
  2492. {
  2493. int i;
  2494. nullpo_retr(0, sd);
  2495. switch(type){
  2496. case SP_ADDELE:
  2497. if(!sd->state.lr_flag)
  2498. sd->addele[type2]+=val;
  2499. else if(sd->state.lr_flag == 1)
  2500. sd->addele_[type2]+=val;
  2501. else if(sd->state.lr_flag == 2)
  2502. sd->arrow_addele[type2]+=val;
  2503. break;
  2504. case SP_ADDRACE:
  2505. if(!sd->state.lr_flag)
  2506. sd->addrace[type2]+=val;
  2507. else if(sd->state.lr_flag == 1)
  2508. sd->addrace_[type2]+=val;
  2509. else if(sd->state.lr_flag == 2)
  2510. sd->arrow_addrace[type2]+=val;
  2511. break;
  2512. case SP_ADDSIZE:
  2513. if(!sd->state.lr_flag)
  2514. sd->addsize[type2]+=val;
  2515. else if(sd->state.lr_flag == 1)
  2516. sd->addsize_[type2]+=val;
  2517. else if(sd->state.lr_flag == 2)
  2518. sd->arrow_addsize[type2]+=val;
  2519. break;
  2520. case SP_SUBELE:
  2521. if(sd->state.lr_flag != 2)
  2522. sd->subele[type2]+=val;
  2523. break;
  2524. case SP_SUBRACE:
  2525. if(sd->state.lr_flag != 2)
  2526. sd->subrace[type2]+=val;
  2527. break;
  2528. case SP_ADDEFF:
  2529. if(sd->state.lr_flag != 2)
  2530. sd->addeff[type2]+=val;
  2531. else
  2532. sd->arrow_addeff[type2]+=val;
  2533. break;
  2534. case SP_ADDEFF2:
  2535. if(sd->state.lr_flag != 2)
  2536. sd->addeff2[type2]+=val;
  2537. else
  2538. sd->arrow_addeff2[type2]+=val;
  2539. break;
  2540. case SP_RESEFF:
  2541. if(sd->state.lr_flag != 2)
  2542. sd->reseff[type2]+=val;
  2543. break;
  2544. case SP_MAGIC_ADDELE:
  2545. if(sd->state.lr_flag != 2)
  2546. sd->magic_addele[type2]+=val;
  2547. break;
  2548. case SP_MAGIC_ADDRACE:
  2549. if(sd->state.lr_flag != 2)
  2550. sd->magic_addrace[type2]+=val;
  2551. break;
  2552. case SP_MAGIC_SUBRACE:
  2553. if(sd->state.lr_flag != 2)
  2554. sd->magic_subrace[type2]+=val;
  2555. break;
  2556. case SP_ADD_DAMAGE_CLASS:
  2557. if(!sd->state.lr_flag) {
  2558. for(i=0;i<sd->add_damage_class_count;i++) {
  2559. if(sd->add_damage_classid[i] == type2) {
  2560. sd->add_damage_classrate[i] += val;
  2561. break;
  2562. }
  2563. }
  2564. if(i >= sd->add_damage_class_count && sd->add_damage_class_count < 10) {
  2565. sd->add_damage_classid[sd->add_damage_class_count] = type2;
  2566. sd->add_damage_classrate[sd->add_damage_class_count] += val;
  2567. sd->add_damage_class_count++;
  2568. }
  2569. }
  2570. else if(sd->state.lr_flag == 1) {
  2571. for(i=0;i<sd->add_damage_class_count_;i++) {
  2572. if(sd->add_damage_classid_[i] == type2) {
  2573. sd->add_damage_classrate_[i] += val;
  2574. break;
  2575. }
  2576. }
  2577. if(i >= sd->add_damage_class_count_ && sd->add_damage_class_count_ < 10) {
  2578. sd->add_damage_classid_[sd->add_damage_class_count_] = type2;
  2579. sd->add_damage_classrate_[sd->add_damage_class_count_] += val;
  2580. sd->add_damage_class_count_++;
  2581. }
  2582. }
  2583. break;
  2584. case SP_ADD_MAGIC_DAMAGE_CLASS:
  2585. if(sd->state.lr_flag != 2) {
  2586. for(i=0;i<sd->add_magic_damage_class_count;i++) {
  2587. if(sd->add_magic_damage_classid[i] == type2) {
  2588. sd->add_magic_damage_classrate[i] += val;
  2589. break;
  2590. }
  2591. }
  2592. if(i >= sd->add_magic_damage_class_count && sd->add_magic_damage_class_count < 10) {
  2593. sd->add_magic_damage_classid[sd->add_magic_damage_class_count] = type2;
  2594. sd->add_magic_damage_classrate[sd->add_magic_damage_class_count] += val;
  2595. sd->add_magic_damage_class_count++;
  2596. }
  2597. }
  2598. break;
  2599. case SP_ADD_DEF_CLASS:
  2600. if(sd->state.lr_flag != 2) {
  2601. for(i=0;i<sd->add_def_class_count;i++) {
  2602. if(sd->add_def_classid[i] == type2) {
  2603. sd->add_def_classrate[i] += val;
  2604. break;
  2605. }
  2606. }
  2607. if(i >= sd->add_def_class_count && sd->add_def_class_count < 10) {
  2608. sd->add_def_classid[sd->add_def_class_count] = type2;
  2609. sd->add_def_classrate[sd->add_def_class_count] += val;
  2610. sd->add_def_class_count++;
  2611. }
  2612. }
  2613. break;
  2614. case SP_ADD_MDEF_CLASS:
  2615. if(sd->state.lr_flag != 2) {
  2616. for(i=0;i<sd->add_mdef_class_count;i++) {
  2617. if(sd->add_mdef_classid[i] == type2) {
  2618. sd->add_mdef_classrate[i] += val;
  2619. break;
  2620. }
  2621. }
  2622. if(i >= sd->add_mdef_class_count && sd->add_mdef_class_count < 10) {
  2623. sd->add_mdef_classid[sd->add_mdef_class_count] = type2;
  2624. sd->add_mdef_classrate[sd->add_mdef_class_count] += val;
  2625. sd->add_mdef_class_count++;
  2626. }
  2627. }
  2628. break;
  2629. case SP_HP_DRAIN_RATE:
  2630. if(!sd->state.lr_flag) {
  2631. sd->hp_drain_rate += type2;
  2632. sd->hp_drain_per += val;
  2633. }
  2634. else if(sd->state.lr_flag == 1) {
  2635. sd->hp_drain_rate_ += type2;
  2636. sd->hp_drain_per_ += val;
  2637. }
  2638. break;
  2639. case SP_HP_DRAIN_VALUE:
  2640. if(!sd->state.lr_flag) {
  2641. sd->hp_drain_rate += type2;
  2642. sd->hp_drain_value += val;
  2643. }
  2644. else if(sd->state.lr_flag == 1) {
  2645. sd->hp_drain_rate_ += type2;
  2646. sd->hp_drain_value_ += val;
  2647. }
  2648. break;
  2649. case SP_SP_DRAIN_RATE:
  2650. if(!sd->state.lr_flag) {
  2651. sd->sp_drain_rate += type2;
  2652. sd->sp_drain_per += val;
  2653. }
  2654. else if(sd->state.lr_flag == 1) {
  2655. sd->sp_drain_rate_ += type2;
  2656. sd->sp_drain_per_ += val;
  2657. }
  2658. break;
  2659. case SP_SP_DRAIN_VALUE:
  2660. if(!sd->state.lr_flag) {
  2661. sd->sp_drain_rate += type2;
  2662. sd->sp_drain_value += val;
  2663. }
  2664. else if(sd->state.lr_flag == 1) {
  2665. sd->sp_drain_rate_ += type2;
  2666. sd->sp_drain_value_ += val;
  2667. }
  2668. break;
  2669. case SP_WEAPON_COMA_ELE:
  2670. if(sd->state.lr_flag != 2)
  2671. sd->weapon_coma_ele[type2] += val;
  2672. break;
  2673. case SP_WEAPON_COMA_RACE:
  2674. if(sd->state.lr_flag != 2)
  2675. sd->weapon_coma_race[type2] += val;
  2676. break;
  2677. case SP_RANDOM_ATTACK_INCREASE: // [Valaris]
  2678. if(sd->state.lr_flag !=2){
  2679. sd->random_attack_increase_add = type2;
  2680. sd->random_attack_increase_per += val;
  2681. }
  2682. break;
  2683. case SP_WEAPON_ATK:
  2684. if(sd->state.lr_flag != 2)
  2685. sd->weapon_atk[type2]+=val;
  2686. break;
  2687. case SP_WEAPON_ATK_RATE:
  2688. if(sd->state.lr_flag != 2)
  2689. sd->weapon_atk_rate[type2]+=val;
  2690. break;
  2691. default:
  2692. if(battle_config.error_log)
  2693. printf("pc_bonus2: unknown type %d %d %d!\n",type,type2,val);
  2694. break;
  2695. }
  2696. return 0;
  2697. }
  2698. int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
  2699. {
  2700. int i;
  2701. switch(type){
  2702. case SP_ADD_MONSTER_DROP_ITEM:
  2703. if(sd->state.lr_flag != 2) {
  2704. for(i=0;i<sd->monster_drop_item_count;i++) {
  2705. if(sd->monster_drop_itemid[i] == type2) {
  2706. sd->monster_drop_race[i] |= 1<<type3;
  2707. if(sd->monster_drop_itemrate[i] < val)
  2708. sd->monster_drop_itemrate[i] = val;
  2709. break;
  2710. }
  2711. }
  2712. if(i >= sd->monster_drop_item_count && sd->monster_drop_item_count < 10) {
  2713. sd->monster_drop_itemid[sd->monster_drop_item_count] = type2;
  2714. sd->monster_drop_race[sd->monster_drop_item_count] |= 1<<type3;
  2715. sd->monster_drop_itemrate[sd->monster_drop_item_count] = val;
  2716. sd->monster_drop_item_count++;
  2717. }
  2718. }
  2719. break;
  2720. case SP_AUTOSPELL:
  2721. if(sd->state.lr_flag != 2){
  2722. sd->autospell_id = type2;
  2723. sd->autospell_lv = type3;
  2724. sd->autospell_rate = val;
  2725. }
  2726. break;
  2727. default:
  2728. if(battle_config.error_log)
  2729. printf("pc_bonus3: unknown type %d %d %d %d!\n",type,type2,type3,val);
  2730. break;
  2731. }
  2732. return 0;
  2733. }
  2734. /*==========================================
  2735. * スクリプトによるスキル所得
  2736. *------------------------------------------
  2737. */
  2738. int pc_skill(struct map_session_data *sd,int id,int level,int flag)
  2739. {
  2740. nullpo_retr(0, sd);
  2741. if(level>MAX_SKILL_LEVEL){
  2742. if(battle_config.error_log)
  2743. printf("support card skill only!\n");
  2744. return 0;
  2745. }
  2746. if(!flag && (sd->status.skill[id].id == id || level == 0)){ // クエスト所得ならここで?件を確認して送信する
  2747. sd->status.skill[id].lv=level;
  2748. pc_calcstatus(sd,0);
  2749. clif_skillinfoblock(sd);
  2750. }
  2751. else if(flag==2 && (sd->status.skill[id].id == id || level == 0)){ // クエスト所得ならここで?件を確認して送信する
  2752. sd->status.skill[id].lv+=level;
  2753. pc_calcstatus(sd,0);
  2754. clif_skillinfoblock(sd);
  2755. }
  2756. else if(sd->status.skill[id].lv < level){ // ?えられるがlvが小さいなら
  2757. if(sd->status.skill[id].id==id)
  2758. sd->status.skill[id].flag=sd->status.skill[id].lv+2; // lvを記憶
  2759. else {
  2760. sd->status.skill[id].id=id;
  2761. sd->status.skill[id].flag=1; // cardスキルとする
  2762. }
  2763. sd->status.skill[id].lv=level;
  2764. }
  2765. return 0;
  2766. }
  2767. /*==========================================
  2768. * カ?ド?入
  2769. *------------------------------------------
  2770. */
  2771. int pc_insert_card(struct map_session_data *sd,int idx_card,int idx_equip)
  2772. {
  2773. nullpo_retr(0, sd);
  2774. if(idx_card >= 0 && idx_card < MAX_INVENTORY && idx_equip >= 0 && idx_equip < MAX_INVENTORY && sd->inventory_data[idx_card]) {
  2775. int i;
  2776. int nameid=sd->status.inventory[idx_equip].nameid;
  2777. int cardid=sd->status.inventory[idx_card].nameid;
  2778. int ep=sd->inventory_data[idx_card]->equip;
  2779. if( nameid <= 0 || sd->inventory_data[idx_equip] == NULL ||
  2780. (sd->inventory_data[idx_equip]->type!=4 && sd->inventory_data[idx_equip]->type!=5)|| // ? 備じゃない
  2781. ( sd->status.inventory[idx_equip].identify==0 ) || // 未鑑定
  2782. ( sd->status.inventory[idx_equip].card[0]==0x00ff) || // 製造武器
  2783. ( sd->status.inventory[idx_equip].card[0]==0x00fe) ||
  2784. ( (sd->inventory_data[idx_equip]->equip&ep)==0 ) || // ? 備個所違い
  2785. ( sd->inventory_data[idx_equip]->type==4 && ep==32) || // ? 手武器と盾カ?ド
  2786. ( sd->status.inventory[idx_equip].card[0]==(short)0xff00) || sd->status.inventory[idx_equip].equip){
  2787. clif_insert_card(sd,idx_equip,idx_card,1);
  2788. return 0;
  2789. }
  2790. for(i=0;i<sd->inventory_data[idx_equip]->slot;i++){
  2791. if( sd->status.inventory[idx_equip].card[i] == 0){
  2792. // 空きスロットがあったので差し?む
  2793. sd->status.inventory[idx_equip].card[i]=cardid;
  2794. // カ?ドは減らす
  2795. clif_insert_card(sd,idx_equip,idx_card,0);
  2796. pc_delitem(sd,idx_card,1,1);
  2797. return 0;
  2798. }
  2799. }
  2800. }
  2801. else
  2802. clif_insert_card(sd,idx_equip,idx_card,1);
  2803. return 0;
  2804. }
  2805. //
  2806. // アイテム物
  2807. //
  2808. /*==========================================
  2809. * スキルによる買い値修正
  2810. *------------------------------------------
  2811. */
  2812. int pc_modifybuyvalue(struct map_session_data *sd,int orig_value)
  2813. {
  2814. int skill,val = orig_value,rate1 = 0,rate2 = 0;
  2815. if((skill=pc_checkskill(sd,MC_DISCOUNT))>0) // ディスカウント
  2816. rate1 = 5+skill*2-((skill==10)? 1:0);
  2817. if((skill=pc_checkskill(sd,RG_COMPULSION))>0) // コムパルションディスカウント
  2818. rate2 = 5+skill*4;
  2819. if(rate1 < rate2) rate1 = rate2;
  2820. if(rate1)
  2821. val = (int)((double)orig_value*(double)(100-rate1)/100.);
  2822. if(val < 0) val = 0;
  2823. if(orig_value > 0 && val < 1) val = 1;
  2824. return val;
  2825. }
  2826. /*==========================================
  2827. * スキルによる?り値修正
  2828. *------------------------------------------
  2829. */
  2830. int pc_modifysellvalue(struct map_session_data *sd,int orig_value)
  2831. {
  2832. int skill,val = orig_value,rate = 0;
  2833. if((skill=pc_checkskill(sd,MC_OVERCHARGE))>0) // オ?バ?チャ?ジ
  2834. rate = 5+skill*2-((skill==10)? 1:0);
  2835. if(rate)
  2836. val = (int)((double)orig_value*(double)(100+rate)/100.);
  2837. if(val < 0) val = 0;
  2838. if(orig_value > 0 && val < 1) val = 1;
  2839. return val;
  2840. }
  2841. /*==========================================
  2842. * アイテムを買った暫ノ、新しいアイテム欄を使うか、
  2843. * 3万個制限にかかるか確認
  2844. *------------------------------------------
  2845. */
  2846. int pc_checkadditem(struct map_session_data *sd,int nameid,int amount)
  2847. {
  2848. int i;
  2849. nullpo_retr(0, sd);
  2850. if(itemdb_isequip(nameid))
  2851. return ADDITEM_NEW;
  2852. for(i=0;i<MAX_INVENTORY;i++){
  2853. if(sd->status.inventory[i].nameid==nameid){
  2854. if(sd->status.inventory[i].amount+amount > MAX_AMOUNT)
  2855. return ADDITEM_OVERAMOUNT;
  2856. return ADDITEM_EXIST;
  2857. }
  2858. }
  2859. if(amount > MAX_AMOUNT)
  2860. return ADDITEM_OVERAMOUNT;
  2861. return ADDITEM_NEW;
  2862. }
  2863. /*==========================================
  2864. * 空きアイテム欄の個?
  2865. *------------------------------------------
  2866. */
  2867. int pc_inventoryblank(struct map_session_data *sd)
  2868. {
  2869. int i,b;
  2870. nullpo_retr(0, sd);
  2871. for(i=0,b=0;i<MAX_INVENTORY;i++){
  2872. if(sd->status.inventory[i].nameid==0)
  2873. b++;
  2874. }
  2875. return b;
  2876. }
  2877. /*==========================================
  2878. * お金を?う
  2879. *------------------------------------------
  2880. */
  2881. int pc_payzeny(struct map_session_data *sd,int zeny)
  2882. {
  2883. double z;
  2884. nullpo_retr(0, sd);
  2885. z = (double)sd->status.zeny;
  2886. if(sd->status.zeny<zeny || z - (double)zeny > MAX_ZENY)
  2887. return 1;
  2888. sd->status.zeny-=zeny;
  2889. clif_updatestatus(sd,SP_ZENY);
  2890. return 0;
  2891. }
  2892. /*==========================================
  2893. * お金を得る
  2894. *------------------------------------------
  2895. */
  2896. int pc_getzeny(struct map_session_data *sd,int zeny)
  2897. {
  2898. double z;
  2899. nullpo_retr(0, sd);
  2900. z = (double)sd->status.zeny;
  2901. if(z + (double)zeny > MAX_ZENY) {
  2902. zeny = 0;
  2903. sd->status.zeny = MAX_ZENY;
  2904. }
  2905. sd->status.zeny+=zeny;
  2906. clif_updatestatus(sd,SP_ZENY);
  2907. return 0;
  2908. }
  2909. /*==========================================
  2910. * アイテムを探して、インデックスを返す
  2911. *------------------------------------------
  2912. */
  2913. int pc_search_inventory(struct map_session_data *sd,int item_id)
  2914. {
  2915. int i;
  2916. nullpo_retr(-1, sd);
  2917. for(i=0;i<MAX_INVENTORY;i++) {
  2918. if(sd->status.inventory[i].nameid == item_id &&
  2919. (sd->status.inventory[i].amount > 0 || item_id == 0))
  2920. return i;
  2921. }
  2922. return -1;
  2923. }
  2924. /*==========================================
  2925. * アイテム追加。個?のみitem構造?の?字を無視
  2926. *------------------------------------------
  2927. */
  2928. int pc_additem(struct map_session_data *sd,struct item *item_data,int amount)
  2929. {
  2930. struct item_data *data;
  2931. int i,w;
  2932. nullpo_retr(1, sd);
  2933. nullpo_retr(1, item_data);
  2934. if(item_data->nameid <= 0 || amount <= 0)
  2935. return 1;
  2936. data = itemdb_search(item_data->nameid);
  2937. if((w = data->weight*amount) + sd->weight > sd->max_weight)
  2938. return 2;
  2939. i = MAX_INVENTORY;
  2940. if(!itemdb_isequip2(data)){
  2941. // ? 備品ではないので、?所有品なら個?のみ?化させる
  2942. for(i=0;i<MAX_INVENTORY;i++)
  2943. if(compare_item(&sd->status.inventory[i], item_data)) {
  2944. if(sd->status.inventory[i].amount+amount > MAX_AMOUNT)
  2945. return 5;
  2946. sd->status.inventory[i].amount+=amount;
  2947. clif_additem(sd,i,amount,0);
  2948. break;
  2949. }
  2950. }
  2951. if(i >= MAX_INVENTORY){
  2952. // ? 備品か未所有品だったので空き欄へ追加
  2953. i = pc_search_inventory(sd,0);
  2954. if(i >= 0) {
  2955. memcpy(&sd->status.inventory[i],item_data,sizeof(sd->status.inventory[0]));
  2956. sd->status.inventory[i].amount=amount;
  2957. sd->inventory_data[i]=data;
  2958. clif_additem(sd,i,amount,0);
  2959. }
  2960. else return 4;
  2961. }
  2962. sd->weight += w;
  2963. clif_updatestatus(sd,SP_WEIGHT);
  2964. return 0;
  2965. }
  2966. /*==========================================
  2967. * アイテムを減らす
  2968. *------------------------------------------
  2969. */
  2970. int pc_delitem(struct map_session_data *sd,int n,int amount,int type)
  2971. {
  2972. nullpo_retr(1, sd);
  2973. if(sd->status.inventory[n].nameid==0 || amount <= 0 || sd->status.inventory[n].amount<amount || sd->inventory_data[n] == NULL)
  2974. return 1;
  2975. sd->status.inventory[n].amount -= amount;
  2976. sd->weight -= sd->inventory_data[n]->weight*amount ;
  2977. if(sd->status.inventory[n].amount<=0){
  2978. if(sd->status.inventory[n].equip)
  2979. pc_unequipitem(sd,n,3);
  2980. memset(&sd->status.inventory[n],0,sizeof(sd->status.inventory[0]));
  2981. sd->inventory_data[n] = NULL;
  2982. }
  2983. if(!(type&1))
  2984. clif_delitem(sd,n,amount);
  2985. if(!(type&2))
  2986. clif_updatestatus(sd,SP_WEIGHT);
  2987. return 0;
  2988. }
  2989. /*==========================================
  2990. * アイテムを落す
  2991. *------------------------------------------
  2992. */
  2993. int pc_dropitem(struct map_session_data *sd,int n,int amount)
  2994. {
  2995. nullpo_retr(1, sd);
  2996. if(n < 0 || n >= MAX_INVENTORY)
  2997. return 1;
  2998. if(amount <= 0)
  2999. return 1;
  3000. if (sd->status.inventory[n].nameid <= 0 ||
  3001. sd->status.inventory[n].amount < amount ||
  3002. sd->trade_partner != 0 || sd->vender_id != 0 ||
  3003. sd->status.inventory[n].amount <= 0 ||
  3004. itemdb_isdropable(sd->status.inventory[n].nameid) == 0 || // Celest
  3005. pc_candrop(sd,sd->status.inventory[n].nameid))
  3006. return 1;
  3007. map_addflooritem(&sd->status.inventory[n], amount, sd->bl.m, sd->bl.x, sd->bl.y, NULL, NULL, NULL, 0);
  3008. pc_delitem(sd, n, amount, 0);
  3009. return 0;
  3010. }
  3011. /*==========================================
  3012. * アイテムを拾う
  3013. *------------------------------------------
  3014. */
  3015. int pc_takeitem(struct map_session_data *sd,struct flooritem_data *fitem)
  3016. {
  3017. int flag;
  3018. unsigned int tick = gettick();
  3019. struct map_session_data *first_sd = NULL,*second_sd = NULL,*third_sd = NULL;
  3020. nullpo_retr(0, sd);
  3021. nullpo_retr(0, fitem);
  3022. if(fitem->first_get_id > 0) {
  3023. first_sd = map_id2sd(fitem->first_get_id);
  3024. if(tick < fitem->first_get_tick) {
  3025. if(fitem->first_get_id != sd->bl.id && !(first_sd && first_sd->status.party_id == sd->status.party_id)) {
  3026. clif_additem(sd,0,0,6);
  3027. return 0;
  3028. }
  3029. }
  3030. else if(fitem->second_get_id > 0) {
  3031. second_sd = map_id2sd(fitem->second_get_id);
  3032. if(tick < fitem->second_get_tick) {
  3033. if(fitem->first_get_id != sd->bl.id && fitem->second_get_id != sd->bl.id &&
  3034. !(first_sd && first_sd->status.party_id == sd->status.party_id) && !(second_sd && second_sd->status.party_id == sd->status.party_id)) {
  3035. clif_additem(sd,0,0,6);
  3036. return 0;
  3037. }
  3038. }
  3039. else if(fitem->third_get_id > 0) {
  3040. third_sd = map_id2sd(fitem->third_get_id);
  3041. if(tick < fitem->third_get_tick) {
  3042. if(fitem->first_get_id != sd->bl.id && fitem->second_get_id != sd->bl.id && fitem->third_get_id != sd->bl.id &&
  3043. !(first_sd && first_sd->status.party_id == sd->status.party_id) && !(second_sd && second_sd->status.party_id == sd->status.party_id) &&
  3044. !(third_sd && third_sd->status.party_id == sd->status.party_id)) {
  3045. clif_additem(sd,0,0,6);
  3046. return 0;
  3047. }
  3048. }
  3049. }
  3050. }
  3051. }
  3052. if((flag = pc_additem(sd,&fitem->item_data,fitem->item_data.amount)))
  3053. // 重量overで取得失敗
  3054. clif_additem(sd,0,0,flag);
  3055. else {
  3056. /* 取得成功 */
  3057. if(sd->attacktimer != -1)
  3058. pc_stopattack(sd);
  3059. clif_takeitem(&sd->bl,&fitem->bl);
  3060. map_clearflooritem(fitem->bl.id);
  3061. }
  3062. return 0;
  3063. }
  3064. int pc_isUseitem(struct map_session_data *sd,int n)
  3065. {
  3066. struct item_data *item;
  3067. int nameid;
  3068. nullpo_retr(0, sd);
  3069. item = sd->inventory_data[n];
  3070. nameid = sd->status.inventory[n].nameid;
  3071. if(item == NULL)
  3072. return 0;
  3073. if(item->type != 0 && item->type != 2)
  3074. return 0;
  3075. if((nameid == 605) && map[sd->bl.m].flag.gvg)
  3076. return 0;
  3077. if(nameid == 601 && (map[sd->bl.m].flag.noteleport || map[sd->bl.m].flag.gvg)) {
  3078. clif_skill_teleportmessage(sd,0);
  3079. return 0;
  3080. }
  3081. if(nameid == 602 && map[sd->bl.m].flag.noreturn)
  3082. return 0;
  3083. if(nameid == 604 && (map[sd->bl.m].flag.nobranch || map[sd->bl.m].flag.gvg))
  3084. return 0;
  3085. if(item->sex != 2 && sd->status.sex != item->sex)
  3086. return 0;
  3087. if(item->elv > 0 && sd->status.base_level < item->elv)
  3088. return 0;
  3089. if(((sd->status.class_==13 || sd->status.class_==4014) && ((1<<7)&item->class_) == 0) || // have mounted classes use unmounted items [Valaris]
  3090. ((sd->status.class_==21 || sd->status.class_==4022) && ((1<<14)&item->class_) == 0))
  3091. return 0;
  3092. if(sd->status.class_!=13 && sd->status.class_!=4014 && sd->status.class_!=21 && sd->status.class_!=4022)
  3093. if((sd->status.class_<=4000 && ((1<<sd->status.class_)&item->class_) == 0) || (sd->status.class_>4000 && sd->status.class_<4023 && ((1<<(sd->status.class_-4001))&item->class_) == 0) ||
  3094. (sd->status.class_>=4023 && ((1<<(sd->status.class_-4023))&item->class_) == 0))
  3095. return 0;
  3096. #ifndef TXT_ONLY
  3097. if((log_config.branch > 0) && (nameid == 604))
  3098. log_branch(sd);
  3099. #endif
  3100. return 1;
  3101. }
  3102. /*==========================================
  3103. * アイテムを使う
  3104. *------------------------------------------
  3105. */
  3106. int pc_useitem(struct map_session_data *sd,int n)
  3107. {
  3108. int nameid,amount;
  3109. nullpo_retr(1, sd);
  3110. if(n >=0 && n < MAX_INVENTORY) {
  3111. nameid = sd->status.inventory[n].nameid;
  3112. amount = sd->status.inventory[n].amount;
  3113. if(sd->status.inventory[n].nameid <= 0 ||
  3114. sd->status.inventory[n].amount <= 0 ||
  3115. sd->sc_data[SC_BERSERK].timer!=-1 ||
  3116. sd->sc_data[SC_MARIONETTE].timer!=-1 ||
  3117. !pc_isUseitem(sd,n) ) {
  3118. clif_useitemack(sd,n,0,0);
  3119. return 1;
  3120. }
  3121. if(sd->inventory_data[n])
  3122. run_script(sd->inventory_data[n]->use_script,0,sd->bl.id,0);
  3123. pc_delitem(sd,n,1,1);
  3124. amount = sd->status.inventory[n].amount;
  3125. clif_useitemack(sd,n,amount,1);
  3126. }
  3127. return 0;
  3128. }
  3129. /*==========================================
  3130. * カ?トアイテム追加。個?のみitem構造?の?字を無視
  3131. *------------------------------------------
  3132. */
  3133. int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amount)
  3134. {
  3135. struct item_data *data;
  3136. int i,w;
  3137. nullpo_retr(1, sd);
  3138. nullpo_retr(1, item_data);
  3139. if(item_data->nameid <= 0 || amount <= 0)
  3140. return 1;
  3141. data = itemdb_search(item_data->nameid);
  3142. if((w=data->weight*amount) + sd->cart_weight > sd->cart_max_weight)
  3143. return 1;
  3144. i=MAX_CART;
  3145. if(!itemdb_isequip2(data)){
  3146. // ? 備品ではないので、?所有品なら個?のみ?化させる
  3147. for(i=0;i<MAX_CART;i++){
  3148. if(compare_item(&sd->status.cart[i], item_data)) {
  3149. if(sd->status.cart[i].amount+amount > MAX_AMOUNT)
  3150. return 1;
  3151. sd->status.cart[i].amount+=amount;
  3152. clif_cart_additem(sd,i,amount,0);
  3153. break;
  3154. }
  3155. }
  3156. }
  3157. if(i >= MAX_CART){
  3158. // ? 備品か未所有品だったので空き欄へ追加
  3159. for(i=0;i<MAX_CART;i++){
  3160. if(sd->status.cart[i].nameid==0){
  3161. memcpy(&sd->status.cart[i],item_data,sizeof(sd->status.cart[0]));
  3162. sd->status.cart[i].amount=amount;
  3163. sd->cart_num++;
  3164. clif_cart_additem(sd,i,amount,0);
  3165. break;
  3166. }
  3167. }
  3168. if(i >= MAX_CART)
  3169. return 1;
  3170. }
  3171. sd->cart_weight += w;
  3172. clif_updatestatus(sd,SP_CARTINFO);
  3173. return 0;
  3174. }
  3175. /*==========================================
  3176. * カ?トアイテムを減らす
  3177. *------------------------------------------
  3178. */
  3179. int pc_cart_delitem(struct map_session_data *sd,int n,int amount,int type)
  3180. {
  3181. nullpo_retr(1, sd);
  3182. if(sd->status.cart[n].nameid==0 ||
  3183. sd->status.cart[n].amount<amount)
  3184. return 1;
  3185. sd->status.cart[n].amount -= amount;
  3186. sd->cart_weight -= itemdb_weight(sd->status.cart[n].nameid)*amount ;
  3187. if(sd->status.cart[n].amount <= 0){
  3188. memset(&sd->status.cart[n],0,sizeof(sd->status.cart[0]));
  3189. sd->cart_num--;
  3190. }
  3191. if(!type) {
  3192. clif_cart_delitem(sd,n,amount);
  3193. clif_updatestatus(sd,SP_CARTINFO);
  3194. }
  3195. return 0;
  3196. }
  3197. /*==========================================
  3198. * カ?トへアイテム移動
  3199. *------------------------------------------
  3200. */
  3201. int pc_putitemtocart(struct map_session_data *sd,int idx,int amount) {
  3202. struct item *item_data;
  3203. nullpo_retr(0, sd);
  3204. nullpo_retr(0, item_data = &sd->status.inventory[idx]);
  3205. if(itemdb_isdropable(sd->status.inventory[idx].nameid) == 0)
  3206. return 1;
  3207. if(pc_candrop(sd,sd->status.inventory[idx].nameid)==1)
  3208. return 1;
  3209. if (item_data->nameid==0 || item_data->amount<amount || sd->vender_id)
  3210. return 1;
  3211. if (pc_cart_additem(sd,item_data,amount) == 0)
  3212. return pc_delitem(sd,idx,amount,0);
  3213. return 1;
  3214. }
  3215. /*==========================================
  3216. * カ?ト?のアイテム?確認(個?の差分を返す)
  3217. *------------------------------------------
  3218. */
  3219. int pc_cartitem_amount(struct map_session_data *sd,int idx,int amount)
  3220. {
  3221. struct item *item_data;
  3222. nullpo_retr(-1, sd);
  3223. nullpo_retr(-1, item_data=&sd->status.cart[idx]);
  3224. if( item_data->nameid==0 || !item_data->amount)
  3225. return -1;
  3226. return item_data->amount-amount;
  3227. }
  3228. /*==========================================
  3229. * カ?トからアイテム移動
  3230. *------------------------------------------
  3231. */
  3232. int pc_getitemfromcart(struct map_session_data *sd,int idx,int amount)
  3233. {
  3234. struct item *item_data;
  3235. int flag;
  3236. nullpo_retr(0, sd);
  3237. nullpo_retr(0, item_data=&sd->status.cart[idx]);
  3238. if( item_data->nameid==0 || item_data->amount<amount || sd->vender_id )
  3239. return 1;
  3240. if((flag = pc_additem(sd,item_data,amount)) == 0)
  3241. return pc_cart_delitem(sd,idx,amount,0);
  3242. clif_additem(sd,0,0,flag);
  3243. return 1;
  3244. }
  3245. /*==========================================
  3246. * アイテム鑑定
  3247. *------------------------------------------
  3248. */
  3249. int pc_item_identify(struct map_session_data *sd,int idx)
  3250. {
  3251. int flag=1;
  3252. nullpo_retr(0, sd);
  3253. // Celest
  3254. if (sd->skillid == BS_REPAIRWEAPON)
  3255. return pc_item_repair (sd, idx);
  3256. else if (sd->skillid == WS_WEAPONREFINE)
  3257. return pc_item_refine (sd, idx);
  3258. if(idx >= 0 && idx < MAX_INVENTORY) {
  3259. if(sd->status.inventory[idx].nameid > 0 && sd->status.inventory[idx].identify == 0 ){
  3260. flag=0;
  3261. sd->status.inventory[idx].identify=1;
  3262. }
  3263. clif_item_identified(sd,idx,flag);
  3264. }
  3265. else
  3266. clif_item_identified(sd,idx,flag);
  3267. return !flag;
  3268. }
  3269. /*==========================================
  3270. * Weapon Repair [Celest]
  3271. *------------------------------------------
  3272. */
  3273. int pc_item_repair(struct map_session_data *sd,int idx)
  3274. {
  3275. int flag=1, material;
  3276. int materials[5] = { 0, 1002, 998, 999, 756 };
  3277. struct item *item;
  3278. nullpo_retr(0, sd);
  3279. item = &sd->status.inventory[idx];
  3280. if(idx >= 0 && idx < MAX_INVENTORY) {
  3281. if(item->nameid > 0 && item->attribute == 1 ) {
  3282. if (itemdb_type(item->nameid)==4)
  3283. material = materials [itemdb_wlv (item->nameid)];
  3284. else
  3285. material = materials [3];
  3286. if (pc_search_inventory(sd, material) < 0 ) { //fixed by Lupus (item pos can be = 0!)
  3287. clif_skill_fail(sd,sd->skillid,0,0);
  3288. return 0;
  3289. }
  3290. flag=0;
  3291. item->attribute=0;
  3292. //Temporary Weapon Repair code [DracoRPG]
  3293. pc_delitem(sd, pc_search_inventory(sd, material), 1, 0);
  3294. clif_equiplist(sd);
  3295. clif_produceeffect(sd, 0, item->nameid);
  3296. clif_misceffect(&sd->bl, 3);
  3297. clif_displaymessage(sd->fd,"Item has been repaired.");
  3298. }
  3299. }
  3300. return !flag;
  3301. }
  3302. /*==========================================
  3303. * Weapon Refining [Celest]
  3304. *------------------------------------------
  3305. */
  3306. int pc_item_refine(struct map_session_data *sd,int idx)
  3307. {
  3308. int flag = 1, i = 0, ep = 0, per;
  3309. int material[5] = { 0, 1010, 1011, 984, 984 };
  3310. struct item *item;
  3311. nullpo_retr(0, sd);
  3312. item = &sd->status.inventory[idx];
  3313. if(idx >= 0 && idx < MAX_INVENTORY) {
  3314. if(item->nameid > 0 && itemdb_type(item->nameid)==4) {
  3315. // if it's no longer refineable
  3316. if (item->refine >= sd->skilllv || item->refine == 10) {
  3317. clif_skill_fail(sd,sd->skillid,0,0);
  3318. return 0;
  3319. }
  3320. if ((i=pc_search_inventory(sd, material [itemdb_wlv (item->nameid)])) < 0 ) { //fixed by Lupus (item pos can be = 0!)
  3321. clif_skill_fail(sd,sd->skillid,0,0);
  3322. return 0;
  3323. }
  3324. per = percentrefinery [itemdb_wlv (item->nameid)][(int)item->refine];
  3325. //per += pc_checkskill(sd,BS_WEAPONRESEARCH);
  3326. per *= (75 + sd->status.job_level/2)/100;
  3327. if (per > rand() % 100) {
  3328. flag = 0;
  3329. item->refine++;
  3330. pc_delitem(sd, i, 1, 0);
  3331. if(item->equip) {
  3332. ep = item->equip;
  3333. pc_unequipitem(sd,idx,3);
  3334. }
  3335. clif_refine(sd->fd,sd,0,idx,item->refine);
  3336. clif_delitem(sd,idx,1);
  3337. clif_additem(sd,idx,1,0);
  3338. if (ep)
  3339. pc_equipitem(sd,idx,ep);
  3340. clif_misceffect(&sd->bl,3);
  3341. }
  3342. else {
  3343. pc_delitem(sd, i, 1, 0);
  3344. item->refine = 0;
  3345. if(item->equip)
  3346. pc_unequipitem(sd,idx,3);
  3347. clif_refine(sd->fd,sd,1,idx,item->refine);
  3348. pc_delitem(sd,idx,1,0);
  3349. clif_misceffect(&sd->bl,2);
  3350. clif_emotion(&sd->bl, 23);
  3351. }
  3352. }
  3353. }
  3354. return !flag;
  3355. }
  3356. /*==========================================
  3357. * スティル品公開
  3358. *------------------------------------------
  3359. */
  3360. int pc_show_steal(struct block_list *bl,va_list ap)
  3361. {
  3362. struct map_session_data *sd;
  3363. int itemid;
  3364. int type;
  3365. struct item_data *item=NULL;
  3366. char output[100];
  3367. nullpo_retr(0, bl);
  3368. nullpo_retr(0, ap);
  3369. nullpo_retr(0, sd=va_arg(ap,struct map_session_data *));
  3370. itemid=va_arg(ap,int);
  3371. type=va_arg(ap,int);
  3372. if(!type){
  3373. if((item=itemdb_exists(itemid))==NULL)
  3374. sprintf(output,"%s stole an Unknown_Item.",sd->status.name);
  3375. else
  3376. sprintf(output,"%s stole %s.",sd->status.name,item->jname);
  3377. clif_displaymessage( ((struct map_session_data *)bl)->fd, output);
  3378. }else{
  3379. sprintf(output,"%s has not stolen the item because of being overweight.",sd->status.name);
  3380. clif_displaymessage( ((struct map_session_data *)bl)->fd, output);
  3381. }
  3382. return 0;
  3383. }
  3384. /*==========================================
  3385. *
  3386. *------------------------------------------
  3387. */
  3388. //** pc.c: Small Steal Item fix by fritz
  3389. int pc_steal_item(struct map_session_data *sd,struct block_list *bl)
  3390. {
  3391. if(sd != NULL && bl != NULL && bl->type == BL_MOB) {
  3392. int i,skill,rate,itemid,flag, count;
  3393. struct mob_data *md;
  3394. md=(struct mob_data *)bl;
  3395. if(!md->state.steal_flag && mob_db[md->class_].mexp <= 0 && !(mob_db[md->class_].mode&0x20) &&
  3396. (!(md->class_>1324 && md->class_<1364))) // prevent stealing from treasure boxes [Valaris]
  3397. {
  3398. if (md->sc_data && (md->sc_data[SC_STONE].timer != -1 || md->sc_data[SC_FREEZE].timer != -1))
  3399. return 0;
  3400. skill = battle_config.skill_steal_type == 1
  3401. ? (sd->paramc[4] - mob_db[md->class_].dex)/2 + pc_checkskill(sd,TF_STEAL)*6 + 10
  3402. : sd->paramc[4] - mob_db[md->class_].dex + pc_checkskill(sd,TF_STEAL)*3 + 10;
  3403. if(0 < skill)
  3404. {
  3405. for(count = 8; count <= 8 && count != 0; count--)
  3406. {
  3407. i = rand()%8;
  3408. itemid = mob_db[md->class_].dropitem[i].nameid;
  3409. if(itemid > 0 && itemdb_type(itemid) != 6)
  3410. {
  3411. rate = (mob_db[md->class_].dropitem[i].p / battle_config.item_rate_common * 100 * skill)/100;
  3412. if(rand()%10000 < rate)
  3413. {
  3414. struct item tmp_item;
  3415. memset(&tmp_item,0,sizeof(tmp_item));
  3416. tmp_item.nameid = itemid;
  3417. tmp_item.amount = 1;
  3418. tmp_item.identify = 1;
  3419. flag = pc_additem(sd,&tmp_item,1);
  3420. if(battle_config.show_steal_in_same_party)
  3421. {
  3422. party_foreachsamemap(pc_show_steal,sd,1,sd,tmp_item.nameid,0);
  3423. }
  3424. if(flag)
  3425. {
  3426. if(battle_config.show_steal_in_same_party)
  3427. {
  3428. party_foreachsamemap(pc_show_steal,sd,1,sd,tmp_item.nameid,1);
  3429. }
  3430. clif_additem(sd,0,0,flag);
  3431. }
  3432. md->state.steal_flag = 1;
  3433. return 1;
  3434. }
  3435. }
  3436. }
  3437. }
  3438. }
  3439. }
  3440. return 0;
  3441. }
  3442. /*==========================================
  3443. *
  3444. *------------------------------------------
  3445. */
  3446. int pc_steal_coin(struct map_session_data *sd,struct block_list *bl)
  3447. {
  3448. if(sd != NULL && bl != NULL && bl->type == BL_MOB) {
  3449. int rate,skill;
  3450. struct mob_data *md=(struct mob_data *)bl;
  3451. if(md && !md->state.steal_coin_flag) {
  3452. if (md->sc_data && (md->sc_data[SC_STONE].timer != -1 || md->sc_data[SC_FREEZE].timer != -1))
  3453. return 0;
  3454. skill = pc_checkskill(sd,RG_STEALCOIN)*10;
  3455. rate = skill + (sd->status.base_level - mob_db[md->class_].lv)*3 + sd->paramc[4]*2 + sd->paramc[5]*2;
  3456. if(rand()%1000 < rate) {
  3457. pc_getzeny(sd,mob_db[md->class_].lv*10 + rand()%100);
  3458. md->state.steal_coin_flag = 1;
  3459. return 1;
  3460. }
  3461. }
  3462. }
  3463. return 0;
  3464. }
  3465. //
  3466. //
  3467. //
  3468. /*==========================================
  3469. * PCの位置設定
  3470. *------------------------------------------
  3471. */
  3472. int pc_setpos(struct map_session_data *sd,char *mapname_org,int x,int y,int clrtype)
  3473. {
  3474. char mapname[24];
  3475. int m=0,disguise=0;
  3476. nullpo_retr(0, sd);
  3477. if(sd->chatID) // チャットから出る
  3478. chat_leavechat(sd);
  3479. if(sd->trade_partner) // 取引を中?する
  3480. trade_tradecancel(sd);
  3481. if(sd->state.storage_flag)
  3482. storage_guild_storage_quit(sd,0);
  3483. else
  3484. storage_storage_quit(sd); // 倉庫を開いてるなら保存する
  3485. if(sd->party_invite>0) // パ?ティ?誘を拒否する
  3486. party_reply_invite(sd,sd->party_invite_account,0);
  3487. if(sd->guild_invite>0) // ギルド?誘を拒否する
  3488. guild_reply_invite(sd,sd->guild_invite,0);
  3489. if(sd->guild_alliance>0) // ギルド同盟?誘を拒否する
  3490. guild_reply_reqalliance(sd,sd->guild_alliance_account,0);
  3491. skill_castcancel(&sd->bl,0); // 詠唱中?
  3492. pc_stop_walking(sd,0); // ?行中?
  3493. pc_stopattack(sd); // 攻?中?
  3494. if(pc_issit(sd)) {
  3495. pc_setstand(sd);
  3496. skill_gangsterparadise(sd,0);
  3497. }
  3498. if (sd->sc_count) {
  3499. if(sd->sc_data[SC_TRICKDEAD].timer != -1)
  3500. skill_status_change_end(&sd->bl, SC_TRICKDEAD, -1);
  3501. if(sd->sc_data[SC_BLADESTOP].timer!=-1)
  3502. skill_status_change_end(&sd->bl,SC_BLADESTOP,-1);
  3503. if(sd->sc_data[SC_DANCING].timer!=-1) // clear dance effect when warping [Valaris]
  3504. skill_stop_dancing(&sd->bl,0);
  3505. }
  3506. if(sd->status.option&2)
  3507. skill_status_change_end(&sd->bl, SC_HIDING, -1);
  3508. if(sd->status.option&4)
  3509. skill_status_change_end(&sd->bl, SC_CLOAKING, -1);
  3510. if(sd->status.option&16386)
  3511. skill_status_change_end(&sd->bl, SC_CHASEWALK, -1);
  3512. if(sd->status.pet_id > 0 && sd->pd && sd->pet.intimate > 0) {
  3513. pet_stopattack(sd->pd);
  3514. pet_changestate(sd->pd,MS_IDLE,0);
  3515. }
  3516. if(sd->disguise) { // clear disguises when warping [Valaris]
  3517. clif_clearchar(&sd->bl, 9);
  3518. disguise=sd->disguise;
  3519. sd->disguise=0;
  3520. }
  3521. strncpy(mapname,mapname_org,sizeof(mapname));
  3522. mapname[16]=0;
  3523. if(strstr(mapname,".gat")==NULL && strstr(mapname,".afm")==NULL && strlen(mapname)<16){
  3524. strcat(mapname,".gat");
  3525. }
  3526. m=map_mapname2mapid(mapname);
  3527. if(m<0){
  3528. if(sd->mapname[0]){
  3529. int ip,port;
  3530. if(map_mapname2ipport(mapname,&ip,&port)==0){
  3531. skill_stop_dancing(&sd->bl,1);
  3532. skill_unit_out_all(&sd->bl,gettick(),1);
  3533. clif_clearchar_area(&sd->bl,clrtype&0xffff);
  3534. skill_gangsterparadise(sd,0);
  3535. map_delblock(&sd->bl);
  3536. if(sd->status.pet_id > 0 && sd->pd) {
  3537. if(sd->pd->bl.m != m && sd->pet.intimate <= 0) {
  3538. pet_remove_map(sd);
  3539. intif_delete_petdata(sd->status.pet_id);
  3540. sd->status.pet_id = 0;
  3541. sd->pd = NULL;
  3542. sd->petDB = NULL;
  3543. if(battle_config.pet_status_support)
  3544. pc_calcstatus(sd,2);
  3545. }
  3546. else if(sd->pet.intimate > 0) {
  3547. pet_stopattack(sd->pd);
  3548. pet_changestate(sd->pd,MS_IDLE,0);
  3549. clif_clearchar_area(&sd->pd->bl,clrtype&0xffff);
  3550. map_delblock(&sd->pd->bl);
  3551. }
  3552. }
  3553. memcpy(sd->mapname,mapname,24);
  3554. sd->bl.x=x;
  3555. sd->bl.y=y;
  3556. sd->state.waitingdisconnect=1;
  3557. pc_makesavestatus(sd);
  3558. if(sd->status.pet_id > 0 && sd->pd)
  3559. intif_save_petdata(sd->status.account_id,&sd->pet);
  3560. chrif_save(sd);
  3561. storage_storage_save(sd);
  3562. storage_delete(sd->status.account_id);
  3563. chrif_changemapserver(sd, mapname, x, y, ip, port);
  3564. return 0;
  3565. }
  3566. }
  3567. #if 0
  3568. clif_authfail_fd(sd->fd,0); // cancel
  3569. clif_setwaitclose(sd->fd);
  3570. #endif
  3571. return 1;
  3572. }
  3573. if(x <0 || x >= map[m].xs || y <0 || y >= map[m].ys)
  3574. x=y=0;
  3575. if((x==0 && y==0) || map_getcell(m,x,y,CELL_CHKNOPASS)){
  3576. if(x||y) {
  3577. if(battle_config.error_log)
  3578. printf("stacked (%d,%d)\n",x,y);
  3579. }
  3580. do {
  3581. x=rand()%(map[m].xs-2)+1;
  3582. y=rand()%(map[m].ys-2)+1;
  3583. } while(map_getcell(m,x,y,CELL_CHKNOPASS));
  3584. }
  3585. if(sd->mapname[0] && sd->bl.prev != NULL){
  3586. skill_unit_out_all(&sd->bl,gettick(),1);
  3587. clif_clearchar_area(&sd->bl,clrtype&0xffff);
  3588. skill_gangsterparadise(sd,0);
  3589. map_delblock(&sd->bl);
  3590. // pet
  3591. if(sd->status.pet_id > 0 && sd->pd) {
  3592. if(sd->pd->bl.m != m && sd->pet.intimate <= 0) {
  3593. pet_remove_map(sd);
  3594. intif_delete_petdata(sd->status.pet_id);
  3595. sd->status.pet_id = 0;
  3596. sd->pd = NULL;
  3597. sd->petDB = NULL;
  3598. if(battle_config.pet_status_support)
  3599. pc_calcstatus(sd,2);
  3600. pc_makesavestatus(sd);
  3601. chrif_save(sd);
  3602. storage_storage_save(sd);
  3603. }
  3604. else if(sd->pet.intimate > 0) {
  3605. pet_stopattack(sd->pd);
  3606. pet_changestate(sd->pd,MS_IDLE,0);
  3607. clif_clearchar_area(&sd->pd->bl,clrtype&0xffff);
  3608. map_delblock(&sd->pd->bl);
  3609. }
  3610. }
  3611. clif_changemap(sd,map[m].name,x,y); // [MouseJstr]
  3612. }
  3613. if(disguise) // disguise teleport fix [Valaris]
  3614. sd->disguise=disguise;
  3615. memcpy(sd->mapname,mapname,24);
  3616. sd->bl.m = m;
  3617. sd->to_x = x;
  3618. sd->to_y = y;
  3619. // moved and changed dance effect stopping
  3620. sd->bl.x = x;
  3621. sd->bl.y = y;
  3622. if(sd->status.pet_id > 0 && sd->pd && sd->pet.intimate > 0) {
  3623. sd->pd->bl.m = m;
  3624. sd->pd->bl.x = sd->pd->to_x = x;
  3625. sd->pd->bl.y = sd->pd->to_y = y;
  3626. sd->pd->dir = sd->dir;
  3627. }
  3628. // map_addblock(&sd->bl); /// ブロック登?とspawnは
  3629. // clif_spawnpc(sd);
  3630. return 0;
  3631. }
  3632. /*==========================================
  3633. * PCのランダムワ?プ
  3634. *------------------------------------------
  3635. */
  3636. int pc_randomwarp(struct map_session_data *sd, int type) {
  3637. int x,y,i=0;
  3638. int m;
  3639. nullpo_retr(0, sd);
  3640. m=sd->bl.m;
  3641. if (map[sd->bl.m].flag.noteleport) // テレポ?ト禁止
  3642. return 0;
  3643. do{
  3644. x=rand()%(map[m].xs-2)+1;
  3645. y=rand()%(map[m].ys-2)+1;
  3646. }while(map_getcell(m,x,y,CELL_CHKNOPASS) && (i++)<1000 );
  3647. if (i < 1000)
  3648. pc_setpos(sd,map[m].name,x,y,type);
  3649. return 0;
  3650. }
  3651. /*==========================================
  3652. * 現在位置のメモ
  3653. *------------------------------------------
  3654. */
  3655. int pc_memo(struct map_session_data *sd, int i) {
  3656. int skill;
  3657. int j;
  3658. nullpo_retr(0, sd);
  3659. skill = pc_checkskill(sd, AL_WARP);
  3660. if (i >= MIN_PORTAL_MEMO)
  3661. i -= MIN_PORTAL_MEMO;
  3662. else if (map[sd->bl.m].flag.nomemo || (map[sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd))) {
  3663. clif_skill_teleportmessage(sd, 1);
  3664. return 0;
  3665. }
  3666. if (skill < 1) {
  3667. clif_skill_memo(sd,2);
  3668. }
  3669. if (skill < 2 || i < -1 || i > 2) {
  3670. clif_skill_memo(sd, 1);
  3671. return 0;
  3672. }
  3673. for(j = 0 ; j < 3; j++) {
  3674. if (strcmp(sd->status.memo_point[j].map, map[sd->bl.m].name) == 0) {
  3675. i = j;
  3676. break;
  3677. }
  3678. }
  3679. if (i == -1) {
  3680. for(i = skill - 3; i >= 0; i--) {
  3681. memcpy(&sd->status.memo_point[i+1],&sd->status.memo_point[i],
  3682. sizeof(struct point));
  3683. }
  3684. i = 0;
  3685. }
  3686. memcpy(sd->status.memo_point[i].map, map[sd->bl.m].name, 24);
  3687. sd->status.memo_point[i].x = sd->bl.x;
  3688. sd->status.memo_point[i].y = sd->bl.y;
  3689. clif_skill_memo(sd, 0);
  3690. return 1;
  3691. }
  3692. /*==========================================
  3693. *
  3694. *------------------------------------------
  3695. */
  3696. int pc_can_reach(struct map_session_data *sd,int x,int y)
  3697. {
  3698. struct walkpath_data wpd;
  3699. nullpo_retr(0, sd);
  3700. if( sd->bl.x==x && sd->bl.y==y ) // 同じマス
  3701. return 1;
  3702. // 障害物判定
  3703. wpd.path_len=0;
  3704. wpd.path_pos=0;
  3705. wpd.path_half=0;
  3706. return (path_search(&wpd,sd->bl.m,sd->bl.x,sd->bl.y,x,y,0)!=-1)?1:0;
  3707. }
  3708. //
  3709. // ? 行物
  3710. //
  3711. /*==========================================
  3712. * 次の1?にかかる史ヤを計算
  3713. *------------------------------------------
  3714. */
  3715. static int calc_next_walk_step(struct map_session_data *sd)
  3716. {
  3717. nullpo_retr(0, sd);
  3718. if(sd->walkpath.path_pos>=sd->walkpath.path_len)
  3719. return -1;
  3720. if(sd->walkpath.path[sd->walkpath.path_pos]&1)
  3721. return sd->speed*14/10;
  3722. return sd->speed;
  3723. }
  3724. /*==========================================
  3725. * 半?進む(timer??)
  3726. *------------------------------------------
  3727. */
  3728. static int pc_walk(int tid,unsigned int tick,int id,int data)
  3729. {
  3730. struct map_session_data *sd;
  3731. int i;
  3732. int moveblock;
  3733. int x,y,dx,dy;
  3734. nullpo_retr(0, (sd=map_id2sd(id)));
  3735. if(sd->walktimer != tid){
  3736. if(battle_config.error_log)
  3737. printf("pc_walk %d != %d\n",sd->walktimer,tid);
  3738. return 0;
  3739. }
  3740. sd->walktimer=-1;
  3741. if(sd->walkpath.path_pos>=sd->walkpath.path_len || sd->walkpath.path_pos!=data)
  3742. return 0;
  3743. //?いたので息吹のタイマ?を初期化
  3744. sd->inchealspirithptick = 0;
  3745. sd->inchealspiritsptick = 0;
  3746. sd->walkpath.path_half ^= 1;
  3747. if(sd->walkpath.path_half==0){ // マス目中心へ途�
  3748. sd->walkpath.path_pos++;
  3749. if(sd->state.change_walk_target){
  3750. pc_walktoxy_sub(sd);
  3751. return 0;
  3752. }
  3753. } else { // マス目境界へ途�
  3754. if(sd->walkpath.path[sd->walkpath.path_pos]>=8)
  3755. return 1;
  3756. x = sd->bl.x;
  3757. y = sd->bl.y;
  3758. if(map_getcell(sd->bl.m,x,y,CELL_CHKNOPASS)) {
  3759. pc_stop_walking(sd,1);
  3760. return 0;
  3761. }
  3762. sd->dir=sd->head_dir=sd->walkpath.path[sd->walkpath.path_pos];
  3763. dx = dirx[(int)sd->dir];
  3764. dy = diry[(int)sd->dir];
  3765. if(map_getcell(sd->bl.m,x,y,CELL_CHKNOPASS)) {
  3766. pc_walktoxy_sub(sd);
  3767. return 0;
  3768. }
  3769. if (skill_check_moonlit (&sd->bl,x+dx,y+dy)) {
  3770. pc_stop_walking(sd,1);
  3771. return 0;
  3772. }
  3773. moveblock = ( x/BLOCK_SIZE != (x+dx)/BLOCK_SIZE || y/BLOCK_SIZE != (y+dy)/BLOCK_SIZE);
  3774. sd->walktimer = 1;
  3775. map_foreachinmovearea(clif_pcoutsight,sd->bl.m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,dx,dy,0,sd);
  3776. x += dx;
  3777. y += dy;
  3778. if(moveblock) map_delblock(&sd->bl);
  3779. sd->bl.x = x;
  3780. sd->bl.y = y;
  3781. if(moveblock) map_addblock(&sd->bl);
  3782. #if 0
  3783. if (sd->status.guild_id > 0) {
  3784. struct skill_unit *su;
  3785. if (sd->sc_data[SC_LEADERSHIP].val4 && (su=(struct skill_unit *)sd->sc_data[SC_LEADERSHIP].val4)) {
  3786. skill_unit_move_unit_group(su->group,sd->bl.m,dx,dy);
  3787. }
  3788. if (sd->sc_data[SC_GLORYWOUNDS].val4 && (su=(struct skill_unit *)sd->sc_data[SC_GLORYWOUNDS].val4)) {
  3789. skill_unit_move_unit_group(su->group,sd->bl.m,dx,dy);
  3790. }
  3791. if (sd->sc_data[SC_SOULCOLD].val4 && (su=(struct skill_unit *)sd->sc_data[SC_SOULCOLD].val4)) {
  3792. skill_unit_move_unit_group(su->group,sd->bl.m,dx,dy);
  3793. }
  3794. if (sd->sc_data[SC_HAWKEYES].val4 && (su=(struct skill_unit *)sd->sc_data[SC_HAWKEYES].val4)) {
  3795. skill_unit_move_unit_group(su->group,sd->bl.m,dx,dy);
  3796. }
  3797. }
  3798. #endif
  3799. map_foreachinmovearea(clif_pcinsight,sd->bl.m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,-dx,-dy,0,sd);
  3800. sd->walktimer = -1;
  3801. if(sd->status.party_id>0){ // パ?ティのHP情報通知?査
  3802. struct party *p=party_search(sd->status.party_id);
  3803. if(p!=NULL){
  3804. int p_flag=0;
  3805. map_foreachinmovearea(party_send_hp_check,sd->bl.m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,-dx,-dy,BL_PC,sd->status.party_id,&p_flag);
  3806. if(p_flag)
  3807. sd->party_hp=-1;
  3808. }
  3809. }
  3810. if(sd->status.option&4) // クロ?キングの消滅?査
  3811. skill_check_cloaking(&sd->bl);
  3812. /* ディボ?ション?査 */
  3813. for(i=0;i<5;i++)
  3814. if(sd->dev.val1[i]){
  3815. skill_devotion3(&sd->bl,sd->dev.val1[i]);
  3816. break;
  3817. }
  3818. /* 被ディボ?ション?査 */
  3819. if(sd->sc_count) {
  3820. if (sd->sc_data[SC_DANCING].timer!=-1)
  3821. skill_unit_move_unit_group((struct skill_unit_group *)sd->sc_data[SC_DANCING].val2,sd->bl.m,dx,dy);
  3822. if (sd->sc_data[SC_DEVOTION].val1)
  3823. skill_devotion2(&sd->bl,sd->sc_data[SC_DEVOTION].val1);
  3824. if (sd->sc_data[SC_BASILICA].timer != -1) { // Basilica cancels if caster moves [celest]
  3825. struct skill_unit *su;
  3826. if ((su = (struct skill_unit *)sd->sc_data[SC_BASILICA].val4)) {
  3827. struct skill_unit_group *sg;
  3828. if ((sg = su->group) && sg->src_id == sd->bl.id) {
  3829. skill_status_change_end(&sd->bl,SC_BASILICA,-1);
  3830. skill_delunitgroup (sg);
  3831. }
  3832. }
  3833. }
  3834. }
  3835. skill_unit_move(&sd->bl,tick,1); // スキルユニットの?査
  3836. if(map_getcell(sd->bl.m,x,y,CELL_CHKTOUCH))
  3837. npc_touch_areanpc(sd,sd->bl.m,x,y);
  3838. else
  3839. sd->areanpc_id=0;
  3840. }
  3841. if((i=calc_next_walk_step(sd))>0) {
  3842. i = i>>1;
  3843. if(i < 1 && sd->walkpath.path_half == 0)
  3844. i = 1;
  3845. sd->walktimer=add_timer(tick+i,pc_walk,id,sd->walkpath.path_pos);
  3846. }
  3847. if(battle_config.disp_hpmeter)
  3848. clif_hpmeter(sd);
  3849. return 0;
  3850. }
  3851. /*==========================================
  3852. * 移動可能か確認して、可能なら?行開始
  3853. *------------------------------------------
  3854. */
  3855. static int pc_walktoxy_sub(struct map_session_data *sd)
  3856. {
  3857. struct walkpath_data wpd;
  3858. int i;
  3859. nullpo_retr(1, sd);
  3860. if(path_search(&wpd,sd->bl.m,sd->bl.x,sd->bl.y,sd->to_x,sd->to_y,0))
  3861. return 1;
  3862. memcpy(&sd->walkpath,&wpd,sizeof(wpd));
  3863. clif_walkok(sd);
  3864. sd->state.change_walk_target=0;
  3865. if((i=calc_next_walk_step(sd))>0){
  3866. i = i>>2;
  3867. sd->walktimer=add_timer(gettick()+i,pc_walk,sd->bl.id,0);
  3868. }
  3869. clif_movechar(sd);
  3870. return 0;
  3871. }
  3872. /*==========================================
  3873. * pc? 行要求
  3874. *------------------------------------------
  3875. */
  3876. int pc_walktoxy(struct map_session_data *sd,int x,int y)
  3877. {
  3878. nullpo_retr(0, sd);
  3879. sd->to_x=x;
  3880. sd->to_y=y;
  3881. sd->idletime = tick_;
  3882. if(sd->walktimer != -1 && sd->state.change_walk_target==0){
  3883. // 現在?いている最中の目的地?更なのでマス目の中心に?た暫ノ
  3884. // timer??からpc_walktoxy_subを呼ぶようにする
  3885. sd->state.change_walk_target=1;
  3886. } else {
  3887. pc_walktoxy_sub(sd);
  3888. }
  3889. if (sd->sc_data && sd->status.guild_id > 0) {
  3890. struct skill_unit *su;
  3891. struct skill_unit_group *sg;
  3892. if (sd->state.leadership_flag && (su=(struct skill_unit *)sd->state.leadership_flag) &&
  3893. (sg=su->group) && sg->src_id == sd->bl.id) {
  3894. skill_unit_move_unit_group(sg,sd->bl.m,(x - sd->bl.x),(y - sd->bl.y));
  3895. }
  3896. if (sd->state.glorywounds_flag && (su=(struct skill_unit *)sd->state.glorywounds_flag) &&
  3897. (sg=su->group) && sg->src_id == sd->bl.id) {
  3898. skill_unit_move_unit_group(sg,sd->bl.m,(x - sd->bl.x),(y - sd->bl.y));
  3899. }
  3900. if (sd->state.soulcold_flag && (su=(struct skill_unit *)sd->state.soulcold_flag) &&
  3901. (sg=su->group) && sg->src_id == sd->bl.id) {
  3902. skill_unit_move_unit_group(sg,sd->bl.m,(x - sd->bl.x),(y - sd->bl.y));
  3903. }
  3904. if (sd->state.hawkeyes_flag && (su=(struct skill_unit *)sd->state.hawkeyes_flag) &&
  3905. (sg=su->group) && sg->src_id == sd->bl.id) {
  3906. skill_unit_move_unit_group(sg,sd->bl.m,(x - sd->bl.x),(y - sd->bl.y));
  3907. }
  3908. }
  3909. return 0;
  3910. }
  3911. /*==========================================
  3912. * ? 行停止
  3913. *------------------------------------------
  3914. */
  3915. int pc_stop_walking(struct map_session_data *sd,int type)
  3916. {
  3917. nullpo_retr(0, sd);
  3918. if(sd->walktimer != -1) {
  3919. delete_timer(sd->walktimer,pc_walk);
  3920. sd->walktimer=-1;
  3921. }
  3922. sd->walkpath.path_len=0;
  3923. sd->to_x = sd->bl.x;
  3924. sd->to_y = sd->bl.y;
  3925. if(type&0x01)
  3926. clif_fixpos(&sd->bl);
  3927. if(type&0x02 && battle_config.pc_damage_delay) {
  3928. unsigned int tick = gettick();
  3929. int delay = battle_get_dmotion(&sd->bl);
  3930. if(sd->canmove_tick < tick)
  3931. sd->canmove_tick = tick + delay;
  3932. }
  3933. return 0;
  3934. }
  3935. /*==========================================
  3936. * Random walk
  3937. *------------------------------------------
  3938. */
  3939. int pc_randomwalk(struct map_session_data *sd,int tick)
  3940. {
  3941. const int retrycount = 20;
  3942. nullpo_retr(0, sd);
  3943. if(DIFF_TICK(sd->next_walktime,tick)<0){
  3944. int i,x,y,d;
  3945. d = rand()%7+5;
  3946. for(i=0;i<retrycount;i++){ // Search of a movable place
  3947. int r=rand();
  3948. x=sd->bl.x+r%(d*2+1)-d;
  3949. y=sd->bl.y+r/(d*2+1)%(d*2+1)-d;
  3950. if((map_getcell(sd->bl.m,x,y,CELL_CHKPASS)) && pc_walktoxy(sd,x,y)==0)
  3951. break;
  3952. }
  3953. // Working on this part later [celest]
  3954. /*for(i=c=0;i<sd->walkpath.path_len;i++){ // The next walk start time is calculated.
  3955. if(sd->walkpath.path[i]&1)
  3956. c+=sd->speed*14/10;
  3957. else
  3958. c+=sd->speed;
  3959. }
  3960. sd->next_walktime = (d=tick+rand()%3000+c);
  3961. return d;*/
  3962. return 1;
  3963. }
  3964. return 0;
  3965. }
  3966. /*==========================================
  3967. *
  3968. *------------------------------------------
  3969. */
  3970. int pc_movepos(struct map_session_data *sd,int dst_x,int dst_y)
  3971. {
  3972. int moveblock;
  3973. int dx,dy,dist;
  3974. struct walkpath_data wpd;
  3975. nullpo_retr(0, sd);
  3976. if(path_search(&wpd,sd->bl.m,sd->bl.x,sd->bl.y,dst_x,dst_y,0))
  3977. return 1;
  3978. sd->dir = sd->head_dir = map_calc_dir(&sd->bl, dst_x,dst_y);
  3979. dx = dst_x - sd->bl.x;
  3980. dy = dst_y - sd->bl.y;
  3981. dist = distance(sd->bl.x,sd->bl.y,dst_x,dst_y);
  3982. moveblock = ( sd->bl.x/BLOCK_SIZE != dst_x/BLOCK_SIZE || sd->bl.y/BLOCK_SIZE != dst_y/BLOCK_SIZE);
  3983. map_foreachinmovearea(clif_pcoutsight,sd->bl.m,sd->bl.x-AREA_SIZE,sd->bl.y-AREA_SIZE,sd->bl.x+AREA_SIZE,sd->bl.y+AREA_SIZE,dx,dy,0,sd);
  3984. if(moveblock) map_delblock(&sd->bl);
  3985. sd->bl.x = dst_x;
  3986. sd->bl.y = dst_y;
  3987. if(moveblock) map_addblock(&sd->bl);
  3988. map_foreachinmovearea(clif_pcinsight,sd->bl.m,sd->bl.x-AREA_SIZE,sd->bl.y-AREA_SIZE,sd->bl.x+AREA_SIZE,sd->bl.y+AREA_SIZE,-dx,-dy,0,sd);
  3989. if(sd->status.party_id>0){ // パ?ティのHP情報通知?査
  3990. struct party *p=party_search(sd->status.party_id);
  3991. if(p!=NULL){
  3992. int flag=0;
  3993. map_foreachinmovearea(party_send_hp_check,sd->bl.m,sd->bl.x-AREA_SIZE,sd->bl.y-AREA_SIZE,sd->bl.x+AREA_SIZE,sd->bl.y+AREA_SIZE,-dx,-dy,BL_PC,sd->status.party_id,&flag);
  3994. if(flag)
  3995. sd->party_hp=-1;
  3996. }
  3997. }
  3998. if(sd->status.option&4) // クロ?キングの消滅?査
  3999. skill_check_cloaking(&sd->bl);
  4000. skill_unit_move(&sd->bl,gettick(),dist+7); // スキルユニットの?査
  4001. if(map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKTOUCH))
  4002. npc_touch_areanpc(sd,sd->bl.m,sd->bl.x,sd->bl.y);
  4003. else
  4004. sd->areanpc_id=0;
  4005. return 0;
  4006. }
  4007. //
  4008. // 武器??
  4009. //
  4010. /*==========================================
  4011. * スキルの?索 所有していた場合Lvが返る
  4012. *------------------------------------------
  4013. */
  4014. int pc_checkskill(struct map_session_data *sd,int skill_id)
  4015. {
  4016. if(sd == NULL) return 0;
  4017. if( skill_id>=10000 ){
  4018. struct guild *g;
  4019. if( sd->status.guild_id>0 && (g=guild_search(sd->status.guild_id))!=NULL)
  4020. return guild_checkskill(g,skill_id);
  4021. return 0;
  4022. }
  4023. if(sd->status.skill[skill_id].id == skill_id)
  4024. return (sd->status.skill[skill_id].lv);
  4025. return 0;
  4026. }
  4027. /*==========================================
  4028. * 武器?更によるスキルの??チェック
  4029. * 引?:
  4030. * struct map_session_data *sd セッションデ?タ
  4031. * int nameid ?備品ID
  4032. * 返り値:
  4033. * 0 ?更なし
  4034. * -1 スキルを解除
  4035. *------------------------------------------
  4036. */
  4037. int pc_checkallowskill(struct map_session_data *sd)
  4038. {
  4039. nullpo_retr(0, sd);
  4040. nullpo_retr(0, sd->sc_data);
  4041. if(!(skill_get_weapontype(KN_TWOHANDQUICKEN)&(1<<sd->status.weapon)) && sd->sc_data[SC_TWOHANDQUICKEN].timer!=-1) { // 2HQ
  4042. skill_status_change_end(&sd->bl,SC_TWOHANDQUICKEN,-1); // 2HQを解除
  4043. return -1;
  4044. }
  4045. if(!(skill_get_weapontype(LK_AURABLADE)&(1<<sd->status.weapon)) && sd->sc_data[SC_AURABLADE].timer!=-1) { /* オ?ラブレ?ド */
  4046. skill_status_change_end(&sd->bl,SC_AURABLADE,-1); /* オ?ラブレ?ドを解除 */
  4047. return -1;
  4048. }
  4049. if(!(skill_get_weapontype(LK_PARRYING)&(1<<sd->status.weapon)) && sd->sc_data[SC_PARRYING].timer!=-1) { /* パリイング */
  4050. skill_status_change_end(&sd->bl,SC_PARRYING,-1); /* パリイングを解除 */
  4051. return -1;
  4052. }
  4053. if(!(skill_get_weapontype(LK_CONCENTRATION)&(1<<sd->status.weapon)) && sd->sc_data[SC_CONCENTRATION].timer!=-1) { /* コンセントレ?ション */
  4054. skill_status_change_end(&sd->bl,SC_CONCENTRATION,-1); /* コンセントレ?ションを解除 */
  4055. return -1;
  4056. }
  4057. if(!(skill_get_weapontype(CR_SPEARQUICKEN)&(1<<sd->status.weapon)) && sd->sc_data[SC_SPEARSQUICKEN].timer!=-1){ // スピアクィッケン
  4058. skill_status_change_end(&sd->bl,SC_SPEARSQUICKEN,-1); // スピアクイッケンを解除
  4059. return -1;
  4060. }
  4061. if(!(skill_get_weapontype(BS_ADRENALINE)&(1<<sd->status.weapon)) && sd->sc_data[SC_ADRENALINE].timer!=-1){ // アドレナリンラッシュ
  4062. skill_status_change_end(&sd->bl,SC_ADRENALINE,-1); // アドレナリンラッシュを解除
  4063. return -1;
  4064. }
  4065. if(sd->status.shield <= 0) {
  4066. if(sd->sc_data[SC_AUTOGUARD].timer!=-1){ // オ?トガ?ド
  4067. skill_status_change_end(&sd->bl,SC_AUTOGUARD,-1);
  4068. return -1;
  4069. }
  4070. if(sd->sc_data[SC_DEFENDER].timer!=-1){ // ディフェンダ?
  4071. skill_status_change_end(&sd->bl,SC_DEFENDER,-1);
  4072. return -1;
  4073. }
  4074. if(sd->sc_data[SC_REFLECTSHIELD].timer!=-1){ //リフレクトシ?ルド
  4075. skill_status_change_end(&sd->bl,SC_REFLECTSHIELD,-1);
  4076. return -1;
  4077. }
  4078. }
  4079. return 0;
  4080. }
  4081. /*==========================================
  4082. * ? 備品のチェック
  4083. *------------------------------------------
  4084. */
  4085. int pc_checkequip(struct map_session_data *sd,int pos)
  4086. {
  4087. int i;
  4088. nullpo_retr(-1, sd);
  4089. for(i=0;i<11;i++){
  4090. if(pos & equip_pos[i])
  4091. return sd->equip_index[i];
  4092. }
  4093. return -1;
  4094. }
  4095. /*==========================================
  4096. * ?生職や養子職の元の職業を返す
  4097. *------------------------------------------
  4098. */
  4099. struct pc_base_job pc_calc_base_job(int b_class)
  4100. {
  4101. struct pc_base_job bj;
  4102. //?生や養子の場合の元の職業を算出する
  4103. //if(b_class < MAX_PC_CLASS){ //通常
  4104. if(b_class < 4001){
  4105. bj.job = b_class;
  4106. bj.upper = 0;
  4107. }else if(b_class >= 4001 && b_class < 4023){ //?生職
  4108. // Athena almost never uses this... well, used this. :3
  4109. bj.job = b_class - 4001;
  4110. bj.upper = 1;
  4111. //}else if(b_class == 23 + 4023 -1){ //養子スパノビ
  4112. }else if(b_class == 4045){ // super baby
  4113. //bj.job = b_class - (4023 - 1);
  4114. bj.job = 23;
  4115. bj.upper = 2;
  4116. }else{ //養子スパノビ以外の養子
  4117. bj.job = b_class - 4023;
  4118. bj.upper = 2;
  4119. }
  4120. if(battle_config.enable_upper_class==0){ //confで無?になっていたらupper=0
  4121. bj.upper = 0;
  4122. }
  4123. if(bj.job == 0){
  4124. bj.type = 0;
  4125. }else if(bj.job < 7){
  4126. bj.type = 1;
  4127. }else{
  4128. bj.type = 2;
  4129. }
  4130. return bj;
  4131. }
  4132. /*==========================================
  4133. * For quick calculating [Celest]
  4134. *------------------------------------------
  4135. */
  4136. int pc_calc_base_job2 (int b_class)
  4137. {
  4138. if(b_class < 4001)
  4139. return b_class;
  4140. else if(b_class >= 4001 && b_class < 4023)
  4141. return b_class - 4001;
  4142. else if(b_class == 4045)
  4143. return 23;
  4144. return b_class - 4023;
  4145. }
  4146. int pc_calc_upper(int b_class)
  4147. {
  4148. if(b_class < 4001)
  4149. return 0;
  4150. else if(b_class >= 4001 && b_class < 4023)
  4151. return 1;
  4152. return 2;
  4153. }
  4154. /*==========================================
  4155. * PCの攻? (timer??)
  4156. *------------------------------------------
  4157. */
  4158. int pc_attack_timer(int tid,unsigned int tick,int id,int data)
  4159. {
  4160. struct map_session_data *sd;
  4161. struct block_list *bl;
  4162. struct status_change *sc_data;
  4163. short *opt;
  4164. int dist,skill,range;
  4165. sd=map_id2sd(id);
  4166. if(sd == NULL)
  4167. return 0;
  4168. sd->idletime = tick_;
  4169. if(sd->attacktimer != tid){
  4170. if(battle_config.error_log)
  4171. printf("pc_attack_timer %d != %d\n",sd->attacktimer,tid);
  4172. return 0;
  4173. }
  4174. sd->attacktimer=-1;
  4175. if(sd->bl.prev == NULL)
  4176. return 0;
  4177. bl=map_id2bl(sd->attacktarget);
  4178. if(bl==NULL || bl->prev == NULL)
  4179. return 0;
  4180. if(bl->type == BL_PC && pc_isdead((struct map_session_data *)bl))
  4181. return 0;
  4182. // 同じmapでないなら攻?しない
  4183. // PCが死んでても攻?しない
  4184. if(sd->bl.m != bl->m || pc_isdead(sd))
  4185. return 0;
  4186. //if( sd->opt1>0 || sd->status.option&2 || sd->status.option&16388) // 異常などで攻?できない
  4187. if( sd->opt1>0 || sd->status.option&2 || sd->status.option&16384) // 異常などで攻?できない
  4188. return 0;
  4189. if (sd->sc_count) {
  4190. if(sd->sc_data[SC_AUTOCOUNTER].timer != -1)
  4191. return 0;
  4192. if(sd->sc_data[SC_BLADESTOP].timer != -1)
  4193. return 0;
  4194. }
  4195. //if((opt = battle_get_option(bl)) != NULL && *opt&0x46)
  4196. if((opt = battle_get_option(bl)) != NULL && *opt&0x42)
  4197. return 0;
  4198. if(((sc_data = battle_get_sc_data(bl)) != NULL && sc_data[SC_TRICKDEAD].timer != -1) ||
  4199. ((sc_data = battle_get_sc_data(bl)) != NULL && sc_data[SC_BASILICA].timer != -1 ))
  4200. return 0;
  4201. if(sd->skilltimer != -1 && pc_checkskill(sd,SA_FREECAST) <= 0)
  4202. return 0;
  4203. if(!battle_config.sdelay_attack_enable && pc_checkskill(sd,SA_FREECAST) <= 0) {
  4204. if(DIFF_TICK(tick , sd->canact_tick) < 0) {
  4205. clif_skill_fail(sd,1,4,0);
  4206. return 0;
  4207. }
  4208. }
  4209. dist = distance(sd->bl.x,sd->bl.y,bl->x,bl->y);
  4210. range = sd->attackrange;
  4211. if(sd->status.weapon != 11) range++;
  4212. if( dist > range ){ // ? かないので移動
  4213. if(pc_can_reach(sd,bl->x,bl->y))
  4214. clif_movetoattack(sd,bl);
  4215. return 0;
  4216. }
  4217. if(dist <= range && !battle_check_range(&sd->bl,bl,range) ) {
  4218. if(pc_can_reach(sd,bl->x,bl->y) && sd->canmove_tick < tick && (sd->sc_data[SC_ANKLE].timer == -1 || sd->sc_data[SC_SPIDERWEB].timer == -1))
  4219. pc_walktoxy(sd,bl->x,bl->y);
  4220. sd->attackabletime = tick + (sd->aspd<<1);
  4221. }
  4222. else {
  4223. if(battle_config.pc_attack_direction_change)
  4224. sd->dir=sd->head_dir=map_calc_dir(&sd->bl, bl->x,bl->y ); // 向き設定
  4225. if(sd->walktimer != -1)
  4226. pc_stop_walking(sd,1);
  4227. if(sd->sc_data[SC_COMBO].timer == -1) {
  4228. map_freeblock_lock();
  4229. pc_stop_walking(sd,0);
  4230. sd->attacktarget_lv = battle_weapon_attack(&sd->bl,bl,tick,0);
  4231. // &2 = ? - Celest
  4232. if(!(battle_config.pc_cloak_check_type&2) && sd->sc_data[SC_CLOAKING].timer != -1)
  4233. skill_status_change_end(&sd->bl,SC_CLOAKING,-1);
  4234. if(sd->status.pet_id > 0 && sd->pd && sd->petDB && battle_config.pet_attack_support)
  4235. pet_target_check(sd,bl,0);
  4236. map_freeblock_unlock();
  4237. if(sd->skilltimer != -1 && (skill = pc_checkskill(sd,SA_FREECAST)) > 0 ) // フリ?キャスト
  4238. sd->attackabletime = tick + ((sd->aspd<<1)*(150 - skill*5)/100);
  4239. else
  4240. sd->attackabletime = tick + (sd->aspd<<1);
  4241. }
  4242. else if(sd->attackabletime <= tick) {
  4243. if(sd->skilltimer != -1 && (skill = pc_checkskill(sd,SA_FREECAST)) > 0 ) // フリ?キャスト
  4244. sd->attackabletime = tick + ((sd->aspd<<1)*(150 - skill*5)/100);
  4245. else
  4246. sd->attackabletime = tick + (sd->aspd<<1);
  4247. }
  4248. if(sd->attackabletime <= tick) sd->attackabletime = tick + (battle_config.max_aspd<<1);
  4249. }
  4250. if(sd->state.attack_continue) {
  4251. sd->attacktimer=add_timer(sd->attackabletime,pc_attack_timer,sd->bl.id,0);
  4252. }
  4253. return 0;
  4254. }
  4255. /*==========================================
  4256. * 攻?要求
  4257. * typeが1なら??攻?
  4258. *------------------------------------------
  4259. */
  4260. int pc_attack(struct map_session_data *sd,int target_id,int type)
  4261. {
  4262. struct block_list *bl;
  4263. int d;
  4264. nullpo_retr(0, sd);
  4265. bl=map_id2bl(target_id);
  4266. if(bl==NULL)
  4267. return 1;
  4268. sd->idletime = tick_;
  4269. if(bl->type==BL_NPC) { // monster npcs [Valaris]
  4270. //npc_click(sd,RFIFOL(sd->fd,2));
  4271. npc_click(sd,target_id); // submitted by leinsirk10 [Celest]
  4272. return 0;
  4273. }
  4274. if(!battle_check_target(&sd->bl,bl,BCT_ENEMY))
  4275. return 1;
  4276. if(sd->attacktimer != -1)
  4277. pc_stopattack(sd);
  4278. sd->attacktarget=target_id;
  4279. sd->state.attack_continue=type;
  4280. d=DIFF_TICK(sd->attackabletime,gettick());
  4281. if(d>0 && d<2000){ // 攻?delay中
  4282. sd->attacktimer=add_timer(sd->attackabletime,pc_attack_timer,sd->bl.id,0);
  4283. } else {
  4284. // 本?timer??なので引?を合わせる
  4285. pc_attack_timer(-1,gettick(),sd->bl.id,0);
  4286. }
  4287. return 0;
  4288. }
  4289. /*==========================================
  4290. * ??攻?停止
  4291. *------------------------------------------
  4292. */
  4293. int pc_stopattack(struct map_session_data *sd)
  4294. {
  4295. nullpo_retr(0, sd);
  4296. if(sd->attacktimer != -1) {
  4297. delete_timer(sd->attacktimer,pc_attack_timer);
  4298. sd->attacktimer=-1;
  4299. }
  4300. sd->attacktarget=0;
  4301. sd->state.attack_continue=0;
  4302. return 0;
  4303. }
  4304. int pc_follow_timer(int tid,unsigned int tick,int id,int data)
  4305. {
  4306. struct map_session_data *sd, *bl;
  4307. sd=map_id2sd(id);
  4308. if(sd == NULL || sd->followtimer != tid || pc_isdead(sd))
  4309. return 0;
  4310. sd->followtimer=-1;
  4311. do {
  4312. if(sd->bl.prev == NULL)
  4313. break;
  4314. bl=(struct map_session_data *) map_id2bl(sd->followtarget);
  4315. if(bl==NULL)
  4316. return 0;
  4317. if(bl->bl.prev == NULL)
  4318. break;
  4319. if(bl->bl.type == BL_PC && pc_isdead((struct map_session_data *)bl))
  4320. return 0;
  4321. if (sd->skilltimer == -1 && sd->attacktimer == -1 && sd->walktimer == -1) {
  4322. if((sd->bl.m == bl->bl.m) && pc_can_reach(sd,bl->bl.x,bl->bl.y)) {
  4323. if (distance(sd->bl.x,sd->bl.y,bl->bl.x,bl->bl.y) > 5)
  4324. pc_walktoxy(sd,bl->bl.x,bl->bl.y);
  4325. } else
  4326. pc_setpos((struct map_session_data*)sd, bl->mapname, bl->bl.x, bl->bl.y, 3);
  4327. }
  4328. } while (0);
  4329. sd->followtimer=add_timer(tick + sd->aspd,pc_follow_timer,sd->bl.id,0);
  4330. return 0;
  4331. }
  4332. int pc_follow(struct map_session_data *sd,int target_id)
  4333. {
  4334. struct block_list *bl;
  4335. bl=map_id2bl(target_id);
  4336. if(bl==NULL)
  4337. return 1;
  4338. sd->followtarget=target_id;
  4339. if(sd->followtimer != -1) {
  4340. delete_timer(sd->followtimer,pc_follow_timer);
  4341. sd->followtimer = -1;
  4342. }
  4343. pc_follow_timer(-1,gettick(),sd->bl.id,0);
  4344. return 0;
  4345. }
  4346. int pc_checkbaselevelup(struct map_session_data *sd)
  4347. {
  4348. int next = pc_nextbaseexp(sd);
  4349. nullpo_retr(0, sd);
  4350. if(sd->status.base_exp >= next && next > 0){
  4351. struct pc_base_job s_class = pc_calc_base_job(sd->status.class_);
  4352. // base側レベルアップ?理
  4353. sd->status.base_exp -= next;
  4354. sd->status.base_level ++;
  4355. sd->status.status_point += (sd->status.base_level+14) / 5 ;
  4356. clif_updatestatus(sd,SP_STATUSPOINT);
  4357. clif_updatestatus(sd,SP_BASELEVEL);
  4358. clif_updatestatus(sd,SP_NEXTBASEEXP);
  4359. pc_calcstatus(sd,0);
  4360. pc_heal(sd,sd->status.max_hp,sd->status.max_sp);
  4361. //スパノビはキリエ、イムポ、マニピ、グロ、サフラLv1がかかる
  4362. if(s_class.job == 23){
  4363. skill_status_change_start(&sd->bl,SkillStatusChangeTable[PR_KYRIE],1,0,0,0,skill_get_time(PR_KYRIE,1),0 );
  4364. skill_status_change_start(&sd->bl,SkillStatusChangeTable[PR_IMPOSITIO],1,0,0,0,skill_get_time(PR_IMPOSITIO,1),0 );
  4365. skill_status_change_start(&sd->bl,SkillStatusChangeTable[PR_MAGNIFICAT],1,0,0,0,skill_get_time(PR_MAGNIFICAT,1),0 );
  4366. skill_status_change_start(&sd->bl,SkillStatusChangeTable[PR_GLORIA],1,0,0,0,skill_get_time(PR_GLORIA,1),0 );
  4367. skill_status_change_start(&sd->bl,SkillStatusChangeTable[PR_SUFFRAGIUM],1,0,0,0,skill_get_time(PR_SUFFRAGIUM,1),0 );
  4368. }
  4369. clif_misceffect(&sd->bl,0);
  4370. //レベルアップしたのでパ?ティ?情報を更新する
  4371. //(公平範?チェック)
  4372. party_send_movemap(sd);
  4373. return 1;
  4374. }
  4375. return 0;
  4376. }
  4377. int pc_checkjoblevelup(struct map_session_data *sd)
  4378. {
  4379. int next = pc_nextjobexp(sd);
  4380. nullpo_retr(0, sd);
  4381. if(sd->status.job_exp >= next && next > 0){
  4382. // job側レベルアップ?理
  4383. sd->status.job_exp -= next;
  4384. sd->status.job_level ++;
  4385. clif_updatestatus(sd,SP_JOBLEVEL);
  4386. clif_updatestatus(sd,SP_NEXTJOBEXP);
  4387. sd->status.skill_point ++;
  4388. clif_updatestatus(sd,SP_SKILLPOINT);
  4389. pc_calcstatus(sd,0);
  4390. clif_misceffect(&sd->bl,1);
  4391. return 1;
  4392. }
  4393. return 0;
  4394. }
  4395. /*==========================================
  4396. * ??値取得
  4397. *------------------------------------------
  4398. */
  4399. int pc_gainexp(struct map_session_data *sd,int base_exp,int job_exp)
  4400. {
  4401. char output[256];
  4402. nullpo_retr(0, sd);
  4403. if(sd->bl.prev == NULL || pc_isdead(sd))
  4404. return 0;
  4405. if((battle_config.pvp_exp == 0) && map[sd->bl.m].flag.pvp) // [MouseJstr]
  4406. return 0; // no exp on pvp maps
  4407. if(sd->sc_data[SC_RICHMANKIM].timer != -1) { // added bounds checking [Vaalris]
  4408. base_exp += base_exp*(25 + sd->sc_data[SC_RICHMANKIM].val1*25)/100;
  4409. job_exp += job_exp*(25 + sd->sc_data[SC_RICHMANKIM].val1*25)/100;
  4410. }
  4411. if(sd->status.guild_id>0){ // ギルドに上納
  4412. base_exp-=guild_payexp(sd,base_exp);
  4413. if(base_exp < 0)
  4414. base_exp = 0;
  4415. }
  4416. if(!battle_config.multi_level_up && pc_nextbaseafter(sd) && sd->status.base_exp+base_exp >= pc_nextbaseafter(sd)) {
  4417. base_exp = pc_nextbaseafter(sd) - sd->status.base_exp;
  4418. if (base_exp < 0)
  4419. base_exp = 0;
  4420. }
  4421. sd->status.base_exp += base_exp;
  4422. if(sd->status.base_exp < 0)
  4423. sd->status.base_exp = 0;
  4424. while(pc_checkbaselevelup(sd)) ;
  4425. clif_updatestatus(sd,SP_BASEEXP);
  4426. if(!battle_config.multi_level_up && pc_nextjobafter(sd) && sd->status.job_exp+job_exp >= pc_nextjobafter(sd)) {
  4427. job_exp = pc_nextjobafter(sd) - sd->status.job_exp;
  4428. if (job_exp < 0)
  4429. job_exp = 0;
  4430. }
  4431. sd->status.job_exp += job_exp;
  4432. if(sd->status.job_exp < 0)
  4433. sd->status.job_exp = 0;
  4434. while(pc_checkjoblevelup(sd)) ;
  4435. clif_updatestatus(sd,SP_JOBEXP);
  4436. if(battle_config.disp_experience){
  4437. sprintf(output,
  4438. "Experienced Gained Base:%d Job:%d",base_exp,job_exp);
  4439. clif_disp_onlyself(sd,output,strlen(output));
  4440. }
  4441. return 0;
  4442. }
  4443. /*==========================================
  4444. * base level側必要??値計算
  4445. *------------------------------------------
  4446. */
  4447. int pc_nextbaseexp(struct map_session_data *sd)
  4448. {
  4449. int i;
  4450. nullpo_retr(0, sd);
  4451. if(sd->status.base_level>=MAX_LEVEL || sd->status.base_level<=0)
  4452. return 0;
  4453. if(sd->status.class_==0) i=0;
  4454. else if(sd->status.class_<=6) i=1;
  4455. else if(sd->status.class_<=22) i=2;
  4456. else if(sd->status.class_==23) i=3;
  4457. else if(sd->status.class_==4001) i=4;
  4458. else if(sd->status.class_<=4007) i=5;
  4459. else i=6;
  4460. return exp_table[i][sd->status.base_level-1];
  4461. }
  4462. /*==========================================
  4463. * job level側必要??値計算
  4464. *------------------------------------------
  4465. */
  4466. int pc_nextjobexp(struct map_session_data *sd)
  4467. {
  4468. int i;
  4469. nullpo_retr(0, sd);
  4470. if(sd->status.job_level>=MAX_LEVEL || sd->status.job_level<=0)
  4471. return 0;
  4472. if(sd->status.class_==0) i=7;
  4473. else if(sd->status.class_<=6) i=8;
  4474. else if(sd->status.class_<=22) i=9;
  4475. else if(sd->status.class_==23) i=10;
  4476. else if(sd->status.class_==4001) i=11;
  4477. else if(sd->status.class_<=4007) i=12;
  4478. else i=13;
  4479. return exp_table[i][sd->status.job_level-1];
  4480. }
  4481. /*==========================================
  4482. * base level after next [Valaris]
  4483. *------------------------------------------
  4484. */
  4485. int pc_nextbaseafter(struct map_session_data *sd)
  4486. {
  4487. int i;
  4488. nullpo_retr(0, sd);
  4489. if(sd->status.base_level>=MAX_LEVEL || sd->status.base_level<=0)
  4490. return 0;
  4491. if(sd->status.class_==0) i=0;
  4492. else if(sd->status.class_<=6) i=1;
  4493. else if(sd->status.class_<=22) i=2;
  4494. else if(sd->status.class_==23) i=3;
  4495. else if(sd->status.class_==4001) i=4;
  4496. else if(sd->status.class_<=4007) i=5;
  4497. else i=6;
  4498. return exp_table[i][sd->status.base_level];
  4499. }
  4500. /*==========================================
  4501. * job level after next [Valaris]
  4502. *------------------------------------------
  4503. */
  4504. int pc_nextjobafter(struct map_session_data *sd)
  4505. {
  4506. int i;
  4507. nullpo_retr(0, sd);
  4508. if(sd->status.job_level>=MAX_LEVEL || sd->status.job_level<=0)
  4509. return 0;
  4510. if(sd->status.class_==0) i=7;
  4511. else if(sd->status.class_<=6) i=8;
  4512. else if(sd->status.class_<=22) i=9;
  4513. else if(sd->status.class_==23) i=10;
  4514. else if(sd->status.class_==4001) i=11;
  4515. else if(sd->status.class_<=4007) i=12;
  4516. else i=13;
  4517. return exp_table[i][sd->status.job_level];
  4518. }
  4519. /*==========================================
  4520. * 必要ステ?タスポイント計算
  4521. *------------------------------------------
  4522. */
  4523. int pc_need_status_point(struct map_session_data *sd,int type)
  4524. {
  4525. int val;
  4526. nullpo_retr(-1, sd);
  4527. if(type<SP_STR || type>SP_LUK)
  4528. return -1;
  4529. val =
  4530. type==SP_STR ? sd->status.str :
  4531. type==SP_AGI ? sd->status.agi :
  4532. type==SP_VIT ? sd->status.vit :
  4533. type==SP_INT ? sd->status.int_:
  4534. type==SP_DEX ? sd->status.dex : sd->status.luk;
  4535. return (val+9)/10+1;
  4536. }
  4537. /*==========================================
  4538. * 能力値成長
  4539. *------------------------------------------
  4540. */
  4541. int pc_statusup(struct map_session_data *sd,int type)
  4542. {
  4543. int max, need,val = 0;
  4544. nullpo_retr(0, sd);
  4545. max = (pc_calc_upper(sd->status.class_)==2) ? 80 : battle_config.max_parameter;
  4546. need=pc_need_status_point(sd,type);
  4547. if(type<SP_STR || type>SP_LUK || need<0 || need>sd->status.status_point){
  4548. clif_statusupack(sd,type,0,0);
  4549. return 1;
  4550. }
  4551. switch(type){
  4552. case SP_STR:
  4553. if(sd->status.str >= max) {
  4554. clif_statusupack(sd,type,0,0);
  4555. return 1;
  4556. }
  4557. val= ++sd->status.str;
  4558. break;
  4559. case SP_AGI:
  4560. if(sd->status.agi >= max) {
  4561. clif_statusupack(sd,type,0,0);
  4562. return 1;
  4563. }
  4564. val= ++sd->status.agi;
  4565. break;
  4566. case SP_VIT:
  4567. if(sd->status.vit >= max) {
  4568. clif_statusupack(sd,type,0,0);
  4569. return 1;
  4570. }
  4571. val= ++sd->status.vit;
  4572. break;
  4573. case SP_INT:
  4574. if(sd->status.int_ >= max) {
  4575. clif_statusupack(sd,type,0,0);
  4576. return 1;
  4577. }
  4578. val= ++sd->status.int_;
  4579. break;
  4580. case SP_DEX:
  4581. if(sd->status.dex >= max) {
  4582. clif_statusupack(sd,type,0,0);
  4583. return 1;
  4584. }
  4585. val= ++sd->status.dex;
  4586. break;
  4587. case SP_LUK:
  4588. if(sd->status.luk >= max) {
  4589. clif_statusupack(sd,type,0,0);
  4590. return 1;
  4591. }
  4592. val= ++sd->status.luk;
  4593. break;
  4594. }
  4595. sd->status.status_point-=need;
  4596. if(need!=pc_need_status_point(sd,type)){
  4597. clif_updatestatus(sd,type-SP_STR+SP_USTR);
  4598. }
  4599. clif_updatestatus(sd,SP_STATUSPOINT);
  4600. clif_updatestatus(sd,type);
  4601. pc_calcstatus(sd,0);
  4602. clif_statusupack(sd,type,1,val);
  4603. return 0;
  4604. }
  4605. /*==========================================
  4606. * 能力値成長
  4607. *------------------------------------------
  4608. */
  4609. int pc_statusup2(struct map_session_data *sd,int type,int val)
  4610. {
  4611. nullpo_retr(0, sd);
  4612. if(type<SP_STR || type>SP_LUK){
  4613. clif_statusupack(sd,type,0,0);
  4614. return 1;
  4615. }
  4616. switch(type){
  4617. case SP_STR:
  4618. if(sd->status.str + val >= battle_config.max_parameter)
  4619. val = battle_config.max_parameter;
  4620. else if(sd->status.str + val < 1)
  4621. val = 1;
  4622. else
  4623. val += sd->status.str;
  4624. sd->status.str = val;
  4625. break;
  4626. case SP_AGI:
  4627. if(sd->status.agi + val >= battle_config.max_parameter)
  4628. val = battle_config.max_parameter;
  4629. else if(sd->status.agi + val < 1)
  4630. val = 1;
  4631. else
  4632. val += sd->status.agi;
  4633. sd->status.agi = val;
  4634. break;
  4635. case SP_VIT:
  4636. if(sd->status.vit + val >= battle_config.max_parameter)
  4637. val = battle_config.max_parameter;
  4638. else if(sd->status.vit + val < 1)
  4639. val = 1;
  4640. else
  4641. val += sd->status.vit;
  4642. sd->status.vit = val;
  4643. break;
  4644. case SP_INT:
  4645. if(sd->status.int_ + val >= battle_config.max_parameter)
  4646. val = battle_config.max_parameter;
  4647. else if(sd->status.int_ + val < 1)
  4648. val = 1;
  4649. else
  4650. val += sd->status.int_;
  4651. sd->status.int_ = val;
  4652. break;
  4653. case SP_DEX:
  4654. if(sd->status.dex + val >= battle_config.max_parameter)
  4655. val = battle_config.max_parameter;
  4656. else if(sd->status.dex + val < 1)
  4657. val = 1;
  4658. else
  4659. val += sd->status.dex;
  4660. sd->status.dex = val;
  4661. break;
  4662. case SP_LUK:
  4663. if(sd->status.luk + val >= battle_config.max_parameter)
  4664. val = battle_config.max_parameter;
  4665. else if(sd->status.luk + val < 1)
  4666. val = 1;
  4667. else
  4668. val = sd->status.luk + val;
  4669. sd->status.luk = val;
  4670. break;
  4671. }
  4672. clif_updatestatus(sd,type-SP_STR+SP_USTR);
  4673. clif_updatestatus(sd,type);
  4674. pc_calcstatus(sd,0);
  4675. clif_statusupack(sd,type,1,val);
  4676. return 0;
  4677. }
  4678. /*==========================================
  4679. * スキルポイント割り振り
  4680. *------------------------------------------
  4681. */
  4682. int pc_skillup(struct map_session_data *sd,int skill_num)
  4683. {
  4684. nullpo_retr(0, sd);
  4685. if( skill_num>=10000 ){
  4686. guild_skillup(sd,skill_num,0);
  4687. return 0;
  4688. }
  4689. if( sd->status.skill_point>0 &&
  4690. sd->status.skill[skill_num].id!=0 &&
  4691. //sd->status.skill[skill_num].lv < skill_get_max(skill_num) ) - celest
  4692. sd->status.skill[skill_num].lv < skill_tree_get_max(skill_num, sd->status.class_) )
  4693. {
  4694. sd->status.skill[skill_num].lv++;
  4695. sd->status.skill_point--;
  4696. pc_calcstatus(sd,0);
  4697. clif_skillup(sd,skill_num);
  4698. clif_updatestatus(sd,SP_SKILLPOINT);
  4699. clif_skillinfoblock(sd);
  4700. }
  4701. return 0;
  4702. }
  4703. /*==========================================
  4704. * /allskill
  4705. *------------------------------------------
  4706. */
  4707. int pc_allskillup(struct map_session_data *sd)
  4708. {
  4709. int i,id;
  4710. int c=0, s=0;
  4711. //?生や養子の場合の元の職業を算出する
  4712. struct pc_base_job s_class;
  4713. nullpo_retr(0, sd);
  4714. s_class = pc_calc_base_job(sd->status.class_);
  4715. c = s_class.job;
  4716. s = (s_class.upper==1) ? 1 : 0 ; //?生以外は通常のスキル?
  4717. for(i=0;i<MAX_SKILL;i++){
  4718. sd->status.skill[i].id=0;
  4719. if (sd->status.skill[i].flag && sd->status.skill[i].flag != 13){ // cardスキルなら、
  4720. sd->status.skill[i].lv=(sd->status.skill[i].flag==1)?0:sd->status.skill[i].flag-2; // 本?のlvに
  4721. sd->status.skill[i].flag=0; // flagは0にしておく
  4722. }
  4723. }
  4724. if (battle_config.gm_allskill > 0 && pc_isGM(sd) >= battle_config.gm_allskill){
  4725. // 全てのスキル
  4726. for(i=1;i<158;i++)
  4727. sd->status.skill[i].lv=skill_get_max(i);
  4728. for(i=210;i<291;i++)
  4729. sd->status.skill[i].lv=skill_get_max(i);
  4730. for(i=304;i<MAX_SKILL;i++){
  4731. if(i==331) continue;
  4732. sd->status.skill[i].lv=skill_get_max(i);
  4733. }
  4734. }
  4735. else {
  4736. for(i=0;(id=skill_tree[s][c][i].id)>0;i++){
  4737. if(sd->status.skill[id].id==0 && (!(skill_get_inf2(id)&0x01) || battle_config.quest_skill_learn) ) {
  4738. sd->status.skill[id].id = id; // celest
  4739. // sd->status.skill[id].lv=skill_get_max(id);
  4740. sd->status.skill[id].lv = skill_tree_get_max(id, sd->status.class_); // celest
  4741. }
  4742. }
  4743. }
  4744. pc_calcstatus(sd,0);
  4745. return 0;
  4746. }
  4747. /*==========================================
  4748. * /resetlvl
  4749. *------------------------------------------
  4750. */
  4751. int pc_resetlvl(struct map_session_data* sd,int type)
  4752. {
  4753. int i;
  4754. nullpo_retr(0, sd);
  4755. for(i=1;i<MAX_SKILL;i++){
  4756. sd->status.skill[i].lv = 0;
  4757. }
  4758. if(type == 1){
  4759. sd->status.skill_point=0;
  4760. sd->status.base_level=1;
  4761. sd->status.job_level=1;
  4762. sd->status.base_exp=sd->status.base_exp=0;
  4763. sd->status.job_exp=sd->status.job_exp=0;
  4764. if(sd->status.option !=0)
  4765. sd->status.option = 0;
  4766. sd->status.str=1;
  4767. sd->status.agi=1;
  4768. sd->status.vit=1;
  4769. sd->status.int_=1;
  4770. sd->status.dex=1;
  4771. sd->status.luk=1;
  4772. if(sd->status.class_ == 4001)
  4773. sd->status.status_point=100; // not 88 [celest]
  4774. // give platinum skills upon changing
  4775. pc_skill(sd,142,1,0);
  4776. pc_skill(sd,143,1,0);
  4777. }
  4778. if(type == 2){
  4779. sd->status.skill_point=0;
  4780. sd->status.base_level=1;
  4781. sd->status.job_level=1;
  4782. sd->status.base_exp=0;
  4783. sd->status.job_exp=0;
  4784. }
  4785. if(type == 3){
  4786. sd->status.base_level=1;
  4787. sd->status.base_exp=0;
  4788. }
  4789. if(type == 4){
  4790. sd->status.job_level=1;
  4791. sd->status.job_exp=0;
  4792. }
  4793. clif_updatestatus(sd,SP_STATUSPOINT);
  4794. clif_updatestatus(sd,SP_STR);
  4795. clif_updatestatus(sd,SP_AGI);
  4796. clif_updatestatus(sd,SP_VIT);
  4797. clif_updatestatus(sd,SP_INT);
  4798. clif_updatestatus(sd,SP_DEX);
  4799. clif_updatestatus(sd,SP_LUK);
  4800. clif_updatestatus(sd,SP_BASELEVEL);
  4801. clif_updatestatus(sd,SP_JOBLEVEL);
  4802. clif_updatestatus(sd,SP_STATUSPOINT);
  4803. clif_updatestatus(sd,SP_NEXTBASEEXP);
  4804. clif_updatestatus(sd,SP_NEXTJOBEXP);
  4805. clif_updatestatus(sd,SP_SKILLPOINT);
  4806. clif_updatestatus(sd,SP_USTR); // Updates needed stat points - Valaris
  4807. clif_updatestatus(sd,SP_UAGI);
  4808. clif_updatestatus(sd,SP_UVIT);
  4809. clif_updatestatus(sd,SP_UINT);
  4810. clif_updatestatus(sd,SP_UDEX);
  4811. clif_updatestatus(sd,SP_ULUK); // End Addition
  4812. for(i=0;i<11;i++) { // unequip items that can't be equipped by base 1 [Valaris]
  4813. if(sd->equip_index[i] >= 0)
  4814. if(!pc_isequip(sd,sd->equip_index[i]))
  4815. pc_unequipitem(sd,sd->equip_index[i],2);
  4816. }
  4817. clif_skillinfoblock(sd);
  4818. pc_calcstatus(sd,0);
  4819. return 0;
  4820. }
  4821. /*==========================================
  4822. * /resetstate
  4823. *------------------------------------------
  4824. */
  4825. int pc_resetstate(struct map_session_data* sd)
  4826. {
  4827. #define sumsp(a) ((a)*((a-2)/10+2) - 5*((a-2)/10)*((a-2)/10) - 6*((a-2)/10) -2)
  4828. // int add=0; // Removed by Dexity
  4829. nullpo_retr(0, sd);
  4830. // New statpoint table used here - Dexity
  4831. sd->status.status_point = atoi (statp[sd->status.base_level - 1]);
  4832. if(sd->status.class_ >= 4001 && sd->status.class_ <= 4024)
  4833. sd->status.status_point+=52; // extra 52+48=100 stat points
  4834. // End addition
  4835. // Removed by Dexity - old count
  4836. // add += sumsp(sd->status.str);
  4837. // add += sumsp(sd->status.agi);
  4838. // add += sumsp(sd->status.vit);
  4839. // add += sumsp(sd->status.int_);
  4840. // add += sumsp(sd->status.dex);
  4841. // add += sumsp(sd->status.luk);
  4842. // sd->status.status_point+=add;
  4843. clif_updatestatus(sd,SP_STATUSPOINT);
  4844. sd->status.str=1;
  4845. sd->status.agi=1;
  4846. sd->status.vit=1;
  4847. sd->status.int_=1;
  4848. sd->status.dex=1;
  4849. sd->status.luk=1;
  4850. clif_updatestatus(sd,SP_STR);
  4851. clif_updatestatus(sd,SP_AGI);
  4852. clif_updatestatus(sd,SP_VIT);
  4853. clif_updatestatus(sd,SP_INT);
  4854. clif_updatestatus(sd,SP_DEX);
  4855. clif_updatestatus(sd,SP_LUK);
  4856. clif_updatestatus(sd,SP_USTR); // Updates needed stat points - Valaris
  4857. clif_updatestatus(sd,SP_UAGI);
  4858. clif_updatestatus(sd,SP_UVIT);
  4859. clif_updatestatus(sd,SP_UINT);
  4860. clif_updatestatus(sd,SP_UDEX);
  4861. clif_updatestatus(sd,SP_ULUK); // End Addition
  4862. pc_calcstatus(sd,0);
  4863. return 0;
  4864. }
  4865. /*==========================================
  4866. * /resetskill
  4867. *------------------------------------------
  4868. */
  4869. int pc_resetskill(struct map_session_data* sd)
  4870. {
  4871. int i,skill;
  4872. nullpo_retr(0, sd);
  4873. for(i=1;i<MAX_SKILL;i++){
  4874. skill = ( i >= 10000 ) ? pc_checkskill(sd,i) : sd->status.skill[i].lv;
  4875. if( skill > 0) {
  4876. if(!(skill_get_inf2(i)&0x01) || battle_config.quest_skill_learn) {
  4877. if(!sd->status.skill[i].flag)
  4878. sd->status.skill_point += skill;
  4879. else if(sd->status.skill[i].flag > 2 && sd->status.skill[i].flag != 13) {
  4880. sd->status.skill_point += (sd->status.skill[i].flag - 2);
  4881. }
  4882. sd->status.skill[i].lv = 0;
  4883. }
  4884. else if(battle_config.quest_skill_reset)
  4885. sd->status.skill[i].lv = 0;
  4886. sd->status.skill[i].flag = 0;
  4887. } else {
  4888. sd->status.skill[i].lv = 0;
  4889. }
  4890. }
  4891. clif_updatestatus(sd,SP_SKILLPOINT);
  4892. clif_skillinfoblock(sd);
  4893. pc_calcstatus(sd,0);
  4894. return 0;
  4895. }
  4896. /*==========================================
  4897. * pcにダメ?ジを?える
  4898. *------------------------------------------
  4899. */
  4900. int pc_damage(struct block_list *src,struct map_session_data *sd,int damage)
  4901. {
  4902. int i=0,j=0;
  4903. struct pc_base_job s_class;
  4904. nullpo_retr(0, sd);
  4905. //?生や養子の場合の元の職業を算出する
  4906. s_class = pc_calc_base_job(sd->status.class_);
  4907. // ?に死んでいたら無?
  4908. if(pc_isdead(sd))
  4909. return 0;
  4910. // 座ってたら立ち上がる
  4911. if(pc_issit(sd)) {
  4912. pc_setstand(sd);
  4913. skill_gangsterparadise(sd,0);
  4914. }
  4915. // ? いていたら足を止める
  4916. if (sd->sc_data) {
  4917. if (sd->sc_data[SC_ENDURE].timer == -1 && sd->sc_data[SC_BERSERK].timer == -1 && !sd->special_state.infinite_endure)
  4918. pc_stop_walking(sd,3);
  4919. else if(sd->sc_data[SC_ENDURE].timer != -1 && (src != NULL && src->type==BL_MOB) && (--sd->sc_data[SC_ENDURE].val2) <= 0)
  4920. skill_status_change_end(&sd->bl, SC_ENDURE, -1);
  4921. } else
  4922. pc_stop_walking(sd,3);
  4923. // 演奏/ダンスの中?
  4924. if(damage > sd->status.max_hp>>2)
  4925. skill_stop_dancing(&sd->bl,0);
  4926. sd->status.hp-=damage;
  4927. if(sd->status.pet_id > 0 && sd->pd && sd->petDB && battle_config.pet_damage_support)
  4928. pet_target_check(sd,src,1);
  4929. if (sd->sc_data[SC_TRICKDEAD].timer != -1)
  4930. skill_status_change_end(&sd->bl, SC_TRICKDEAD, -1);
  4931. if(sd->status.option&2)
  4932. skill_status_change_end(&sd->bl, SC_HIDING, -1);
  4933. if(sd->status.option&4)
  4934. skill_status_change_end(&sd->bl, SC_CLOAKING, -1);
  4935. if(sd->status.option&16386)
  4936. skill_status_change_end(&sd->bl, SC_CHASEWALK, -1);
  4937. if(sd->status.hp>0){
  4938. // まだ生きているならHP更新
  4939. clif_updatestatus(sd,SP_HP);
  4940. //if(sd->status.hp<sd->status.max_hp>>2 && pc_checkskill(sd,SM_AUTOBERSERK)>0 &&
  4941. if(sd->status.hp<sd->status.max_hp>>2 && sd->sc_data[SC_AUTOBERSERK].timer != -1 &&
  4942. (sd->sc_data[SC_PROVOKE].timer==-1 || sd->sc_data[SC_PROVOKE].val2==0 ))
  4943. // オ?トバ?サ?ク?動
  4944. skill_status_change_start(&sd->bl,SC_PROVOKE,10,1,0,0,0,0);
  4945. sd->canlog_tick = gettick();
  4946. if(sd->status.party_id>0) { // on-the-fly party hp updates [Valaris]
  4947. struct party *p=party_search(sd->status.party_id);
  4948. if(p!=NULL) clif_party_hp(p,sd);
  4949. } // end addition [Valaris]
  4950. return 0;
  4951. }
  4952. sd->status.hp = 0;
  4953. //pc_setdead(sd);
  4954. if(sd->vender_id)
  4955. vending_closevending(sd);
  4956. if(sd->status.pet_id > 0 && sd->pd) {
  4957. if(sd->petDB) {
  4958. sd->pet.intimate -= sd->petDB->die;
  4959. if(sd->pet.intimate < 0)
  4960. sd->pet.intimate = 0;
  4961. clif_send_petdata(sd,1,sd->pet.intimate);
  4962. }
  4963. }
  4964. pc_stop_walking(sd,0);
  4965. skill_castcancel(&sd->bl,0); // 詠唱の中止
  4966. clif_clearchar_area(&sd->bl,1);
  4967. pc_setdead(sd);
  4968. skill_unit_out_all(&sd->bl,gettick(),1);
  4969. if(sd->sc_data[SC_BLADESTOP].timer!=-1)//白刃は事前に解除
  4970. skill_status_change_end(&sd->bl,SC_BLADESTOP,-1);
  4971. pc_setglobalreg(sd,"PC_DIE_COUNTER",++sd->die_counter); //死にカウンタ?書き?み
  4972. skill_status_change_clear(&sd->bl,0); // ステ?タス異常を解除する
  4973. clif_updatestatus(sd,SP_HP);
  4974. pc_calcstatus(sd,0);
  4975. if (sd->state.event_death) {
  4976. struct npc_data *npc;
  4977. if ((npc = npc_name2id("PCDeathEvent"))) {
  4978. run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCDeathNPC
  4979. ShowStatus("Event '"CL_WHITE"PCDeathEvent"CL_RESET"' executed.\n");
  4980. }
  4981. }
  4982. if (src && src->type == BL_PC) {
  4983. if (((struct map_session_data *)src)->state.event_kill) {
  4984. struct npc_data *npc;
  4985. if ((npc = npc_name2id("PCKillEvent"))) {
  4986. run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCKillNPC
  4987. ShowStatus("Event '"CL_WHITE"PCKillEvent"CL_RESET"' executed.\n");
  4988. }
  4989. }
  4990. if (sd->state.event_death)
  4991. pc_setglobalreg(sd,"killerrid",((struct map_session_data *)src)->status.account_id);
  4992. }
  4993. if(battle_config.bone_drop==2
  4994. || (battle_config.bone_drop==1 && map[sd->bl.m].flag.pvp)){ // ドクロドロップ
  4995. struct item item_tmp;
  4996. memset(&item_tmp,0,sizeof(item_tmp));
  4997. item_tmp.nameid=7005;
  4998. item_tmp.identify=1;
  4999. item_tmp.card[0]=0x00fe;
  5000. item_tmp.card[1]=0;
  5001. *((unsigned long *)(&item_tmp.card[2]))=sd->char_id; /* キャラID */
  5002. map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0);
  5003. }
  5004. // activate Steel body if a super novice dies at 99+% exp [celest]
  5005. if (s_class.job == 23) {
  5006. if ((i=pc_nextbaseexp(sd))<=0)
  5007. i=sd->status.base_exp;
  5008. if ((j=sd->status.base_exp*1000/i)>=990 && j<=1000)
  5009. sd->state.snovice_flag = 4;
  5010. }
  5011. for(i=0;i<5;i++)
  5012. if(sd->dev.val1[i]){
  5013. skill_status_change_end(&map_id2sd(sd->dev.val1[i])->bl,SC_DEVOTION,-1);
  5014. sd->dev.val1[i] = sd->dev.val2[i]=0;
  5015. }
  5016. if(battle_config.death_penalty_type>0) { // changed penalty options, added death by player if pk_mode [Valaris]
  5017. if(sd->status.class_ != 0 && !map[sd->bl.m].flag.nopenalty && !map[sd->bl.m].flag.gvg){ // only novices will recieve no penalty
  5018. if(battle_config.death_penalty_type==1 && battle_config.death_penalty_base > 0)
  5019. sd->status.base_exp -= (double)pc_nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000;
  5020. if(battle_config.pk_mode && src && src->type==BL_PC)
  5021. sd->status.base_exp -= (double)pc_nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000;
  5022. else if(battle_config.death_penalty_type==2 && battle_config.death_penalty_base > 0) {
  5023. if(pc_nextbaseexp(sd) > 0)
  5024. sd->status.base_exp -= (double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000;
  5025. if(battle_config.pk_mode && src && src->type==BL_PC)
  5026. sd->status.base_exp -= (double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000;
  5027. }
  5028. if(sd->status.base_exp < 0)
  5029. sd->status.base_exp = 0;
  5030. clif_updatestatus(sd,SP_BASEEXP);
  5031. if(battle_config.death_penalty_type==1 && battle_config.death_penalty_job > 0)
  5032. sd->status.job_exp -= (double)pc_nextjobexp(sd) * (double)battle_config.death_penalty_job/10000;
  5033. if(battle_config.pk_mode && src && src->type==BL_PC)
  5034. sd->status.job_exp -= (double)pc_nextjobexp(sd) * (double)battle_config.death_penalty_job/10000;
  5035. else if(battle_config.death_penalty_type==2 && battle_config.death_penalty_job > 0) {
  5036. if(pc_nextjobexp(sd) > 0)
  5037. sd->status.job_exp -= (double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000;
  5038. if(battle_config.pk_mode && src && src->type==BL_PC)
  5039. sd->status.job_exp -= (double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000;
  5040. }
  5041. if(sd->status.job_exp < 0)
  5042. sd->status.job_exp = 0;
  5043. clif_updatestatus(sd,SP_JOBEXP);
  5044. }
  5045. }
  5046. // monster level up [Valaris]
  5047. if(battle_config.mobs_level_up && src && src->type==BL_MOB) {
  5048. struct mob_data *md=(struct mob_data *)src;
  5049. if(md && md->target_id != 0 && md->target_id==sd->bl.id) { // reset target id when player dies
  5050. md->target_id=0;
  5051. mob_changestate(md,MS_WALK,0);
  5052. }
  5053. if(md && md->state.state!=MS_DEAD && md->level < 99) {
  5054. clif_misceffect(&md->bl,0);
  5055. md->level++;
  5056. md->hp+=sd->status.max_hp*.1;
  5057. }
  5058. }
  5059. //ナイトメアモ?ドアイテムドロップ
  5060. if(map[sd->bl.m].flag.pvp_nightmaredrop){ // Moved this outside so it works when PVP isnt enabled and during pk mode [Ancyker]
  5061. for(j=0;j<MAX_DROP_PER_MAP;j++){
  5062. int id = map[sd->bl.m].drop_list[j].drop_id;
  5063. int type = map[sd->bl.m].drop_list[j].drop_type;
  5064. int per = map[sd->bl.m].drop_list[j].drop_per;
  5065. if(id == 0)
  5066. continue;
  5067. if(id == -1){//ランダムドロップ
  5068. int eq_num=0,eq_n[MAX_INVENTORY];
  5069. memset(eq_n,0,sizeof(eq_n));
  5070. //先ず?備しているアイテム?をカウント
  5071. for(i=0;i<MAX_INVENTORY;i++){
  5072. int k;
  5073. if( (type == 1 && !sd->status.inventory[i].equip)
  5074. || (type == 2 && sd->status.inventory[i].equip)
  5075. || type == 3){
  5076. //InventoryIndexを格納
  5077. for(k=0;k<MAX_INVENTORY;k++){
  5078. if(eq_n[k] <= 0){
  5079. eq_n[k]=i;
  5080. break;
  5081. }
  5082. }
  5083. eq_num++;
  5084. }
  5085. }
  5086. if(eq_num > 0){
  5087. int n = eq_n[rand()%eq_num];//該?アイテムの中からランダム
  5088. if(rand()%10000 < per){
  5089. if(sd->status.inventory[n].equip)
  5090. pc_unequipitem(sd,n,3);
  5091. pc_dropitem(sd,n,1);
  5092. }
  5093. }
  5094. }
  5095. else if(id > 0){
  5096. for(i=0;i<MAX_INVENTORY;i++){
  5097. if(sd->status.inventory[i].nameid == id//ItemIDが一致していて
  5098. && rand()%10000 < per//ドロップ率判定もOKで
  5099. && ((type == 1 && !sd->status.inventory[i].equip)//タイプ判定もOKならドロップ
  5100. || (type == 2 && sd->status.inventory[i].equip)
  5101. || type == 3) ){
  5102. if(sd->status.inventory[i].equip)
  5103. pc_unequipitem(sd,i,3);
  5104. pc_dropitem(sd,i,1);
  5105. break;
  5106. }
  5107. }
  5108. }
  5109. }
  5110. }
  5111. // pvp
  5112. if( map[sd->bl.m].flag.pvp && !battle_config.pk_mode){ // disable certain pvp functions on pk_mode [Valaris]
  5113. //ランキング計算
  5114. if(!map[sd->bl.m].flag.pvp_nocalcrank){
  5115. sd->pvp_point-=5;
  5116. if(src && src->type==BL_PC )
  5117. ((struct map_session_data *)src)->pvp_point++;
  5118. //} //fixed wrong '{' placement by Lupus
  5119. pc_setdead(sd);
  5120. }
  5121. // ?制送還
  5122. if( sd->pvp_point < 0 ){
  5123. sd->pvp_point=0;
  5124. pc_setstand(sd);
  5125. pc_setrestartvalue(sd,3);
  5126. pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,0);
  5127. }
  5128. }
  5129. //GvG
  5130. if(map[sd->bl.m].flag.gvg){
  5131. pc_setstand(sd);
  5132. pc_setrestartvalue(sd,3);
  5133. pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,0);
  5134. }
  5135. return 0;
  5136. }
  5137. //
  5138. // script? 連
  5139. //
  5140. /*==========================================
  5141. * script用PCステ?タス?み出し
  5142. *------------------------------------------
  5143. */
  5144. int pc_readparam(struct map_session_data *sd,int type)
  5145. {
  5146. int val=0;
  5147. struct pc_base_job s_class;
  5148. s_class = pc_calc_base_job(sd->status.class_);
  5149. nullpo_retr(0, sd);
  5150. switch(type){
  5151. case SP_SKILLPOINT:
  5152. val= sd->status.skill_point;
  5153. break;
  5154. case SP_STATUSPOINT:
  5155. val= sd->status.status_point;
  5156. break;
  5157. case SP_ZENY:
  5158. val= sd->status.zeny;
  5159. break;
  5160. case SP_BASELEVEL:
  5161. val= sd->status.base_level;
  5162. break;
  5163. case SP_JOBLEVEL:
  5164. val= sd->status.job_level;
  5165. break;
  5166. case SP_CLASS:
  5167. if(val>=24 && val < 45)
  5168. val+=3978;
  5169. else
  5170. val= sd->status.class_;
  5171. break;
  5172. case SP_BASEJOB:
  5173. val= s_class.job;
  5174. break;
  5175. case SP_UPPER:
  5176. val= s_class.upper;
  5177. break;
  5178. case SP_SEX:
  5179. val= sd->sex;
  5180. break;
  5181. case SP_WEIGHT:
  5182. val= sd->weight;
  5183. break;
  5184. case SP_MAXWEIGHT:
  5185. val= sd->max_weight;
  5186. break;
  5187. case SP_BASEEXP:
  5188. val= sd->status.base_exp;
  5189. break;
  5190. case SP_JOBEXP:
  5191. val= sd->status.job_exp;
  5192. break;
  5193. case SP_NEXTBASEEXP:
  5194. val= pc_nextbaseexp(sd);
  5195. break;
  5196. case SP_NEXTJOBEXP:
  5197. val= pc_nextjobexp(sd);
  5198. break;
  5199. case SP_HP:
  5200. val= sd->status.hp;
  5201. break;
  5202. case SP_MAXHP:
  5203. val= sd->status.max_hp;
  5204. break;
  5205. case SP_SP:
  5206. val= sd->status.sp;
  5207. break;
  5208. case SP_MAXSP:
  5209. val= sd->status.max_sp;
  5210. break;
  5211. case SP_STR:
  5212. val= sd->status.str;
  5213. break;
  5214. case SP_AGI:
  5215. val= sd->status.agi;
  5216. break;
  5217. case SP_VIT:
  5218. val= sd->status.vit;
  5219. break;
  5220. case SP_INT:
  5221. val= sd->status.int_;
  5222. break;
  5223. case SP_DEX:
  5224. val= sd->status.dex;
  5225. break;
  5226. case SP_LUK:
  5227. val= sd->status.luk;
  5228. break;
  5229. case SP_FAME:
  5230. val= sd->fame;
  5231. break;
  5232. }
  5233. return val;
  5234. }
  5235. /*==========================================
  5236. * script用PCステ?タス設定
  5237. *------------------------------------------
  5238. */
  5239. int pc_setparam(struct map_session_data *sd,int type,int val)
  5240. {
  5241. int i = 0,up_level = 50;
  5242. struct pc_base_job s_class;
  5243. nullpo_retr(0, sd);
  5244. s_class = pc_calc_base_job(sd->status.class_);
  5245. switch(type){
  5246. case SP_BASELEVEL:
  5247. if (val > sd->status.base_level) {
  5248. for (i = 1; i <= (val - sd->status.base_level); i++)
  5249. sd->status.status_point += (sd->status.base_level + i + 14) / 5 ;
  5250. }
  5251. sd->status.base_level = val;
  5252. sd->status.base_exp = 0;
  5253. clif_updatestatus(sd, SP_BASELEVEL);
  5254. clif_updatestatus(sd, SP_NEXTBASEEXP);
  5255. clif_updatestatus(sd, SP_STATUSPOINT);
  5256. clif_updatestatus(sd, SP_BASEEXP);
  5257. pc_calcstatus(sd, 0);
  5258. pc_heal(sd, sd->status.max_hp, sd->status.max_sp);
  5259. break;
  5260. case SP_JOBLEVEL:
  5261. if (s_class.job == 0)
  5262. up_level -= 40;
  5263. // super novices can go up to 99 [celest]
  5264. else if (s_class.job == 23)
  5265. up_level += 49;
  5266. else if (sd->status.class_ >= 4008 && sd->status.class_ <= 4022)
  5267. up_level += 20;
  5268. if (val >= sd->status.job_level) {
  5269. if (val > up_level)val = up_level;
  5270. sd->status.skill_point += (val-sd->status.job_level);
  5271. sd->status.job_level = val;
  5272. sd->status.job_exp = 0;
  5273. clif_updatestatus(sd, SP_JOBLEVEL);
  5274. clif_updatestatus(sd, SP_NEXTJOBEXP);
  5275. clif_updatestatus(sd, SP_JOBEXP);
  5276. clif_updatestatus(sd, SP_SKILLPOINT);
  5277. pc_calcstatus(sd, 0);
  5278. clif_misceffect(&sd->bl, 1);
  5279. } else {
  5280. sd->status.job_level = val;
  5281. sd->status.job_exp = 0;
  5282. clif_updatestatus(sd, SP_JOBLEVEL);
  5283. clif_updatestatus(sd, SP_NEXTJOBEXP);
  5284. clif_updatestatus(sd, SP_JOBEXP);
  5285. pc_calcstatus(sd, 0);
  5286. }
  5287. clif_updatestatus(sd,type);
  5288. break;
  5289. case SP_SKILLPOINT:
  5290. sd->status.skill_point = val;
  5291. break;
  5292. case SP_STATUSPOINT:
  5293. sd->status.status_point = val;
  5294. break;
  5295. case SP_ZENY:
  5296. sd->status.zeny = val;
  5297. break;
  5298. case SP_BASEEXP:
  5299. if(pc_nextbaseexp(sd) > 0) {
  5300. sd->status.base_exp = val;
  5301. if(sd->status.base_exp < 0)
  5302. sd->status.base_exp=0;
  5303. pc_checkbaselevelup(sd);
  5304. }
  5305. break;
  5306. case SP_JOBEXP:
  5307. if(pc_nextjobexp(sd) > 0) {
  5308. sd->status.job_exp = val;
  5309. if(sd->status.job_exp < 0)
  5310. sd->status.job_exp=0;
  5311. pc_checkjoblevelup(sd);
  5312. }
  5313. break;
  5314. case SP_SEX:
  5315. sd->sex = val;
  5316. break;
  5317. case SP_WEIGHT:
  5318. sd->weight = val;
  5319. break;
  5320. case SP_MAXWEIGHT:
  5321. sd->max_weight = val;
  5322. break;
  5323. case SP_HP:
  5324. sd->status.hp = val;
  5325. break;
  5326. case SP_MAXHP:
  5327. sd->status.max_hp = val;
  5328. break;
  5329. case SP_SP:
  5330. sd->status.sp = val;
  5331. break;
  5332. case SP_MAXSP:
  5333. sd->status.max_sp = val;
  5334. break;
  5335. case SP_STR:
  5336. sd->status.str = val;
  5337. break;
  5338. case SP_AGI:
  5339. sd->status.agi = val;
  5340. break;
  5341. case SP_VIT:
  5342. sd->status.vit = val;
  5343. break;
  5344. case SP_INT:
  5345. sd->status.int_ = val;
  5346. break;
  5347. case SP_DEX:
  5348. sd->status.dex = val;
  5349. break;
  5350. case SP_LUK:
  5351. sd->status.luk = val;
  5352. break;
  5353. case SP_FAME:
  5354. sd->fame = val;
  5355. break;
  5356. }
  5357. clif_updatestatus(sd,type);
  5358. return 0;
  5359. }
  5360. /*==========================================
  5361. * HP/SP回復
  5362. *------------------------------------------
  5363. */
  5364. int pc_heal(struct map_session_data *sd,int hp,int sp)
  5365. {
  5366. // if(battle_config.battle_log)
  5367. // printf("heal %d %d\n",hp,sp);
  5368. nullpo_retr(0, sd);
  5369. if(pc_checkoverhp(sd)) {
  5370. if(hp > 0)
  5371. hp = 0;
  5372. }
  5373. if(pc_checkoversp(sd)) {
  5374. if(sp > 0)
  5375. sp = 0;
  5376. }
  5377. if(sd->sc_count && sd->sc_data[SC_BERSERK].timer!=-1) //バ?サ?ク中は回復させないらしい
  5378. return 0;
  5379. if(hp+sd->status.hp>sd->status.max_hp)
  5380. hp=sd->status.max_hp-sd->status.hp;
  5381. if(sp+sd->status.sp>sd->status.max_sp)
  5382. sp=sd->status.max_sp-sd->status.sp;
  5383. sd->status.hp+=hp;
  5384. if(sd->status.hp <= 0) {
  5385. sd->status.hp = 0;
  5386. pc_damage(NULL,sd,1);
  5387. hp = 0;
  5388. }
  5389. sd->status.sp+=sp;
  5390. if(sd->status.sp <= 0)
  5391. sd->status.sp = 0;
  5392. if(hp)
  5393. clif_updatestatus(sd,SP_HP);
  5394. if(sp)
  5395. clif_updatestatus(sd,SP_SP);
  5396. if(sd->status.party_id>0) { // on-the-fly party hp updates [Valaris]
  5397. struct party *p=party_search(sd->status.party_id);
  5398. if(p!=NULL) clif_party_hp(p,sd);
  5399. } // end addition [Valaris]
  5400. return hp + sp;
  5401. }
  5402. /*==========================================
  5403. * HP/SP回復
  5404. *------------------------------------------
  5405. */
  5406. int pc_itemheal(struct map_session_data *sd,int hp,int sp)
  5407. {
  5408. int bonus;
  5409. // if(battle_config.battle_log)
  5410. // printf("heal %d %d\n",hp,sp);
  5411. nullpo_retr(0, sd);
  5412. if(sd->sc_count && sd->sc_data[SC_GOSPEL].timer!=-1) //バ?サ?ク中は回復させないらしい
  5413. return 0;
  5414. if(sd->state.potionpitcher_flag) {
  5415. sd->potion_hp = hp;
  5416. sd->potion_sp = sp;
  5417. return 0;
  5418. }
  5419. if(pc_checkoverhp(sd)) {
  5420. if(hp > 0)
  5421. hp = 0;
  5422. }
  5423. if(pc_checkoversp(sd)) {
  5424. if(sp > 0)
  5425. sp = 0;
  5426. }
  5427. if(hp > 0) {
  5428. bonus = (sd->paramc[2]<<1) + 100 + pc_checkskill(sd,SM_RECOVERY)*10;
  5429. if(bonus != 100)
  5430. hp = hp * bonus / 100;
  5431. bonus = 100 + pc_checkskill(sd,AM_LEARNINGPOTION)*5;
  5432. if(bonus != 100)
  5433. hp = hp * bonus / 100;
  5434. }
  5435. if(sp > 0) {
  5436. bonus = (sd->paramc[3]<<1) + 100 + pc_checkskill(sd,MG_SRECOVERY)*10;
  5437. if(bonus != 100)
  5438. sp = sp * bonus / 100;
  5439. bonus = 100 + pc_checkskill(sd,AM_LEARNINGPOTION)*5;
  5440. if(bonus != 100)
  5441. sp = sp * bonus / 100;
  5442. }
  5443. if(hp+sd->status.hp>sd->status.max_hp)
  5444. hp=sd->status.max_hp-sd->status.hp;
  5445. if(sp+sd->status.sp>sd->status.max_sp)
  5446. sp=sd->status.max_sp-sd->status.sp;
  5447. sd->status.hp+=hp;
  5448. if(sd->status.hp <= 0) {
  5449. sd->status.hp = 0;
  5450. pc_damage(NULL,sd,1);
  5451. hp = 0;
  5452. }
  5453. sd->status.sp+=sp;
  5454. if(sd->status.sp <= 0)
  5455. sd->status.sp = 0;
  5456. if(hp)
  5457. clif_updatestatus(sd,SP_HP);
  5458. if(sp)
  5459. clif_updatestatus(sd,SP_SP);
  5460. return 0;
  5461. }
  5462. /*==========================================
  5463. * HP/SP回復
  5464. *------------------------------------------
  5465. */
  5466. int pc_percentheal(struct map_session_data *sd,int hp,int sp)
  5467. {
  5468. nullpo_retr(0, sd);
  5469. if(sd->state.potionpitcher_flag) {
  5470. sd->potion_per_hp = hp;
  5471. sd->potion_per_sp = sp;
  5472. return 0;
  5473. }
  5474. if(pc_checkoverhp(sd)) {
  5475. if(hp > 0)
  5476. hp = 0;
  5477. }
  5478. if(pc_checkoversp(sd)) {
  5479. if(sp > 0)
  5480. sp = 0;
  5481. }
  5482. if(hp) {
  5483. if(hp >= 100) {
  5484. sd->status.hp = sd->status.max_hp;
  5485. }
  5486. else if(hp <= -100) {
  5487. sd->status.hp = 0;
  5488. pc_damage(NULL,sd,1);
  5489. }
  5490. else {
  5491. sd->status.hp += sd->status.max_hp*hp/100;
  5492. if(sd->status.hp > sd->status.max_hp)
  5493. sd->status.hp = sd->status.max_hp;
  5494. if(sd->status.hp <= 0) {
  5495. sd->status.hp = 0;
  5496. pc_damage(NULL,sd,1);
  5497. hp = 0;
  5498. }
  5499. }
  5500. }
  5501. if(sp) {
  5502. if(sp >= 100) {
  5503. sd->status.sp = sd->status.max_sp;
  5504. }
  5505. else if(sp <= -100) {
  5506. sd->status.sp = 0;
  5507. }
  5508. else {
  5509. sd->status.sp += sd->status.max_sp*sp/100;
  5510. if(sd->status.sp > sd->status.max_sp)
  5511. sd->status.sp = sd->status.max_sp;
  5512. if(sd->status.sp < 0)
  5513. sd->status.sp = 0;
  5514. }
  5515. }
  5516. if(hp)
  5517. clif_updatestatus(sd,SP_HP);
  5518. if(sp)
  5519. clif_updatestatus(sd,SP_SP);
  5520. return 0;
  5521. }
  5522. /*==========================================
  5523. * 職?更
  5524. * 引? job 職業 0~23
  5525. * upper 通常 0, ?生 1, 養子 2, そのまま -1
  5526. * Rewrote to make it tidider [Celest]
  5527. *------------------------------------------
  5528. */
  5529. int pc_jobchange(struct map_session_data *sd,int job, int upper)
  5530. {
  5531. int i;
  5532. int b_class = 0;
  5533. //?生や養子の場合の元の職業を算出する
  5534. struct pc_base_job s_class = pc_calc_base_job(sd->status.class_);
  5535. nullpo_retr(0, sd);
  5536. if (upper < 0 || upper > 2) //現在?生かどうかを判?する
  5537. upper = s_class.upper;
  5538. b_class = job; //通常職ならjobそのまんま
  5539. if (job < 23) {
  5540. if (upper == 1)
  5541. b_class += 4001;
  5542. else if (upper == 2) //養子に結婚はないけどどうせ次で蹴られるからいいや
  5543. b_class += 4023;
  5544. } else if (job == 23) {
  5545. if (upper == 1) //?生にスパノビは存在しないのでお?り
  5546. return 1;
  5547. else if (upper == 2)
  5548. b_class += 4022;
  5549. } else if (job > 23 && job < 69) {
  5550. b_class += 3977;
  5551. } else if ((job >= 69 && job < 4001) || (job > 4045))
  5552. return 1;
  5553. job = pc_calc_base_job2 (b_class); // check base class [celest]
  5554. if((sd->status.sex == 0 && job == 19) || (sd->status.sex == 1 && job == 20) ||
  5555. // not needed [celest]
  5556. //(sd->status.sex == 0 && job == 4020) || (sd->status.sex == 1 && job == 4021) ||
  5557. job == 22 || sd->status.class_ == b_class) //♀はバ?ドになれない、♂はダンサ?になれない、結婚衣裳もお?り
  5558. return 1;
  5559. // check if we are changing from 1st to 2nd job
  5560. if (job >= 7 && job <= 21) {
  5561. if (s_class.job > 0 && s_class.job < 7)
  5562. sd->change_level = sd->status.job_level;
  5563. else
  5564. sd->change_level = 40;
  5565. }
  5566. else
  5567. sd->change_level = 0;
  5568. pc_setglobalreg (sd, "jobchange_level", sd->change_level);
  5569. sd->status.class_ = sd->view_class = b_class;
  5570. sd->status.job_level=1;
  5571. sd->status.job_exp=0;
  5572. clif_updatestatus(sd,SP_JOBLEVEL);
  5573. clif_updatestatus(sd,SP_JOBEXP);
  5574. clif_updatestatus(sd,SP_NEXTJOBEXP);
  5575. for(i=0;i<11;i++) {
  5576. if(sd->equip_index[i] >= 0)
  5577. if(!pc_isequip(sd,sd->equip_index[i]))
  5578. pc_unequipitem(sd,sd->equip_index[i],2); // ?備外し
  5579. }
  5580. clif_changelook(&sd->bl,LOOK_BASE,sd->view_class); // move sprite update to prevent client crashes with incompatible equipment [Valaris]
  5581. if(sd->status.clothes_color > 0)
  5582. clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->status.clothes_color);
  5583. if(battle_config.muting_players && sd->status.manner < 0)
  5584. clif_changestatus(&sd->bl,SP_MANNER,sd->status.manner);
  5585. pc_calcstatus(sd,0);
  5586. pc_checkallowskill(sd);
  5587. pc_equiplookall(sd);
  5588. clif_equiplist(sd);
  5589. if(pc_isriding(sd)) { // remove peco status if changing into invalid class [Valaris]
  5590. if(!(pc_checkskill(sd,KN_RIDING)))
  5591. pc_setoption(sd,sd->status.option|-0x0000);
  5592. if(pc_checkskill(sd,KN_RIDING)>0)
  5593. pc_setriding(sd);
  5594. }
  5595. return 0;
  5596. }
  5597. /*==========================================
  5598. * 見た目?更
  5599. *------------------------------------------
  5600. */
  5601. int pc_equiplookall(struct map_session_data *sd)
  5602. {
  5603. nullpo_retr(0, sd);
  5604. #if PACKETVER < 4
  5605. clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
  5606. clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
  5607. #else
  5608. clif_changelook(&sd->bl,LOOK_WEAPON,0);
  5609. clif_changelook(&sd->bl,LOOK_SHOES,0);
  5610. #endif
  5611. clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
  5612. clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
  5613. clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
  5614. return 0;
  5615. }
  5616. /*==========================================
  5617. * 見た目?更
  5618. *------------------------------------------
  5619. */
  5620. int pc_changelook(struct map_session_data *sd,int type,int val)
  5621. {
  5622. nullpo_retr(0, sd);
  5623. switch(type){
  5624. case LOOK_HAIR:
  5625. sd->status.hair=val;
  5626. break;
  5627. case LOOK_WEAPON:
  5628. sd->status.weapon=val;
  5629. break;
  5630. case LOOK_HEAD_BOTTOM:
  5631. sd->status.head_bottom=val;
  5632. break;
  5633. case LOOK_HEAD_TOP:
  5634. sd->status.head_top=val;
  5635. break;
  5636. case LOOK_HEAD_MID:
  5637. sd->status.head_mid=val;
  5638. break;
  5639. case LOOK_HAIR_COLOR:
  5640. sd->status.hair_color=val;
  5641. break;
  5642. case LOOK_CLOTHES_COLOR:
  5643. sd->status.clothes_color=val;
  5644. break;
  5645. case LOOK_SHIELD:
  5646. sd->status.shield=val;
  5647. break;
  5648. case LOOK_SHOES:
  5649. break;
  5650. }
  5651. clif_changelook(&sd->bl,type,val);
  5652. return 0;
  5653. }
  5654. /*==========================================
  5655. * 付?品(鷹,ペコ,カ?ト)設定
  5656. *------------------------------------------
  5657. */
  5658. int pc_setoption(struct map_session_data *sd,int type)
  5659. {
  5660. nullpo_retr(0, sd);
  5661. sd->status.option=type;
  5662. clif_changeoption(&sd->bl);
  5663. pc_calcstatus(sd,0);
  5664. return 0;
  5665. }
  5666. /*==========================================
  5667. * カ?ト設定
  5668. *------------------------------------------
  5669. */
  5670. int pc_setcart(struct map_session_data *sd,int type)
  5671. {
  5672. int cart[6]={0x0000,0x0008,0x0080,0x0100,0x0200,0x0400};
  5673. nullpo_retr(0, sd);
  5674. if(pc_checkskill(sd,MC_PUSHCART)>0){ // プッシュカ?トスキル所持
  5675. if(!pc_iscarton(sd)){ // カ?トを付けていない
  5676. pc_setoption(sd,cart[type]);
  5677. clif_cart_itemlist(sd);
  5678. clif_cart_equiplist(sd);
  5679. clif_updatestatus(sd,SP_CARTINFO);
  5680. clif_status_change(&sd->bl,0x0c,0);
  5681. }
  5682. else{
  5683. pc_setoption(sd,cart[type]);
  5684. }
  5685. }
  5686. return 0;
  5687. }
  5688. /*==========================================
  5689. * 鷹設定
  5690. *------------------------------------------
  5691. */
  5692. int pc_setfalcon(struct map_session_data *sd)
  5693. {
  5694. if(pc_checkskill(sd,HT_FALCON)>0){ // ファルコンマスタリ?スキル所持
  5695. pc_setoption(sd,sd->status.option|0x0010);
  5696. }
  5697. return 0;
  5698. }
  5699. /*==========================================
  5700. * ペコペコ設定
  5701. *------------------------------------------
  5702. */
  5703. int pc_setriding(struct map_session_data *sd)
  5704. {
  5705. if(sd->disguise > 0) { // temporary prevention of crash caused by peco + disguise, will look into a better solution [Valaris]
  5706. clif_displaymessage(sd->fd, "Cannot mount a Peco while in disguise.");
  5707. return 0;
  5708. }
  5709. if((pc_checkskill(sd,KN_RIDING)>0)){ // ライディングスキル所持
  5710. pc_setoption(sd,sd->status.option|0x0020);
  5711. if(sd->status.class_==7)
  5712. sd->status.class_=sd->view_class=13;
  5713. if(sd->status.class_==14)
  5714. sd->status.class_=sd->view_class=21;
  5715. if(sd->status.class_==4008)
  5716. sd->status.class_=sd->view_class=4014;
  5717. if(sd->status.class_==4015)
  5718. sd->status.class_=sd->view_class=4022;
  5719. }
  5720. return 0;
  5721. }
  5722. /*==========================================
  5723. * アイテムドロップ可不可判定
  5724. *------------------------------------------
  5725. */
  5726. int pc_candrop(struct map_session_data *sd,int item_id)
  5727. {
  5728. int level;
  5729. if((level=pc_isGM(sd))>0 && level < battle_config.gm_can_drop_lv) // search only once [Celest]
  5730. return 1;
  5731. return 0;
  5732. }
  5733. /*==========================================
  5734. * script用??の値を?む
  5735. *------------------------------------------
  5736. */
  5737. int pc_readreg(struct map_session_data *sd,int reg)
  5738. {
  5739. int i;
  5740. nullpo_retr(0, sd);
  5741. for(i=0;i<sd->reg_num;i++)
  5742. if(sd->reg[i].index==reg)
  5743. return sd->reg[i].data;
  5744. return 0;
  5745. }
  5746. /*==========================================
  5747. * script用??の値を設定
  5748. *------------------------------------------
  5749. */
  5750. int pc_setreg(struct map_session_data *sd,int reg,int val)
  5751. {
  5752. int i;
  5753. nullpo_retr(0, sd);
  5754. for (i = 0; i < sd->reg_num; i++) {
  5755. if (sd->reg[i].index == reg){
  5756. sd->reg[i].data = val;
  5757. return 0;
  5758. }
  5759. }
  5760. sd->reg_num++;
  5761. sd->reg = aRealloc(sd->reg, sizeof(*(sd->reg)) * sd->reg_num);
  5762. if (sd->reg == NULL){
  5763. printf("out of memory : pc_setreg\n");
  5764. exit(1);
  5765. }
  5766. /* memset(sd->reg + (sd->reg_num - 1) * sizeof(*(sd->reg)), 0,
  5767. sizeof(*(sd->reg)));
  5768. */
  5769. sd->reg[i].index = reg;
  5770. sd->reg[i].data = val;
  5771. return 0;
  5772. }
  5773. /*==========================================
  5774. * script用文字列??の値を?む
  5775. *------------------------------------------
  5776. */
  5777. char *pc_readregstr(struct map_session_data *sd,int reg)
  5778. {
  5779. int i;
  5780. nullpo_retr(0, sd);
  5781. for(i=0;i<sd->regstr_num;i++)
  5782. if(sd->regstr[i].index==reg)
  5783. return sd->regstr[i].data;
  5784. return NULL;
  5785. }
  5786. /*==========================================
  5787. * script用文字列??の値を設定
  5788. *------------------------------------------
  5789. */
  5790. int pc_setregstr(struct map_session_data *sd,int reg,char *str)
  5791. {
  5792. int i;
  5793. nullpo_retr(0, sd);
  5794. if(strlen(str)+1 >= sizeof(sd->regstr[0].data)){
  5795. printf("pc_setregstr: string too long !\n");
  5796. return 0;
  5797. }
  5798. for(i=0;i<sd->regstr_num;i++)
  5799. if(sd->regstr[i].index==reg){
  5800. strcpy(sd->regstr[i].data,str);
  5801. return 0;
  5802. }
  5803. sd->regstr_num++;
  5804. sd->regstr = aRealloc(sd->regstr, sizeof(sd->regstr[0]) * sd->regstr_num);
  5805. if(sd->regstr==NULL){
  5806. printf("out of memory : pc_setreg\n");
  5807. exit(1);
  5808. }
  5809. /* memset(sd->reg + (sd->reg_num - 1) * sizeof(*(sd->reg)), 0,
  5810. sizeof(*(sd->reg)));
  5811. */
  5812. sd->regstr[i].index=reg;
  5813. strcpy(sd->regstr[i].data,str);
  5814. return 0;
  5815. }
  5816. /*==========================================
  5817. * script用グロ?バル??の値を?む
  5818. *------------------------------------------
  5819. */
  5820. int pc_readglobalreg(struct map_session_data *sd,char *reg)
  5821. {
  5822. int i;
  5823. nullpo_retr(0, sd);
  5824. for(i=0;i<sd->status.global_reg_num;i++){
  5825. if(strcmp(sd->status.global_reg[i].str,reg)==0)
  5826. return sd->status.global_reg[i].value;
  5827. }
  5828. return 0;
  5829. }
  5830. /*==========================================
  5831. * script用グロ?バル??の値を設定
  5832. *------------------------------------------
  5833. */
  5834. int pc_setglobalreg(struct map_session_data *sd,char *reg,int val)
  5835. {
  5836. int i;
  5837. nullpo_retr(0, sd);
  5838. //PC_DIE_COUNTERがスクリプトなどで?更された暫フ?理
  5839. if(strcmp(reg,"PC_DIE_COUNTER") == 0 && sd->die_counter != val){
  5840. sd->die_counter = val;
  5841. pc_calcstatus(sd,0);
  5842. } else if(strcmp(reg,"PCDieEvent") == 0){
  5843. sd->state.event_death = val;
  5844. } else if(strcmp(reg,"PCKillEvent") == 0){
  5845. sd->state.event_kill = val;
  5846. } else if(strcmp(reg,"PCLogoutEvent") == 0){
  5847. sd->state.event_disconnect = val;
  5848. } else if(strcmp(reg,"PCLoginEvent") == 0){
  5849. sd->state.event_onconnect = val;
  5850. }
  5851. if(val==0){
  5852. for(i=0;i<sd->status.global_reg_num;i++){
  5853. if(strcmp(sd->status.global_reg[i].str,reg)==0){
  5854. sd->status.global_reg[i]=sd->status.global_reg[sd->status.global_reg_num-1];
  5855. sd->status.global_reg_num--;
  5856. break;
  5857. }
  5858. }
  5859. return 0;
  5860. }
  5861. for(i=0;i<sd->status.global_reg_num;i++){
  5862. if(strcmp(sd->status.global_reg[i].str,reg)==0){
  5863. sd->status.global_reg[i].value=val;
  5864. return 0;
  5865. }
  5866. }
  5867. if(sd->status.global_reg_num<GLOBAL_REG_NUM){
  5868. strcpy(sd->status.global_reg[i].str,reg);
  5869. sd->status.global_reg[i].value=val;
  5870. sd->status.global_reg_num++;
  5871. return 0;
  5872. }
  5873. if(battle_config.error_log)
  5874. printf("pc_setglobalreg : couldn't set %s (GLOBAL_REG_NUM = %d)\n", reg, GLOBAL_REG_NUM);
  5875. return 1;
  5876. }
  5877. /*==========================================
  5878. * script用アカウント??の値を?む
  5879. *------------------------------------------
  5880. */
  5881. int pc_readaccountreg(struct map_session_data *sd,char *reg)
  5882. {
  5883. int i;
  5884. nullpo_retr(0, sd);
  5885. for(i=0;i<sd->status.account_reg_num;i++){
  5886. if(strcmp(sd->status.account_reg[i].str,reg)==0)
  5887. return sd->status.account_reg[i].value;
  5888. }
  5889. return 0;
  5890. }
  5891. /*==========================================
  5892. * script用アカウント??の値を設定
  5893. *------------------------------------------
  5894. */
  5895. int pc_setaccountreg(struct map_session_data *sd,char *reg,int val)
  5896. {
  5897. int i;
  5898. nullpo_retr(0, sd);
  5899. if (sd->status.account_reg_num == -1) {
  5900. if(battle_config.error_log)
  5901. printf("pc_setaccountreg : refusing to set until vars are received\n");
  5902. return 1;
  5903. }
  5904. if(val==0){
  5905. for(i=0;i<sd->status.account_reg_num;i++){
  5906. if(strcmp(sd->status.account_reg[i].str,reg)==0){
  5907. sd->status.account_reg[i]=sd->status.account_reg[sd->status.account_reg_num-1];
  5908. sd->status.account_reg_num--;
  5909. break;
  5910. }
  5911. }
  5912. intif_saveaccountreg(sd);
  5913. return 0;
  5914. }
  5915. for(i=0;i<sd->status.account_reg_num;i++){
  5916. if(strcmp(sd->status.account_reg[i].str,reg)==0){
  5917. sd->status.account_reg[i].value=val;
  5918. intif_saveaccountreg(sd);
  5919. return 0;
  5920. }
  5921. }
  5922. if(sd->status.account_reg_num<ACCOUNT_REG_NUM){
  5923. strcpy(sd->status.account_reg[i].str,reg);
  5924. sd->status.account_reg[i].value=val;
  5925. sd->status.account_reg_num++;
  5926. intif_saveaccountreg(sd);
  5927. return 0;
  5928. }
  5929. if(battle_config.error_log)
  5930. printf("pc_setaccountreg : couldn't set %s (ACCOUNT_REG_NUM = %d)\n", reg, ACCOUNT_REG_NUM);
  5931. return 1;
  5932. }
  5933. /*==========================================
  5934. * script用アカウント??2の値を?む
  5935. *------------------------------------------
  5936. */
  5937. int pc_readaccountreg2(struct map_session_data *sd,char *reg)
  5938. {
  5939. int i;
  5940. nullpo_retr(0, sd);
  5941. for(i=0;i<sd->status.account_reg2_num;i++){
  5942. if(strcmp(sd->status.account_reg2[i].str,reg)==0)
  5943. return sd->status.account_reg2[i].value;
  5944. }
  5945. return 0;
  5946. }
  5947. /*==========================================
  5948. * script用アカウント??2の値を設定
  5949. *------------------------------------------
  5950. */
  5951. int pc_setaccountreg2(struct map_session_data *sd,char *reg,int val)
  5952. {
  5953. int i;
  5954. nullpo_retr(1, sd);
  5955. if(val==0){
  5956. for(i=0;i<sd->status.account_reg2_num;i++){
  5957. if(strcmp(sd->status.account_reg2[i].str,reg)==0){
  5958. sd->status.account_reg2[i]=sd->status.account_reg2[sd->status.account_reg2_num-1];
  5959. sd->status.account_reg2_num--;
  5960. break;
  5961. }
  5962. }
  5963. chrif_saveaccountreg2(sd);
  5964. return 0;
  5965. }
  5966. for(i=0;i<sd->status.account_reg2_num;i++){
  5967. if(strcmp(sd->status.account_reg2[i].str,reg)==0){
  5968. sd->status.account_reg2[i].value=val;
  5969. chrif_saveaccountreg2(sd);
  5970. return 0;
  5971. }
  5972. }
  5973. if(sd->status.account_reg2_num<ACCOUNT_REG2_NUM){
  5974. strcpy(sd->status.account_reg2[i].str,reg);
  5975. sd->status.account_reg2[i].value=val;
  5976. sd->status.account_reg2_num++;
  5977. chrif_saveaccountreg2(sd);
  5978. return 0;
  5979. }
  5980. if(battle_config.error_log)
  5981. printf("pc_setaccountreg2 : couldn't set %s (ACCOUNT_REG2_NUM = %d)\n", reg, ACCOUNT_REG2_NUM);
  5982. return 1;
  5983. }
  5984. /*==========================================
  5985. * 精?成功率
  5986. *------------------------------------------
  5987. */
  5988. int pc_percentrefinery(struct map_session_data *sd,struct item *item)
  5989. {
  5990. int percent;
  5991. nullpo_retr(0, item);
  5992. percent=percentrefinery[itemdb_wlv(item->nameid)][(int)item->refine];
  5993. percent += pc_checkskill(sd,BS_WEAPONRESEARCH); // 武器?究スキル所持
  5994. // 確率の有?範?チェック
  5995. if( percent > 100 ){
  5996. percent = 100;
  5997. }
  5998. if( percent < 0 ){
  5999. percent = 0;
  6000. }
  6001. return percent;
  6002. }
  6003. /*==========================================
  6004. * イベントタイマ??理
  6005. *------------------------------------------
  6006. */
  6007. int pc_eventtimer(int tid,unsigned int tick,int id,int data)
  6008. {
  6009. struct map_session_data *sd=map_id2sd(id);
  6010. int i;
  6011. if(sd==NULL)
  6012. return 0;
  6013. for(i=0;i<MAX_EVENTTIMER;i++){
  6014. if( sd->eventtimer[i]==tid ){
  6015. sd->eventtimer[i]=-1;
  6016. npc_event(sd,(const char *)data,0);
  6017. break;
  6018. }
  6019. }
  6020. free((void *)data);
  6021. if(i==MAX_EVENTTIMER) {
  6022. if(battle_config.error_log)
  6023. printf("pc_eventtimer: no such event timer\n");
  6024. }
  6025. return 0;
  6026. }
  6027. /*==========================================
  6028. * イベントタイマ?追加
  6029. *------------------------------------------
  6030. */
  6031. int pc_addeventtimer(struct map_session_data *sd,int tick,const char *name)
  6032. {
  6033. int i;
  6034. nullpo_retr(0, sd);
  6035. Assert(strlen(name) < 24);
  6036. for(i=0;i<MAX_EVENTTIMER;i++)
  6037. if( sd->eventtimer[i]==-1 )
  6038. break;
  6039. if(i<MAX_EVENTTIMER){
  6040. char *evname=(char *)aCalloc(24,sizeof(char));
  6041. memcpy(evname,name,24);
  6042. sd->eventtimer[i]=add_timer(gettick()+tick,
  6043. pc_eventtimer,sd->bl.id,(int)evname);
  6044. sd->eventcount++;
  6045. }
  6046. return 0;
  6047. }
  6048. /*==========================================
  6049. * イベントタイマ?削除
  6050. *------------------------------------------
  6051. */
  6052. int pc_deleventtimer(struct map_session_data *sd,const char *name)
  6053. {
  6054. int i;
  6055. nullpo_retr(0, sd);
  6056. if (sd->eventcount <= 0)
  6057. return 0;
  6058. for(i=0;i<MAX_EVENTTIMER;i++)
  6059. if( sd->eventtimer[i]!=-1 && strcmp(
  6060. (char *)(get_timer(sd->eventtimer[i])->data), name)==0 ){
  6061. delete_timer(sd->eventtimer[i],pc_eventtimer);
  6062. sd->eventtimer[i]=-1;
  6063. sd->eventcount--;
  6064. break;
  6065. }
  6066. return 0;
  6067. }
  6068. /*==========================================
  6069. * イベントタイマ?カウント値追加
  6070. *------------------------------------------
  6071. */
  6072. int pc_addeventtimercount(struct map_session_data *sd,const char *name,int tick)
  6073. {
  6074. int i;
  6075. nullpo_retr(0, sd);
  6076. for(i=0;i<MAX_EVENTTIMER;i++)
  6077. if( sd->eventtimer[i]!=-1 && strcmp(
  6078. (char *)(get_timer(sd->eventtimer[i])->data), name)==0 ){
  6079. addtick_timer(sd->eventtimer[i],tick);
  6080. break;
  6081. }
  6082. return 0;
  6083. }
  6084. /*==========================================
  6085. * イベントタイマ?全削除
  6086. *------------------------------------------
  6087. */
  6088. int pc_cleareventtimer(struct map_session_data *sd)
  6089. {
  6090. int i;
  6091. nullpo_retr(0, sd);
  6092. if (sd->eventcount <= 0)
  6093. return 0;
  6094. for(i=0;i<MAX_EVENTTIMER;i++)
  6095. if( sd->eventtimer[i]!=-1 ){
  6096. delete_timer(sd->eventtimer[i],pc_eventtimer);
  6097. sd->eventtimer[i]=-1;
  6098. }
  6099. return 0;
  6100. }
  6101. //
  6102. // ? 備物
  6103. //
  6104. /*==========================================
  6105. * アイテムを?備する
  6106. *------------------------------------------
  6107. */
  6108. int pc_equipitem(struct map_session_data *sd,int n,int pos)
  6109. {
  6110. int i,nameid, arrow;
  6111. struct item_data *id;
  6112. //?生や養子の場合の元の職業を算出する
  6113. nullpo_retr(0, sd);
  6114. nameid = sd->status.inventory[n].nameid;
  6115. id = sd->inventory_data[n];
  6116. pos = pc_equippoint(sd,n);
  6117. if(battle_config.battle_log)
  6118. printf("equip %d(%d) %x:%x\n",nameid,n,id->equip,pos);
  6119. if(!pc_isequip(sd,n) || !pos || sd->status.inventory[n].attribute==1 ) { // [Valaris]
  6120. clif_equipitemack(sd,n,0,0); // fail
  6121. return 0;
  6122. }
  6123. // -- moonsoul (if player is berserk then cannot equip)
  6124. //
  6125. if(sd->sc_count && sd->sc_data[SC_BERSERK].timer!=-1){
  6126. clif_equipitemack(sd,n,0,0); // fail
  6127. return 0;
  6128. }
  6129. if(pos==0x88){ // アクセサリ用例外?理
  6130. int epor=0;
  6131. if(sd->equip_index[0] >= 0)
  6132. epor |= sd->status.inventory[sd->equip_index[0]].equip;
  6133. if(sd->equip_index[1] >= 0)
  6134. epor |= sd->status.inventory[sd->equip_index[1]].equip;
  6135. epor &= 0x88;
  6136. pos = epor == 0x08 ? 0x80 : 0x08;
  6137. }
  6138. // 二刀流?理
  6139. if ((pos==0x22) // 一?、?備要求箇所が二刀流武器かチェックする
  6140. && (id->equip==2) // ? 手武器
  6141. && (pc_checkskill(sd, AS_LEFT) > 0 || pc_calc_base_job2(sd->status.class_) == 12) ) // 左手修?有
  6142. {
  6143. int tpos=0;
  6144. if(sd->equip_index[8] >= 0)
  6145. tpos |= sd->status.inventory[sd->equip_index[8]].equip;
  6146. if(sd->equip_index[9] >= 0)
  6147. tpos |= sd->status.inventory[sd->equip_index[9]].equip;
  6148. tpos &= 0x02;
  6149. pos = tpos == 0x02 ? 0x20 : 0x02;
  6150. }
  6151. arrow=pc_search_inventory(sd,pc_checkequip(sd,9)); // Added by RoVeRT
  6152. for(i=0;i<11;i++) {
  6153. if(sd->equip_index[i] >= 0 && sd->status.inventory[sd->equip_index[i]].equip&pos) {
  6154. pc_unequipitem(sd,sd->equip_index[i],2);
  6155. }
  6156. }
  6157. // 弓矢?備
  6158. if(pos==0x8000){
  6159. clif_arrowequip(sd,n);
  6160. clif_arrow_fail(sd,3); // 3=矢が?備できました
  6161. }
  6162. else
  6163. clif_equipitemack(sd,n,pos,1);
  6164. for(i=0;i<11;i++) {
  6165. if(pos & equip_pos[i])
  6166. sd->equip_index[i] = n;
  6167. }
  6168. sd->status.inventory[n].equip=pos;
  6169. if(sd->status.inventory[n].equip & 0x0002) {
  6170. if(sd->inventory_data[n])
  6171. sd->weapontype1 = sd->inventory_data[n]->look;
  6172. else
  6173. sd->weapontype1 = 0;
  6174. pc_calcweapontype(sd);
  6175. clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
  6176. }
  6177. if(sd->status.inventory[n].equip & 0x0020) {
  6178. if(sd->inventory_data[n]) {
  6179. if(sd->inventory_data[n]->type == 4) {
  6180. sd->status.shield = 0;
  6181. if(sd->status.inventory[n].equip == 0x0020)
  6182. sd->weapontype2 = sd->inventory_data[n]->look;
  6183. else
  6184. sd->weapontype2 = 0;
  6185. }
  6186. else if(sd->inventory_data[n]->type == 5) {
  6187. sd->status.shield = sd->inventory_data[n]->look;
  6188. sd->weapontype2 = 0;
  6189. }
  6190. }
  6191. else
  6192. sd->status.shield = sd->weapontype2 = 0;
  6193. pc_calcweapontype(sd);
  6194. clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
  6195. }
  6196. if(sd->status.inventory[n].equip & 0x0001) {
  6197. if(sd->inventory_data[n])
  6198. sd->status.head_bottom = sd->inventory_data[n]->look;
  6199. else
  6200. sd->status.head_bottom = 0;
  6201. clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
  6202. }
  6203. if(sd->status.inventory[n].equip & 0x0100) {
  6204. if(sd->inventory_data[n])
  6205. sd->status.head_top = sd->inventory_data[n]->look;
  6206. else
  6207. sd->status.head_top = 0;
  6208. clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
  6209. }
  6210. if(sd->status.inventory[n].equip & 0x0200) {
  6211. if(sd->inventory_data[n])
  6212. sd->status.head_mid = sd->inventory_data[n]->look;
  6213. else
  6214. sd->status.head_mid = 0;
  6215. clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
  6216. }
  6217. if(sd->status.inventory[n].equip & 0x0040)
  6218. clif_changelook(&sd->bl,LOOK_SHOES,0);
  6219. pc_checkallowskill(sd); // ?備品でスキルか解除されるかチェック
  6220. if (itemdb_look(sd->status.inventory[n].nameid) == 11 && (arrow >= 0)){ // Added by RoVeRT
  6221. clif_arrowequip(sd,arrow);
  6222. sd->status.inventory[arrow].equip=32768;
  6223. }
  6224. pc_calcstatus(sd,0);
  6225. if(sd->special_state.infinite_endure) {
  6226. if(sd->sc_data[SC_ENDURE].timer == -1)
  6227. skill_status_change_start(&sd->bl,SC_ENDURE,10,1,0,0,0,0);
  6228. }
  6229. else {
  6230. if(sd->sc_count && sd->sc_data[SC_ENDURE].timer != -1 && sd->sc_data[SC_ENDURE].val2)
  6231. skill_status_change_end(&sd->bl,SC_ENDURE,-1);
  6232. }
  6233. if(sd->sc_count) {
  6234. if (sd->sc_data[SC_SIGNUMCRUCIS].timer != -1 && !battle_check_undead(7,sd->def_ele))
  6235. skill_status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1);
  6236. if(sd->sc_data[SC_DANCING].timer!=-1 && (sd->status.weapon != 13 && sd->status.weapon !=14))
  6237. skill_stop_dancing(&sd->bl,0);
  6238. }
  6239. return 0;
  6240. }
  6241. /*==========================================
  6242. * ? 備した物を外す
  6243. * type:
  6244. * 0 - only unequip
  6245. * 1 - calculate status after unequipping
  6246. * 2 - force unequip
  6247. *------------------------------------------
  6248. */
  6249. int pc_unequipitem(struct map_session_data *sd,int n,int flag)
  6250. {
  6251. nullpo_retr(0, sd);
  6252. // -- moonsoul (if player is berserk then cannot unequip)
  6253. //
  6254. if(flag<2 && sd->sc_count && (sd->sc_data[SC_BLADESTOP].timer!=-1 || sd->sc_data[SC_BERSERK].timer!=-1)){
  6255. clif_unequipitemack(sd,n,0,0);
  6256. return 0;
  6257. }
  6258. if(battle_config.battle_log)
  6259. printf("unequip %d %x:%x\n",n,pc_equippoint(sd,n),sd->status.inventory[n].equip);
  6260. if(sd->status.inventory[n].equip){
  6261. int i;
  6262. for(i=0;i<11;i++) {
  6263. if(sd->status.inventory[n].equip & equip_pos[i])
  6264. sd->equip_index[i] = -1;
  6265. }
  6266. if(sd->status.inventory[n].equip & 0x0002) {
  6267. sd->weapontype1 = 0;
  6268. sd->status.weapon = sd->weapontype2;
  6269. pc_calcweapontype(sd);
  6270. clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
  6271. }
  6272. if(sd->status.inventory[n].equip & 0x0020) {
  6273. sd->status.shield = sd->weapontype2 = 0;
  6274. pc_calcweapontype(sd);
  6275. clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
  6276. }
  6277. if(sd->status.inventory[n].equip & 0x0001) {
  6278. sd->status.head_bottom = 0;
  6279. clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
  6280. }
  6281. if(sd->status.inventory[n].equip & 0x0100) {
  6282. sd->status.head_top = 0;
  6283. clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
  6284. }
  6285. if(sd->status.inventory[n].equip & 0x0200) {
  6286. sd->status.head_mid = 0;
  6287. clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
  6288. }
  6289. if(sd->status.inventory[n].equip & 0x0040)
  6290. clif_changelook(&sd->bl,LOOK_SHOES,0);
  6291. if(sd->sc_count) {
  6292. if (sd->sc_data[SC_BROKNWEAPON].timer != -1 && sd->status.inventory[n].equip & 0x0002 &&
  6293. sd->status.inventory[n].attribute == 1)
  6294. skill_status_change_end(&sd->bl,SC_BROKNWEAPON,-1);
  6295. if(sd->sc_data[SC_BROKNARMOR].timer != -1 && sd->status.inventory[n].equip & 0x0010 &&
  6296. sd->status.inventory[n].attribute == 1)
  6297. skill_status_change_end(&sd->bl,SC_BROKNARMOR,-1);
  6298. }
  6299. clif_unequipitemack(sd,n,sd->status.inventory[n].equip,1);
  6300. sd->status.inventory[n].equip=0;
  6301. if(flag&1)
  6302. pc_checkallowskill(sd);
  6303. if(sd->weapontype1 == 0 && sd->weapontype2 == 0)
  6304. skill_encchant_eremental_end(&sd->bl,-1); //武器持ち誓えは無?件で?性付?解除
  6305. } else {
  6306. clif_unequipitemack(sd,n,0,0);
  6307. }
  6308. if(flag&1) {
  6309. pc_calcstatus(sd,0);
  6310. if(sd->sc_count && sd->sc_data[SC_SIGNUMCRUCIS].timer != -1 && !battle_check_undead(7,sd->def_ele))
  6311. skill_status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1);
  6312. }
  6313. return 0;
  6314. }
  6315. /*==========================================
  6316. * アイテムのindex番?を詰めたり
  6317. * ? 備品の?備可能チェックを行なう
  6318. *------------------------------------------
  6319. */
  6320. int pc_checkitem(struct map_session_data *sd)
  6321. {
  6322. int i,j,k,id,calc_flag = 0;
  6323. struct item_data *it=NULL;
  6324. nullpo_retr(0, sd);
  6325. // 所持品空き詰め
  6326. for(i=j=0;i<MAX_INVENTORY;i++){
  6327. if( (id=sd->status.inventory[i].nameid)==0)
  6328. continue;
  6329. if( battle_config.item_check && !itemdb_available(id) ){
  6330. if(battle_config.error_log)
  6331. printf("illeagal item id %d in %d[%s] inventory.\n",id,sd->bl.id,sd->status.name);
  6332. pc_delitem(sd,i,sd->status.inventory[i].amount,3);
  6333. continue;
  6334. }
  6335. if(i>j){
  6336. memcpy(&sd->status.inventory[j],&sd->status.inventory[i],sizeof(struct item));
  6337. sd->inventory_data[j] = sd->inventory_data[i];
  6338. }
  6339. j++;
  6340. }
  6341. if(j < MAX_INVENTORY)
  6342. memset(&sd->status.inventory[j],0,sizeof(struct item)*(MAX_INVENTORY-j));
  6343. for(k=j;k<MAX_INVENTORY;k++)
  6344. sd->inventory_data[k] = NULL;
  6345. // カ?ト?空き詰め
  6346. for(i=j=0;i<MAX_CART;i++){
  6347. if( (id=sd->status.cart[i].nameid)==0 )
  6348. continue;
  6349. if( battle_config.item_check && !itemdb_available(id) ){
  6350. if(battle_config.error_log)
  6351. printf("illeagal item id %d in %d[%s] cart.\n",id,sd->bl.id,sd->status.name);
  6352. pc_cart_delitem(sd,i,sd->status.cart[i].amount,1);
  6353. continue;
  6354. }
  6355. if(i>j){
  6356. memcpy(&sd->status.cart[j],&sd->status.cart[i],sizeof(struct item));
  6357. }
  6358. j++;
  6359. }
  6360. if(j < MAX_CART)
  6361. memset(&sd->status.cart[j],0,sizeof(struct item)*(MAX_CART-j));
  6362. // ? 備位置チェック
  6363. for(i=0;i<MAX_INVENTORY;i++){
  6364. it=sd->inventory_data[i];
  6365. if(sd->status.inventory[i].nameid==0)
  6366. continue;
  6367. if(sd->status.inventory[i].equip & ~pc_equippoint(sd,i)) {
  6368. sd->status.inventory[i].equip=0;
  6369. calc_flag = 1;
  6370. }
  6371. //?備制限チェック
  6372. if(sd->status.inventory[i].equip && map[sd->bl.m].flag.pvp && (it->flag.no_equip==1 || it->flag.no_equip==3)){//PvP制限
  6373. sd->status.inventory[i].equip=0;
  6374. calc_flag = 1;
  6375. }else if(sd->status.inventory[i].equip && map[sd->bl.m].flag.gvg && (it->flag.no_equip==2 || it->flag.no_equip==3)){//GvG制限
  6376. sd->status.inventory[i].equip=0;
  6377. calc_flag = 1;
  6378. }
  6379. }
  6380. pc_setequipindex(sd);
  6381. if(calc_flag)
  6382. pc_calcstatus(sd,2);
  6383. return 0;
  6384. }
  6385. int pc_checkoverhp(struct map_session_data *sd)
  6386. {
  6387. nullpo_retr(0, sd);
  6388. if(sd->status.hp == sd->status.max_hp)
  6389. return 1;
  6390. if(sd->status.hp > sd->status.max_hp) {
  6391. sd->status.hp = sd->status.max_hp;
  6392. clif_updatestatus(sd,SP_HP);
  6393. return 2;
  6394. }
  6395. return 0;
  6396. }
  6397. int pc_checkoversp(struct map_session_data *sd)
  6398. {
  6399. nullpo_retr(0, sd);
  6400. if(sd->status.sp == sd->status.max_sp)
  6401. return 1;
  6402. if(sd->status.sp > sd->status.max_sp) {
  6403. sd->status.sp = sd->status.max_sp;
  6404. clif_updatestatus(sd,SP_SP);
  6405. return 2;
  6406. }
  6407. return 0;
  6408. }
  6409. /*==========================================
  6410. * PVP順位計算用(foreachinarea)
  6411. *------------------------------------------
  6412. */
  6413. int pc_calc_pvprank_sub(struct block_list *bl,va_list ap)
  6414. {
  6415. struct map_session_data *sd1,*sd2=NULL;
  6416. nullpo_retr(0, bl);
  6417. nullpo_retr(0, ap);
  6418. nullpo_retr(0, sd1=(struct map_session_data *)bl);
  6419. nullpo_retr(0, sd2=va_arg(ap,struct map_session_data *));
  6420. if( sd1->pvp_point > sd2->pvp_point )
  6421. sd2->pvp_rank++;
  6422. return 0;
  6423. }
  6424. /*==========================================
  6425. * PVP順位計算
  6426. *------------------------------------------
  6427. */
  6428. int pc_calc_pvprank(struct map_session_data *sd)
  6429. {
  6430. int old;
  6431. struct map_data *m;
  6432. nullpo_retr(0, sd);
  6433. nullpo_retr(0, m=&map[sd->bl.m]);
  6434. old=sd->pvp_rank;
  6435. if( !(m->flag.pvp) )
  6436. return 0;
  6437. sd->pvp_rank=1;
  6438. map_foreachinarea(pc_calc_pvprank_sub,sd->bl.m,0,0,m->xs,m->ys,BL_PC,sd);
  6439. if(old!=sd->pvp_rank || sd->pvp_lastusers!=m->users)
  6440. clif_pvpset(sd,sd->pvp_rank,sd->pvp_lastusers=m->users,0);
  6441. return sd->pvp_rank;
  6442. }
  6443. /*==========================================
  6444. * PVP順位計算(timer)
  6445. *------------------------------------------
  6446. */
  6447. int pc_calc_pvprank_timer(int tid,unsigned int tick,int id,int data)
  6448. {
  6449. struct map_session_data *sd=NULL;
  6450. if(battle_config.pk_mode) // disable pvp ranking if pk_mode on [Valaris]
  6451. return 0;
  6452. sd=map_id2sd(id);
  6453. if(sd==NULL)
  6454. return 0;
  6455. sd->pvp_timer=-1;
  6456. if( pc_calc_pvprank(sd)>0 )
  6457. sd->pvp_timer=add_timer(
  6458. gettick()+PVP_CALCRANK_INTERVAL,
  6459. pc_calc_pvprank_timer,id,data);
  6460. return 0;
  6461. }
  6462. /*==========================================
  6463. * sdは結婚しているか(?婚の場合は相方のchar_idを返す)
  6464. *------------------------------------------
  6465. */
  6466. int pc_ismarried(struct map_session_data *sd)
  6467. {
  6468. if(sd == NULL)
  6469. return -1;
  6470. if(sd->status.partner_id > 0)
  6471. return sd->status.partner_id;
  6472. else
  6473. return 0;
  6474. }
  6475. /*==========================================
  6476. * sdがdstsdと結婚(dstsd→sdの結婚?理も同暫ノ行う)
  6477. *------------------------------------------
  6478. */
  6479. int pc_marriage(struct map_session_data *sd,struct map_session_data *dstsd)
  6480. {
  6481. if(sd == NULL || dstsd == NULL || sd->status.partner_id > 0 || dstsd->status.partner_id > 0 || pc_calc_upper(sd->status.class_)==2)
  6482. return -1;
  6483. sd->status.partner_id=dstsd->status.char_id;
  6484. dstsd->status.partner_id=sd->status.char_id;
  6485. return 0;
  6486. }
  6487. /*==========================================
  6488. * sdが離婚(相手はsd->status.partner_idに依る)(相手も同暫ノ離婚?結婚指輪自動?奪)
  6489. *------------------------------------------
  6490. */
  6491. int pc_divorce(struct map_session_data *sd)
  6492. {
  6493. struct map_session_data *p_sd=NULL;
  6494. if(sd == NULL || !pc_ismarried(sd))
  6495. return -1;
  6496. if( (p_sd=map_nick2sd(map_charid2nick(sd->status.partner_id))) !=NULL){
  6497. int i;
  6498. if(p_sd->status.partner_id != sd->status.char_id || sd->status.partner_id != p_sd->status.char_id){
  6499. printf("pc_divorce: Illegal partner_id sd=%d p_sd=%d\n",sd->status.partner_id,p_sd->status.partner_id);
  6500. return -1;
  6501. }
  6502. sd->status.partner_id=0;
  6503. p_sd->status.partner_id=0;
  6504. for(i=0;i<MAX_INVENTORY;i++)
  6505. if(sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F)
  6506. pc_delitem(sd,i,1,0);
  6507. for(i=0;i<MAX_INVENTORY;i++)
  6508. if(p_sd->status.inventory[i].nameid == WEDDING_RING_M || p_sd->status.inventory[i].nameid == WEDDING_RING_F)
  6509. pc_delitem(p_sd,i,1,0);
  6510. }else{
  6511. printf("pc_divorce: p_sd nullpo\n");
  6512. return -1;
  6513. }
  6514. return 0;
  6515. }
  6516. /*==========================================
  6517. * sdの相方のmap_session_dataを返す
  6518. *------------------------------------------
  6519. */
  6520. struct map_session_data *pc_get_partner(struct map_session_data *sd)
  6521. {
  6522. struct map_session_data *p_sd = NULL;
  6523. char *nick;
  6524. if(sd == NULL || !pc_ismarried(sd))
  6525. return NULL;
  6526. nick=map_charid2nick(sd->status.partner_id);
  6527. if (nick==NULL)
  6528. return NULL;
  6529. if((p_sd=map_nick2sd(nick)) == NULL )
  6530. return NULL;
  6531. return p_sd;
  6532. }
  6533. //
  6534. // 自然回復物
  6535. //
  6536. /*==========================================
  6537. * SP回復量計算
  6538. *------------------------------------------
  6539. */
  6540. static int natural_heal_tick,natural_heal_prev_tick,natural_heal_diff_tick;
  6541. static int pc_spheal(struct map_session_data *sd)
  6542. {
  6543. int a, skill;
  6544. struct guild_castle *gc = NULL;
  6545. nullpo_retr(0, sd);
  6546. a = natural_heal_diff_tick;
  6547. if(pc_issit(sd)) a += a;
  6548. if (sd->sc_count) {
  6549. if (sd->sc_data[SC_MAGNIFICAT].timer!=-1) // マグニフィカ?ト
  6550. a += a;
  6551. if (sd->sc_data[SC_REGENERATION].timer != -1)
  6552. a *= sd->sc_data[SC_REGENERATION].val1;
  6553. }
  6554. if((skill = pc_checkskill(sd,HP_MEDITATIO)) > 0) //Increase natural SP regen with Meditatio [DracoRPG]
  6555. a += a*skill*3/100;
  6556. gc=guild_mapname2gc(sd->mapname); // Increased guild castle regen [Valaris]
  6557. if(gc) {
  6558. struct guild *g;
  6559. g=guild_search(sd->status.guild_id);
  6560. if(g && g->guild_id == gc->guild_id)
  6561. a += a;
  6562. } // end addition [Valaris]
  6563. return a;
  6564. }
  6565. /*==========================================
  6566. * HP回復量計算
  6567. *------------------------------------------
  6568. */
  6569. static int pc_hpheal(struct map_session_data *sd)
  6570. {
  6571. int a;
  6572. struct guild_castle *gc;
  6573. nullpo_retr(0, sd);
  6574. a = natural_heal_diff_tick;
  6575. if(pc_issit(sd)) a += a;
  6576. if (sd->sc_count) {
  6577. if( sd->sc_data[SC_MAGNIFICAT].timer!=-1 ) // Modified by RoVeRT
  6578. a += a;
  6579. if (sd->sc_data[SC_REGENERATION].timer != -1)
  6580. a *= sd->sc_data[SC_REGENERATION].val1;
  6581. }
  6582. gc=guild_mapname2gc(sd->mapname); // Increased guild castle regen [Valaris]
  6583. if(gc) {
  6584. struct guild *g;
  6585. g=guild_search(sd->status.guild_id);
  6586. if(g && g->guild_id == gc->guild_id)
  6587. a += a;
  6588. } // end addition [Valaris]
  6589. return a;
  6590. }
  6591. static int pc_natural_heal_hp(struct map_session_data *sd)
  6592. {
  6593. int bhp;
  6594. int inc_num,bonus,skill,hp_flag;
  6595. nullpo_retr(0, sd);
  6596. if (sd->sc_count && sd->sc_data[SC_TRICKDEAD].timer != -1) // Modified by RoVeRT
  6597. return 0;
  6598. if(pc_checkoverhp(sd)) {
  6599. sd->hp_sub = sd->inchealhptick = 0;
  6600. return 0;
  6601. }
  6602. bhp=sd->status.hp;
  6603. hp_flag = (pc_checkskill(sd,SM_MOVINGRECOVERY) > 0 && sd->walktimer != -1);
  6604. if(sd->walktimer == -1) {
  6605. inc_num = pc_hpheal(sd);
  6606. if(sd->sc_data[SC_TENSIONRELAX].timer!=-1 ){ // テンションリラックス
  6607. sd->hp_sub += 2*inc_num;
  6608. sd->inchealhptick += 3*natural_heal_diff_tick;
  6609. } else {
  6610. sd->hp_sub += inc_num;
  6611. sd->inchealhptick += natural_heal_diff_tick;
  6612. }
  6613. }
  6614. else if(hp_flag) {
  6615. inc_num = pc_hpheal(sd);
  6616. sd->hp_sub += inc_num;
  6617. sd->inchealhptick = 0;
  6618. }
  6619. else {
  6620. sd->hp_sub = sd->inchealhptick = 0;
  6621. return 0;
  6622. }
  6623. if(sd->hp_sub >= battle_config.natural_healhp_interval) {
  6624. bonus = sd->nhealhp;
  6625. if(hp_flag) {
  6626. bonus >>= 2;
  6627. if(bonus <= 0) bonus = 1;
  6628. }
  6629. while(sd->hp_sub >= battle_config.natural_healhp_interval) {
  6630. sd->hp_sub -= battle_config.natural_healhp_interval;
  6631. if(sd->status.hp + bonus <= sd->status.max_hp)
  6632. sd->status.hp += bonus;
  6633. else {
  6634. sd->status.hp = sd->status.max_hp;
  6635. sd->hp_sub = sd->inchealhptick = 0;
  6636. }
  6637. }
  6638. }
  6639. if(bhp!=sd->status.hp)
  6640. clif_updatestatus(sd,SP_HP);
  6641. if(sd->nshealhp > 0) {
  6642. if(sd->inchealhptick >= battle_config.natural_heal_skill_interval && sd->status.hp < sd->status.max_hp) {
  6643. bonus = sd->nshealhp;
  6644. while(sd->inchealhptick >= battle_config.natural_heal_skill_interval) {
  6645. sd->inchealhptick -= battle_config.natural_heal_skill_interval;
  6646. if(sd->status.hp + bonus <= sd->status.max_hp)
  6647. sd->status.hp += bonus;
  6648. else {
  6649. bonus = sd->status.max_hp - sd->status.hp;
  6650. sd->status.hp = sd->status.max_hp;
  6651. sd->hp_sub = sd->inchealhptick = 0;
  6652. }
  6653. clif_heal(sd->fd,SP_HP,bonus);
  6654. }
  6655. }
  6656. }
  6657. else sd->inchealhptick = 0;
  6658. return 0;
  6659. if(sd->sc_count && sd->sc_data[SC_APPLEIDUN].timer!=-1 && sd->sc_data[SC_BERSERK].timer==-1) { // Apple of Idun
  6660. if(sd->inchealhptick >= 6000 && sd->status.hp < sd->status.max_hp) {
  6661. bonus = skill*20;
  6662. while(sd->inchealhptick >= 6000) {
  6663. sd->inchealhptick -= 6000;
  6664. if(sd->status.hp + bonus <= sd->status.max_hp)
  6665. sd->status.hp += bonus;
  6666. else {
  6667. bonus = sd->status.max_hp - sd->status.hp;
  6668. sd->status.hp = sd->status.max_hp;
  6669. sd->hp_sub = sd->inchealhptick = 0;
  6670. }
  6671. clif_heal(sd->fd,SP_HP,bonus);
  6672. }
  6673. }
  6674. }
  6675. else sd->inchealhptick = 0;
  6676. return 0;
  6677. }
  6678. static int pc_natural_heal_sp(struct map_session_data *sd)
  6679. {
  6680. int bsp;
  6681. int inc_num,bonus;
  6682. nullpo_retr(0, sd);
  6683. if (sd->sc_count && (sd->sc_data[SC_TRICKDEAD].timer != -1 || // Modified by RoVeRT
  6684. sd->sc_data[SC_BERSERK].timer != -1))
  6685. return 0;
  6686. if(pc_checkoversp(sd)) {
  6687. sd->sp_sub = sd->inchealsptick = 0;
  6688. return 0;
  6689. }
  6690. bsp=sd->status.sp;
  6691. inc_num = pc_spheal(sd);
  6692. if(sd->sc_data[SC_EXPLOSIONSPIRITS].timer == -1)
  6693. sd->sp_sub += inc_num;
  6694. if(sd->walktimer == -1)
  6695. sd->inchealsptick += natural_heal_diff_tick;
  6696. else sd->inchealsptick = 0;
  6697. if(sd->sp_sub >= battle_config.natural_healsp_interval){
  6698. bonus = sd->nhealsp;;
  6699. while(sd->sp_sub >= battle_config.natural_healsp_interval){
  6700. sd->sp_sub -= battle_config.natural_healsp_interval;
  6701. if(sd->status.sp + bonus <= sd->status.max_sp)
  6702. sd->status.sp += bonus;
  6703. else {
  6704. sd->status.sp = sd->status.max_sp;
  6705. sd->sp_sub = sd->inchealsptick = 0;
  6706. }
  6707. }
  6708. }
  6709. if(bsp != sd->status.sp)
  6710. clif_updatestatus(sd,SP_SP);
  6711. if(sd->nshealsp > 0) {
  6712. if(sd->inchealsptick >= battle_config.natural_heal_skill_interval && sd->status.sp < sd->status.max_sp) {
  6713. struct pc_base_job s_class = pc_calc_base_job(sd->status.class_);
  6714. if(sd->doridori_counter && s_class.job == 23)
  6715. bonus = sd->nshealsp*2;
  6716. else
  6717. bonus = sd->nshealsp;
  6718. sd->doridori_counter = 0;
  6719. while(sd->inchealsptick >= battle_config.natural_heal_skill_interval) {
  6720. sd->inchealsptick -= battle_config.natural_heal_skill_interval;
  6721. if(sd->status.sp + bonus <= sd->status.max_sp)
  6722. sd->status.sp += bonus;
  6723. else {
  6724. bonus = sd->status.max_sp - sd->status.sp;
  6725. sd->status.sp = sd->status.max_sp;
  6726. sd->sp_sub = sd->inchealsptick = 0;
  6727. }
  6728. clif_heal(sd->fd,SP_SP,bonus);
  6729. }
  6730. }
  6731. }
  6732. else sd->inchealsptick = 0;
  6733. return 0;
  6734. }
  6735. static int pc_spirit_heal_hp(struct map_session_data *sd,int level)
  6736. {
  6737. int bonus_hp,interval = battle_config.natural_heal_skill_interval;
  6738. nullpo_retr(0, sd);
  6739. if(pc_checkoverhp(sd)) {
  6740. sd->inchealspirithptick = 0;
  6741. return 0;
  6742. }
  6743. sd->inchealspirithptick += natural_heal_diff_tick;
  6744. if(sd->weight*100/sd->max_weight >= battle_config.natural_heal_weight_rate)
  6745. interval += interval;
  6746. if(sd->inchealspirithptick >= interval) {
  6747. bonus_hp = sd->nsshealhp;
  6748. while(sd->inchealspirithptick >= interval) {
  6749. if(pc_issit(sd)) {
  6750. sd->inchealspirithptick -= interval;
  6751. if(sd->status.hp < sd->status.max_hp) {
  6752. if(sd->status.hp + bonus_hp <= sd->status.max_hp)
  6753. sd->status.hp += bonus_hp;
  6754. else {
  6755. bonus_hp = sd->status.max_hp - sd->status.hp;
  6756. sd->status.hp = sd->status.max_hp;
  6757. }
  6758. clif_heal(sd->fd,SP_HP,bonus_hp);
  6759. sd->inchealspirithptick = 0;
  6760. }
  6761. }else{
  6762. sd->inchealspirithptick -= natural_heal_diff_tick;
  6763. break;
  6764. }
  6765. }
  6766. }
  6767. return 0;
  6768. }
  6769. static int pc_spirit_heal_sp(struct map_session_data *sd,int level)
  6770. {
  6771. int bonus_sp,interval = battle_config.natural_heal_skill_interval;
  6772. nullpo_retr(0, sd);
  6773. if(pc_checkoversp(sd)) {
  6774. sd->inchealspiritsptick = 0;
  6775. return 0;
  6776. }
  6777. sd->inchealspiritsptick += natural_heal_diff_tick;
  6778. if(sd->weight*100/sd->max_weight >= battle_config.natural_heal_weight_rate)
  6779. interval += interval;
  6780. if(sd->inchealspiritsptick >= interval) {
  6781. bonus_sp = sd->nsshealsp;
  6782. while(sd->inchealspiritsptick >= interval) {
  6783. if(pc_issit(sd)) {
  6784. sd->inchealspiritsptick -= interval;
  6785. if(sd->status.sp < sd->status.max_sp) {
  6786. if(sd->status.sp + bonus_sp <= sd->status.max_sp)
  6787. sd->status.sp += bonus_sp;
  6788. else {
  6789. bonus_sp = sd->status.max_sp - sd->status.sp;
  6790. sd->status.sp = sd->status.max_sp;
  6791. }
  6792. clif_heal(sd->fd,SP_SP,bonus_sp);
  6793. sd->inchealspiritsptick = 0;
  6794. }
  6795. }else{
  6796. sd->inchealspiritsptick -= natural_heal_diff_tick;
  6797. break;
  6798. }
  6799. }
  6800. }
  6801. return 0;
  6802. }
  6803. /*==========================================
  6804. * HP/SP 自然回復 各クライアント
  6805. *------------------------------------------
  6806. */
  6807. static int pc_natural_heal_sub(struct map_session_data *sd,va_list ap) {
  6808. int skill;
  6809. nullpo_retr(0, sd);
  6810. // -- moonsoul (if conditions below altered to disallow natural healing if under berserk status)
  6811. if ((battle_config.natural_heal_weight_rate > 100 || sd->weight*100/sd->max_weight < battle_config.natural_heal_weight_rate) &&
  6812. !pc_isdead(sd) &&
  6813. !pc_ishiding(sd) &&
  6814. //-- cannot regen for 5 minutes after using Berserk --- [Celest]
  6815. DIFF_TICK (gettick(), sd->canregen_tick)>=0 &&
  6816. (sd->sc_data && !(sd->sc_data[SC_POISON].timer != -1 && sd->sc_data[SC_SLOWPOISON].timer == -1) &&
  6817. sd->sc_data[SC_BERSERK].timer == -1 )) {
  6818. pc_natural_heal_hp(sd);
  6819. if( sd->sc_data && sd->sc_data[SC_EXTREMITYFIST].timer == -1 && //阿修羅?態ではSPが回復しない
  6820. sd->sc_data[SC_DANCING].timer == -1 && //ダンス?態ではSPが回復しない
  6821. sd->sc_data[SC_BERSERK].timer == -1 ) //バ?サ?ク?態ではSPが回復しない
  6822. pc_natural_heal_sp(sd);
  6823. sd->canregen_tick = gettick();
  6824. } else {
  6825. sd->hp_sub = sd->inchealhptick = 0;
  6826. sd->sp_sub = sd->inchealsptick = 0;
  6827. }
  6828. if((skill = pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0 && !pc_ishiding(sd) &&
  6829. sd->sc_data[SC_POISON].timer == -1 && sd->sc_data[SC_BERSERK].timer == -1){
  6830. pc_spirit_heal_hp(sd,skill);
  6831. pc_spirit_heal_sp(sd,skill);
  6832. }
  6833. else {
  6834. sd->inchealspirithptick = 0;
  6835. sd->inchealspiritsptick = 0;
  6836. }
  6837. return 0;
  6838. }
  6839. /*==========================================
  6840. * HP/SP自然回復 (interval timer??)
  6841. *------------------------------------------
  6842. */
  6843. int pc_natural_heal(int tid,unsigned int tick,int id,int data)
  6844. {
  6845. natural_heal_tick = tick;
  6846. natural_heal_diff_tick = DIFF_TICK(natural_heal_tick,natural_heal_prev_tick);
  6847. clif_foreachclient(pc_natural_heal_sub);
  6848. natural_heal_prev_tick = tick;
  6849. return 0;
  6850. }
  6851. /*==========================================
  6852. * セ?ブポイントの保存
  6853. *------------------------------------------
  6854. */
  6855. int pc_setsavepoint(struct map_session_data *sd,char *mapname,int x,int y)
  6856. {
  6857. nullpo_retr(0, sd);
  6858. strncpy(sd->status.save_point.map,mapname,24);
  6859. sd->status.save_point.x = x;
  6860. sd->status.save_point.y = y;
  6861. return 0;
  6862. }
  6863. /*==========================================
  6864. * 自動セ?ブ 各クライアント
  6865. *------------------------------------------
  6866. */
  6867. static int last_save_fd,save_flag;
  6868. static int pc_autosave_sub(struct map_session_data *sd,va_list ap)
  6869. {
  6870. nullpo_retr(0, sd);
  6871. Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd);
  6872. if(save_flag==0 && sd->fd>last_save_fd){
  6873. struct guild_castle *gc=NULL;
  6874. int i;
  6875. // if(battle_config.save_log)
  6876. // printf("autosave %d\n",sd->fd);
  6877. // pet
  6878. if(sd->status.pet_id > 0 && sd->pd)
  6879. intif_save_petdata(sd->status.account_id,&sd->pet);
  6880. pc_makesavestatus(sd);
  6881. chrif_save(sd);
  6882. storage_storage_save(sd);
  6883. for(i=0;i<MAX_GUILDCASTLE;i++){
  6884. gc=guild_castle_search(i);
  6885. if(!gc) continue;
  6886. if(gc->visibleG0==1) guild_castledatasave(gc->castle_id,18,gc->Ghp0);
  6887. if(gc->visibleG1==1) guild_castledatasave(gc->castle_id,19,gc->Ghp1);
  6888. if(gc->visibleG2==1) guild_castledatasave(gc->castle_id,20,gc->Ghp2);
  6889. if(gc->visibleG3==1) guild_castledatasave(gc->castle_id,21,gc->Ghp3);
  6890. if(gc->visibleG4==1) guild_castledatasave(gc->castle_id,22,gc->Ghp4);
  6891. if(gc->visibleG5==1) guild_castledatasave(gc->castle_id,23,gc->Ghp5);
  6892. if(gc->visibleG6==1) guild_castledatasave(gc->castle_id,24,gc->Ghp6);
  6893. if(gc->visibleG7==1) guild_castledatasave(gc->castle_id,25,gc->Ghp7);
  6894. }
  6895. save_flag=1;
  6896. last_save_fd = sd->fd;
  6897. }
  6898. return 0;
  6899. }
  6900. /*==========================================
  6901. * 自動セ?ブ (timer??)
  6902. *------------------------------------------
  6903. */
  6904. int pc_autosave(int tid,unsigned int tick,int id,int data)
  6905. {
  6906. int interval;
  6907. save_flag=0;
  6908. clif_foreachclient(pc_autosave_sub);
  6909. if(save_flag==0)
  6910. last_save_fd=0;
  6911. interval = autosave_interval/(clif_countusers()+1);
  6912. if(interval <= 0)
  6913. interval = 1;
  6914. add_timer(gettick()+interval,pc_autosave,0,0);
  6915. return 0;
  6916. }
  6917. int pc_read_gm_account(int fd)
  6918. {
  6919. #ifdef TXT_ONLY
  6920. int i = 0;
  6921. #endif
  6922. if (gm_account != NULL)
  6923. free(gm_account);
  6924. GM_num = 0;
  6925. #ifdef TXT_ONLY
  6926. gm_account = aCalloc(sizeof(struct gm_account) * ((RFIFOW(fd,2) - 4) / 5), 1);
  6927. for (i = 4; i < RFIFOW(fd,2); i = i + 5) {
  6928. gm_account[GM_num].account_id = RFIFOL(fd,i);
  6929. gm_account[GM_num].level = (int)RFIFOB(fd,i+4);
  6930. //printf("GM account: %d -> level %d\n", gm_account[GM_num].account_id, gm_account[GM_num].level);
  6931. GM_num++;
  6932. }
  6933. #else
  6934. sprintf (tmp_lsql, "SELECT `%s`,`%s` FROM `%s` WHERE `%s`>='%d'",gm_db_account_id,gm_db_level,gm_db,gm_db_level,lowest_gm_level);
  6935. if(mysql_query(&lmysql_handle, tmp_lsql) ) {
  6936. printf("DB server Error (select %s to Memory)- %s\n",login_db,mysql_error(&lmysql_handle) );
  6937. }
  6938. lsql_res = mysql_store_result(&lmysql_handle);
  6939. if (lsql_res) {
  6940. gm_account = aCalloc(sizeof(struct gm_account) * mysql_num_rows(lsql_res), 1);
  6941. while ((lsql_row = mysql_fetch_row(lsql_res))) {
  6942. gm_account[GM_num].account_id = atoi(lsql_row[0]);
  6943. gm_account[GM_num].level = atoi(lsql_row[1]);
  6944. printf("GM account: %d -> level %d\n", gm_account[GM_num].account_id, gm_account[GM_num].level);
  6945. GM_num++;
  6946. }
  6947. }
  6948. mysql_free_result(lsql_res);
  6949. #endif /* TXT_ONLY */
  6950. return GM_num;
  6951. }
  6952. /*==========================================
  6953. * timer to do the day
  6954. *------------------------------------------
  6955. */
  6956. int map_day_timer(int tid, unsigned int tick, int id, int data) { // by [yor]
  6957. struct map_session_data *pl_sd = NULL;
  6958. int i;
  6959. char tmpstr[1024];
  6960. if (battle_config.day_duration > 0) { // if we want a day
  6961. if (night_flag != 0) {
  6962. strcpy(tmpstr, msg_txt(502)); // The day has arrived!
  6963. night_flag = 0; // 0=day, 1=night [Yor]
  6964. for(i = 0; i < fd_max; i++) {
  6965. if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth) {
  6966. pl_sd->opt2 &= ~STATE_BLIND;
  6967. clif_changeoption(&pl_sd->bl);
  6968. clif_wis_message(pl_sd->fd, wisp_server_name, tmpstr, strlen(tmpstr)+1);
  6969. }
  6970. }
  6971. }
  6972. }
  6973. return 0;
  6974. }
  6975. /*==========================================
  6976. * timer to do the night
  6977. *------------------------------------------
  6978. */
  6979. int map_night_timer(int tid, unsigned int tick, int id, int data) { // by [yor]
  6980. struct map_session_data *pl_sd = NULL;
  6981. int i;
  6982. char tmpstr[1024];
  6983. if (battle_config.night_duration > 0) { // if we want a night
  6984. if (night_flag == 0) {
  6985. strcpy(tmpstr, msg_txt(503)); // The night has fallen...
  6986. night_flag = 1; // 0=day, 1=night [Yor]
  6987. for(i = 0; i < fd_max; i++) {
  6988. if (session[i] && (pl_sd = session[i]->session_data) && pl_sd->state.auth && !map[pl_sd->bl.m].flag.indoors) {
  6989. if (battle_config.night_darkness_level > 0)
  6990. clif_specialeffect(&pl_sd->bl, 474 + battle_config.night_darkness_level, 0);
  6991. else {
  6992. //clif_specialeffect(&pl_sd->bl, 483, 0); // default darkness level
  6993. pl_sd->opt2 |= STATE_BLIND;
  6994. clif_changeoption(&pl_sd->bl);
  6995. }
  6996. clif_wis_message(pl_sd->fd, wisp_server_name, tmpstr, strlen(tmpstr)+1);
  6997. }
  6998. }
  6999. }
  7000. }
  7001. return 0;
  7002. }
  7003. void pc_setstand(struct map_session_data *sd){
  7004. nullpo_retv(sd);
  7005. if(sd->sc_count && sd->sc_data[SC_TENSIONRELAX].timer!=-1)
  7006. skill_status_change_end(&sd->bl,SC_TENSIONRELAX,-1);
  7007. sd->state.dead_sit = 0;
  7008. }
  7009. //
  7010. // 初期化物
  7011. //
  7012. /*==========================================
  7013. * 設定ファイル?み?む
  7014. * exp.txt 必要??値
  7015. * job_db1.txt 重量,hp,sp,攻?速度
  7016. * job_db2.txt job能力値ボ?ナス
  7017. * skill_tree.txt 各職?のスキルツリ?
  7018. * attr_fix.txt ?性修正テ?ブル
  7019. * size_fix.txt サイズ補正テ?ブル
  7020. * refine_db.txt 精?デ?タテ?ブル
  7021. *------------------------------------------
  7022. */
  7023. int pc_readdb(void)
  7024. {
  7025. int i,j,k,u;
  7026. struct pc_base_job s_class;
  7027. FILE *fp;
  7028. char line[1024],*p;
  7029. // 必要??値?み?み
  7030. fp=fopen("db/exp.txt","r");
  7031. if(fp==NULL){
  7032. printf("can't read db/exp.txt\n");
  7033. return 1;
  7034. }
  7035. i=0;
  7036. while(fgets(line, sizeof(line)-1, fp)){
  7037. int bn,b1,b2,b3,b4,b5,b6,jn,j1,j2,j3,j4,j5,j6;
  7038. if(line[0]=='/' && line[1]=='/')
  7039. continue;
  7040. if(sscanf(line,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",&bn,&b1,&b2,&b3,&b4,&b5,&b6,&jn,&j1,&j2,&j3,&j4,&j5,&j6)!=14)
  7041. continue;
  7042. exp_table[0][i]=bn;
  7043. exp_table[1][i]=b1;
  7044. exp_table[2][i]=b2;
  7045. exp_table[3][i]=b3;
  7046. exp_table[4][i]=b4;
  7047. exp_table[5][i]=b5;
  7048. exp_table[6][i]=b6;
  7049. exp_table[7][i]=jn;
  7050. exp_table[8][i]=j1;
  7051. exp_table[9][i]=j2;
  7052. exp_table[10][i]=j3;
  7053. exp_table[11][i]=j4;
  7054. exp_table[12][i]=j5;
  7055. exp_table[13][i]=j6;
  7056. i++;
  7057. if(i >= battle_config.maximum_level)
  7058. break;
  7059. }
  7060. fclose(fp);
  7061. sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/exp.txt");
  7062. ShowStatus(tmp_output);
  7063. // JOB補正?値1
  7064. fp=fopen("db/job_db1.txt","r");
  7065. if(fp==NULL){
  7066. printf("can't read db/job_db1.txt\n");
  7067. return 1;
  7068. }
  7069. i=0;
  7070. while(fgets(line, sizeof(line)-1, fp)){
  7071. char *split[50];
  7072. if(line[0]=='/' && line[1]=='/')
  7073. continue;
  7074. for(j=0,p=line;j<21 && p;j++){
  7075. split[j]=p;
  7076. p=strchr(p,',');
  7077. if(p) *p++=0;
  7078. }
  7079. if(j<21)
  7080. continue;
  7081. max_weight_base[i]=atoi(split[0]);
  7082. hp_coefficient[i]=atoi(split[1]);
  7083. hp_coefficient2[i]=atoi(split[2]);
  7084. sp_coefficient[i]=atoi(split[3]);
  7085. for(j=0;j<17;j++)
  7086. aspd_base[i][j]=atoi(split[j+4]);
  7087. i++;
  7088. // -- moonsoul (below two lines added to accommodate high numbered new class ids)
  7089. if(i==24)
  7090. i=4001;
  7091. if(i==MAX_PC_CLASS)
  7092. break;
  7093. }
  7094. fclose(fp);
  7095. sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/job_db1.txt");
  7096. ShowStatus(tmp_output);
  7097. // JOBボ?ナス
  7098. fp=fopen("db/job_db2.txt","r");
  7099. if(fp==NULL){
  7100. printf("can't read db/job_db2.txt\n");
  7101. return 1;
  7102. }
  7103. i=0;
  7104. while(fgets(line, sizeof(line)-1, fp)){
  7105. if(line[0]=='/' && line[1]=='/')
  7106. continue;
  7107. for(j=0,p=line;j<MAX_LEVEL && p;j++){
  7108. if(sscanf(p,"%d",&k)==0)
  7109. break;
  7110. job_bonus[0][i][j]=k;
  7111. job_bonus[2][i][j]=k; //養子職のボ?ナスは分からないので?
  7112. p=strchr(p,',');
  7113. if(p) p++;
  7114. }
  7115. i++;
  7116. // -- moonsoul (below two lines added to accommodate high numbered new class ids)
  7117. if(i==24)
  7118. i=4001;
  7119. if(i==MAX_PC_CLASS)
  7120. break;
  7121. }
  7122. fclose(fp);
  7123. sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/job_db2.txt");
  7124. ShowStatus(tmp_output);
  7125. // JOBボ?ナス2 ?生職用
  7126. fp=fopen("db/job_db2-2.txt","r");
  7127. if(fp==NULL){
  7128. printf("can't read db/job_db2-2.txt\n");
  7129. return 1;
  7130. }
  7131. i=0;
  7132. while(fgets(line, sizeof(line)-1, fp)){
  7133. if(line[0]=='/' && line[1]=='/')
  7134. continue;
  7135. for(j=0,p=line;j<MAX_LEVEL && p;j++){
  7136. if(sscanf(p,"%d",&k)==0)
  7137. break;
  7138. job_bonus[1][i][j]=k;
  7139. p=strchr(p,',');
  7140. if(p) p++;
  7141. }
  7142. i++;
  7143. if(i==MAX_PC_CLASS)
  7144. break;
  7145. }
  7146. fclose(fp);
  7147. sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/job_db2-2.txt");
  7148. ShowStatus(tmp_output);
  7149. // スキルツリ?
  7150. memset(skill_tree,0,sizeof(skill_tree));
  7151. fp=fopen("db/skill_tree.txt","r");
  7152. if(fp==NULL){
  7153. printf("can't read db/skill_tree.txt\n");
  7154. return 1;
  7155. }
  7156. while(fgets(line, sizeof(line)-1, fp)){
  7157. char *split[50];
  7158. if(line[0]=='/' && line[1]=='/')
  7159. continue;
  7160. for(j=0,p=line;j<13 && p;j++){
  7161. split[j]=p;
  7162. p=strchr(p,',');
  7163. if(p) *p++=0;
  7164. }
  7165. if(j<13)
  7166. continue;
  7167. //i=atoi(split[0]);
  7168. s_class = pc_calc_base_job(atoi(split[0]));
  7169. i = s_class.job;
  7170. u = s_class.upper;
  7171. for(j=0;skill_tree[u][i][j].id;j++);
  7172. skill_tree[u][i][j].id=atoi(split[1]);
  7173. skill_tree[u][i][j].max=atoi(split[2]);
  7174. //not required - Celest
  7175. //skill_tree[2][i][j].id=atoi(split[1]); //養子職は良く分からないので暫定
  7176. //skill_tree[2][i][j].max=atoi(split[2]); //養子職は良く分からないので暫定
  7177. for(k=0;k<5;k++){
  7178. skill_tree[u][i][j].need[k].id=atoi(split[k*2+3]);
  7179. skill_tree[u][i][j].need[k].lv=atoi(split[k*2+4]);
  7180. //skill_tree[2][i][j].need[k].id=atoi(split[k*2+3]); //養子職は良く分からないので暫定
  7181. //skill_tree[2][i][j].need[k].lv=atoi(split[k*2+4]); //養子職は良く分からないので暫定
  7182. }
  7183. }
  7184. fclose(fp);
  7185. sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/skill_tree.txt");
  7186. ShowStatus(tmp_output);
  7187. // ?性修正テ?ブル
  7188. for(i=0;i<4;i++)
  7189. for(j=0;j<10;j++)
  7190. for(k=0;k<10;k++)
  7191. attr_fix_table[i][j][k]=100;
  7192. fp=fopen("db/attr_fix.txt","r");
  7193. if(fp==NULL){
  7194. printf("can't read db/attr_fix.txt\n");
  7195. return 1;
  7196. }
  7197. while(fgets(line, sizeof(line)-1, fp)){
  7198. char *split[10];
  7199. int lv,n;
  7200. if(line[0]=='/' && line[1]=='/')
  7201. continue;
  7202. for(j=0,p=line;j<3 && p;j++){
  7203. split[j]=p;
  7204. p=strchr(p,',');
  7205. if(p) *p++=0;
  7206. }
  7207. lv=atoi(split[0]);
  7208. n=atoi(split[1]);
  7209. // printf("%d %d\n",lv,n);
  7210. for(i=0;i<n;){
  7211. if( !fgets(line, sizeof(line)-1, fp) )
  7212. break;
  7213. if(line[0]=='/' && line[1]=='/')
  7214. continue;
  7215. for(j=0,p=line;j<n && p;j++){
  7216. while(*p==32 && *p>0)
  7217. p++;
  7218. attr_fix_table[lv-1][i][j]=atoi(p);
  7219. if(battle_config.attr_recover == 0 && attr_fix_table[lv-1][i][j] < 0)
  7220. attr_fix_table[lv-1][i][j] = 0;
  7221. p=strchr(p,',');
  7222. if(p) *p++=0;
  7223. }
  7224. i++;
  7225. }
  7226. }
  7227. fclose(fp);
  7228. sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/attr_fix.txt");
  7229. ShowStatus(tmp_output);
  7230. // サイズ補正テ?ブル
  7231. for(i=0;i<3;i++)
  7232. for(j=0;j<20;j++)
  7233. atkmods[i][j]=100;
  7234. fp=fopen("db/size_fix.txt","r");
  7235. if(fp==NULL){
  7236. printf("can't read db/size_fix.txt\n");
  7237. return 1;
  7238. }
  7239. i=0;
  7240. while(fgets(line, sizeof(line)-1, fp)){
  7241. char *split[20];
  7242. if(line[0]=='/' && line[1]=='/')
  7243. continue;
  7244. if(atoi(line)<=0)
  7245. continue;
  7246. memset(split,0,sizeof(split));
  7247. for(j=0,p=line;j<20 && p;j++){
  7248. split[j]=p;
  7249. p=strchr(p,',');
  7250. if(p) *p++=0;
  7251. }
  7252. for(j=0;j<20 && split[j];j++)
  7253. atkmods[i][j]=atoi(split[j]);
  7254. i++;
  7255. }
  7256. fclose(fp);
  7257. sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/size_fix.txt");
  7258. ShowStatus(tmp_output);
  7259. // 精?デ?タテ?ブル
  7260. for(i=0;i<5;i++){
  7261. for(j=0;j<10;j++)
  7262. percentrefinery[i][j]=100;
  7263. refinebonus[i][0]=0;
  7264. refinebonus[i][1]=0;
  7265. refinebonus[i][2]=10;
  7266. }
  7267. fp=fopen("db/refine_db.txt","r");
  7268. if(fp==NULL){
  7269. printf("can't read db/refine_db.txt\n");
  7270. return 1;
  7271. }
  7272. i=0;
  7273. while(fgets(line, sizeof(line)-1, fp)){
  7274. char *split[16];
  7275. if(line[0]=='/' && line[1]=='/')
  7276. continue;
  7277. if(atoi(line)<=0)
  7278. continue;
  7279. memset(split,0,sizeof(split));
  7280. for(j=0,p=line;j<16 && p;j++){
  7281. split[j]=p;
  7282. p=strchr(p,',');
  7283. if(p) *p++=0;
  7284. }
  7285. refinebonus[i][0]=atoi(split[0]); // 精?ボ?ナス
  7286. refinebonus[i][1]=atoi(split[1]); // 過?精?ボ?ナス
  7287. refinebonus[i][2]=atoi(split[2]); // 安全精?限界
  7288. for(j=0;j<10 && split[j];j++)
  7289. percentrefinery[i][j]=atoi(split[j+3]);
  7290. i++;
  7291. }
  7292. fclose(fp); //Lupus. close this file!!!
  7293. sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/refine_db.txt");
  7294. ShowStatus(tmp_output);
  7295. return 0;
  7296. }
  7297. static int pc_calc_sigma(void)
  7298. {
  7299. int i,j,k;
  7300. for(i=0;i<MAX_PC_CLASS;i++) {
  7301. memset(hp_sigma_val[i],0,sizeof(hp_sigma_val[i]));
  7302. for(k=0,j=2;j<=MAX_LEVEL;j++) {
  7303. k += hp_coefficient[i]*j + 50;
  7304. k -= k%100;
  7305. hp_sigma_val[i][j-1] = k;
  7306. }
  7307. }
  7308. return 0;
  7309. }
  7310. static void pc_statpointdb(void)
  7311. {
  7312. char * buf_stat;
  7313. int i=0,j=0,k=0,l=0, end = 0;
  7314. FILE *stp;
  7315. stp=fopen("db/statpoint.txt","r");
  7316. if(stp==NULL){
  7317. printf("can't read db/statpoint.txt\n");
  7318. return;
  7319. }
  7320. fseek(stp, 0, SEEK_END);
  7321. end = ftell(stp);
  7322. rewind(stp);
  7323. buf_stat = (char *) malloc (end + 1);
  7324. l = fread(buf_stat,1,end,stp);
  7325. fclose(stp);
  7326. sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","db/statpoint.txt");
  7327. ShowStatus(tmp_output);
  7328. // printf("read db/statpoint.txt done (size=%d)\n",l);
  7329. for(i=0;i<255;i++) {
  7330. j=0;
  7331. while (*(buf_stat+k)!='\n') {
  7332. statp[i][j]=*(buf_stat+k);
  7333. j++;k++;
  7334. }
  7335. statp[i][j+1]='\0';
  7336. k++;
  7337. }
  7338. free(buf_stat);
  7339. }
  7340. /*==========================================
  7341. * pc? 係初期化
  7342. *------------------------------------------
  7343. */
  7344. int do_init_pc(void) {
  7345. pc_readdb();
  7346. pc_statpointdb();
  7347. pc_calc_sigma();
  7348. // gm_account_db = numdb_init();
  7349. add_timer_func_list(pc_walk, "pc_walk");
  7350. add_timer_func_list(pc_attack_timer, "pc_attack_timer");
  7351. add_timer_func_list(pc_natural_heal, "pc_natural_heal");
  7352. add_timer_func_list(pc_invincible_timer, "pc_invincible_timer");
  7353. add_timer_func_list(pc_eventtimer, "pc_eventtimer");
  7354. add_timer_func_list(pc_calc_pvprank_timer, "pc_calc_pvprank_timer");
  7355. add_timer_func_list(pc_autosave, "pc_autosave");
  7356. add_timer_func_list(pc_spiritball_timer, "pc_spiritball_timer");
  7357. add_timer_interval((natural_heal_prev_tick = gettick() + NATURAL_HEAL_INTERVAL), pc_natural_heal, 0, 0, NATURAL_HEAL_INTERVAL);
  7358. add_timer(gettick() + autosave_interval, pc_autosave, 0, 0);
  7359. #ifndef TXT_ONLY
  7360. pc_read_gm_account(0);
  7361. #endif /* not TXT_ONLY */
  7362. // add night/day timer (by [yor])
  7363. add_timer_func_list(map_day_timer, "map_day_timer"); // by [yor]
  7364. add_timer_func_list(map_night_timer, "map_night_timer"); // by [yor]
  7365. {
  7366. int day_duration = battle_config.day_duration;
  7367. int night_duration = battle_config.night_duration;
  7368. if (day_duration < 60000)
  7369. day_duration = 60000;
  7370. if (night_duration < 60000)
  7371. night_duration = 60000;
  7372. if (battle_config.night_at_start == 0) {
  7373. night_flag = 0; // 0=day, 1=night [Yor]
  7374. day_timer_tid = add_timer_interval(gettick() + day_duration + night_duration, map_day_timer, 0, 0, day_duration + night_duration);
  7375. night_timer_tid = add_timer_interval(gettick() + day_duration, map_night_timer, 0, 0, day_duration + night_duration);
  7376. } else {
  7377. night_flag = 1; // 0=day, 1=night [Yor]
  7378. day_timer_tid = add_timer_interval(gettick() + night_duration, map_day_timer, 0, 0, day_duration + night_duration);
  7379. night_timer_tid = add_timer_interval(gettick() + day_duration + night_duration, map_night_timer, 0, 0, day_duration + night_duration);
  7380. }
  7381. }
  7382. return 0;
  7383. }