playerbase.c 251 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379
  1. class PlayerBase extends ManBase
  2. {
  3. const int SIMPLIFIED_SHOCK_CAP = 63;
  4. const int SHAKE_LEVEL_MAX = 7;
  5. private int m_LifeSpanState;
  6. private int m_LastShavedSeconds;
  7. private int m_BloodType;
  8. private bool m_HasBloodTypeVisible;
  9. private bool m_LiquidTendencyDrain; //client-side only - Obsolete
  10. private bool m_FlagRaisingTendency;
  11. private int m_HasBloodyHandsVisible;
  12. protected bool m_HasHeatBuffer;
  13. protected int m_HeatBufferStage;
  14. protected float m_HeatBufferDynamicMax;
  15. protected bool m_IsInColdArea;
  16. protected bool m_PlayerLoaded;
  17. protected bool m_PlayerDisconnectProcessed;
  18. protected bool m_ProcessUIWarning;
  19. protected int m_LocalRefreshAnimStateIdx;
  20. protected int m_RefreshAnimStateIdx;
  21. private int m_StoreLoadVersion;
  22. const int ACT_STORE_SAVE_VERSION = 4;
  23. protected int m_LifespanLevelLocal; //control variable for change calls
  24. protected int m_AnimCommandStarting; //signals the command that is about to start the next frame (e.g. Swim, Fall...)
  25. EUndergroundPresence m_UndergroundPresence;
  26. private PluginPlayerStatus m_ModulePlayerStatus;
  27. PluginConfigEmotesProfile m_ConfigEmotesProfile;
  28. private PluginLifespan m_ModuleLifespan;
  29. protected PluginPresenceNotifier m_PresenceNotifier;
  30. protected ref UndergroundHandlerClient m_UndergroundHandler;
  31. protected ref UndergroundBunkerHandlerClient m_UndergroundBunkerHandler;
  32. ref PlayerStats m_PlayerStats;
  33. PluginRecipesManager m_ModuleRecipesManager;
  34. ref BleedingSourcesManagerServer m_BleedingManagerServer;
  35. ref BleedingSourcesManagerRemote m_BleedingManagerRemote;
  36. ref ModifiersManager m_ModifiersManager;
  37. ref NotifiersManager m_NotifiersManager;
  38. ref protected ActionManagerBase m_ActionManager;
  39. ref PlayerAgentPool m_AgentPool;
  40. int m_Agents;
  41. ref Environment m_Environment;
  42. ref EmoteManager m_EmoteManager;
  43. ref SymptomManager m_SymptomManager;
  44. ref VirtualHud m_VirtualHud;
  45. ref StaminaHandler m_StaminaHandler;
  46. ref InjuryAnimationHandler m_InjuryHandler;
  47. ref ShockHandler m_ShockHandler; //New shock handler
  48. ref SoftSkillsManager m_SoftSkillsManager;
  49. ref StanceIndicator m_StanceIndicator;
  50. ref TransferValues m_TrasferValues;
  51. ref DebugMonitorValues m_DebugMonitorValues;
  52. const int OVERLOAD_LIMIT = 30000;
  53. float m_CargoLoad;
  54. float m_VisibilityCoef;
  55. float m_OriginalSlidePoseAngle;
  56. int m_SoundEvent;
  57. int m_SoundEventParam;
  58. int m_FliesIndex;
  59. bool m_SoundEventSent;
  60. ref Param2<float,float> m_UAProgressParam;
  61. ref Param2<int,int> m_UAParam;
  62. ref Param3<float,float,bool> m_StaminaParam;
  63. ref Param1<string> m_UAParamMessage;
  64. ref Param1<float> m_UnconParam;
  65. ref Param1<float> m_DeathDarkeningParam;
  66. ref DamageDealtEffect m_DamageDealtEffect;
  67. ref EffectRadial m_EffectRadial;
  68. ref FlashbangEffect m_FlashbangEffect;
  69. ref ShockDealtEffect m_ShockDealtEffect;
  70. ref EffectParticle m_FliesEff;
  71. ref TInputActionMap m_InputActionMap; // Backwards compatibility
  72. ref TInputActionMap m_InputActionMapControled;
  73. ref TInputActionMap m_InputActionMapAsTarget;
  74. bool m_ActionsInitialize;
  75. //ref CraftingMeta m_CraftingMeta;
  76. ref HiddenSelectionsData m_EmptyGloves;
  77. ref WeaponManager m_WeaponManager;
  78. ref CraftingManager m_CraftingManager;
  79. ref ArrowManagerPlayer m_ArrowManager;
  80. ref InventoryActionHandler m_InventoryActionHandler;
  81. ref protected QuickBarBase m_QuickBarBase;
  82. ref PlayerSoundManagerServer m_PlayerSoundManagerServer;
  83. ref PlayerSoundManagerClient m_PlayerSoundManagerClient;
  84. ref HeatComfortAnimHandler m_HCAnimHandler;
  85. ref EffectSound m_SoundFliesEffect;
  86. bool m_QuickBarHold;
  87. bool m_QuickBarFT = false;
  88. Hud m_Hud;
  89. protected int m_RecipePick;
  90. protected bool m_IsHoldingBreath;
  91. protected bool m_IsInWater;
  92. float m_LastPostFrameTickTime;
  93. //AbstractWave m_SaySoundWave;
  94. ref Timer m_DeathCheckTimer;
  95. bool m_CorpseProcessing;
  96. int m_CorpseState;
  97. protected int m_CorpseStateLocal;
  98. protected bool m_IsHeadingRestricted;
  99. protected ref HeadingRestrictData m_HeadingRestrictData;
  100. int m_PersistentFlags;
  101. int m_StaminaState;
  102. float m_UnconsciousTime;
  103. int m_ShockSimplified;
  104. float m_CurrentShock; //Used to synchronize shock between server and client
  105. bool m_IsRestrained;
  106. bool m_IsRestrainedLocal;
  107. bool m_IsRestrainStarted;
  108. bool m_IsRestrainStartedLocal;
  109. bool m_IsRestrainPrelocked;
  110. bool m_ImmunityBoosted;
  111. bool m_AreHandsLocked; //Currently only used to block quickbar usage after canceling placement
  112. float m_UnconsciousVignetteTarget = 2;
  113. float m_CameraSwayModifier = 0.2;
  114. float m_LastShockHitTime;
  115. DayZPlayerCameraBase m_CurrentCamera;
  116. int m_BleedingBits;
  117. vector m_DirectionToCursor;
  118. vector m_DefaultHitPosition;
  119. int m_DiseaseCount;
  120. int m_HealingsCount;
  121. protected bool m_AllowQuickRestrain;
  122. protected bool m_AllowQuickFishing;
  123. protected int m_Shakes;
  124. protected int m_ShakesForced;
  125. int m_BreathVapour;
  126. int m_HealthLevel;
  127. int m_MixedSoundStates;
  128. int m_QuickBarBonus = 0;
  129. bool m_IsVehicleSeatDriver;
  130. float m_UnconsciousEndTime = 0;
  131. int m_BleedingSourceCount;
  132. Head_Default m_CharactersHead;
  133. EPulseType m_PulseType;
  134. PlayerBase m_CheckPulseLastTarget;
  135. int m_ForceInjuryAnimMask;
  136. bool m_HideHairAnimated;
  137. string m_DecayedTexture;
  138. protected ref array<EntityAI> m_ItemsToDelete;
  139. int m_BrokenLegState = eBrokenLegs.NO_BROKEN_LEGS; //Describe the current leg state, can go bellow 0, cannot be used directly to obtain broken legs state, use GetBrokenLegs() instead
  140. int m_LocalBrokenState = eBrokenLegs.NO_BROKEN_LEGS;
  141. bool m_BrokenLegsJunctureReceived;
  142. ref EffectSound m_BrokenLegSound;
  143. const string SOUND_BREAK_LEG = "broken_leg_SoundSet";
  144. bool m_CanPlayBrokenLegSound; //Used to check if sound has already been played
  145. static bool DEBUG_INVENTORY_ACCESS = false;
  146. static ref array<string> m_BleedingSourcesLow; //Stores all LOWER body part bleeding sources
  147. static ref array<string> m_BleedingSourcesUp; //Stores all UPPER body part bleeding sources EXCLUDING HEAD
  148. float m_UnconRefillModifier = 1;
  149. ref protected RandomGeneratorSyncManager m_RGSManager;
  150. // CONTAMINATED AREA RELATED
  151. bool m_ContaminatedAreaEffectEnabled;
  152. const string CONTAMINATED_AREA_AMBIENT = "ContaminatedArea_SoundSet";//obsolete, use EffectTrigger::GetAmbientSoundsetName() instead
  153. EffectSound m_AmbientContamination;
  154. protected int m_ContaminatedAreaCount;
  155. protected int m_EffectAreaCount;
  156. protected bool m_InsideEffectArea;
  157. protected bool m_InsideEffectAreaPrev;
  158. protected EffectTrigger m_CurrentEffectTrigger;
  159. // effect areas
  160. protected EEffectAreaType m_InEffectAreaType; // flags for identifying which area the player is in, synchronized by EffectTriggers
  161. protected ref map<EEffectAreaType, int> m_EffectAreaOverlap = new map<EEffectAreaType, int>(); // type -> how many of such areas is player currently in
  162. protected ref map<EEffectAreaType, float> m_EffectAreaTimeToTick = new map<EEffectAreaType, float>(); // type -> how long has player spent in an area since last effect tick
  163. static ref array<Man> m_ServerPlayers = new array<Man>;
  164. protected bool m_CanDisplayHitEffectPPE;
  165. protected string m_CachedPlayerName;//cached from player identity
  166. protected string m_CachedPlayerID;//cached from player identity
  167. #ifdef DIAG_DEVELOPER
  168. int m_IsInsideTrigger;
  169. bool m_CanBeTargetedDebug; //server-side only
  170. ref array<EntityAI> m_PresetItems = new array<EntityAI>;
  171. bool m_PresetSpawned;
  172. ref CameraToolsMenuClient m_CameraToolsMenuClient;
  173. protected PluginTargetTemperature m_TargetTemperatureDiag;
  174. #endif
  175. #ifdef DEVELOPER
  176. Transport m_GetInVehicleTransportDebug;
  177. #endif
  178. #ifdef DIAG_DEVELOPER
  179. ref Bot m_Bot;
  180. #endif
  181. //Temp QuickBar load
  182. ref array<ref Param2<EntityAI,int> > m_aQuickBarLoad;
  183. //hologram
  184. ref Hologram m_HologramServer;
  185. ref Hologram m_HologramLocal;
  186. vector m_LocalProjectionPosition = "0 0 0 ";
  187. vector m_LocalProjectionOrientation = "0 0 0 ";
  188. //Sheduler
  189. float m_LastTick = -1;
  190. int m_AddModifier = -1;
  191. //crafting start
  192. int m_RecipeID = -1;
  193. EntityAI m_Item1;
  194. EntityAI m_Item2;
  195. bool m_IsCraftingReady;
  196. float m_RecipeAnimLength;
  197. vector m_CraftingInitialPos;
  198. ref array<int> m_Recipes;
  199. //crafting end
  200. ref SoundParams m_SaySoundParams;
  201. ref SoundObjectBuilder m_SaySoundBuilder;
  202. ref SoundObject m_SaySoundObject;
  203. string m_SaySoundLastSetName;
  204. //input control
  205. bool m_ActionQBControl;
  206. //Action data for base building actions
  207. ref ConstructionActionData m_ConstructionActionData;
  208. //Action data for fireplace (indoor)
  209. vector m_LastFirePoint;
  210. float m_LastFirePointRot;
  211. int m_LastFirePointIndex;
  212. bool ItemToInventory;
  213. bool m_IsFighting = false;
  214. bool m_IsDrowning;//Set only via the setter SetDrowning
  215. // debug monitor
  216. int m_DebugMonitorEnabled;
  217. //map
  218. ActionUnfoldMapCB m_hac;
  219. bool m_MapOpen;
  220. bool m_MapCloseRequestProcessed; //DEPRECATED
  221. protected bool m_MapClosingSyncSent;
  222. protected float m_LastMapScale = -1.0;
  223. protected vector m_LastMapPos;
  224. protected ref MapNavigationBehaviour m_MapNavigationBehaviour;
  225. //inventory soft locking
  226. protected bool m_InventorySoftLocked; //obsolete, count should be checked instead. Left in here for legacy's sake.
  227. protected int m_InventorySoftLockCount = 0;
  228. static ref TStringArray m_QBarItems;
  229. //Analytics
  230. string m_DatabaseID;
  231. ref Timer m_AnalyticsTimer;
  232. //! melee stats
  233. protected bool m_MeleeDebug;
  234. //protected bool m_CheckMeleeItem;
  235. protected ItemBase m_CheckMeleeItem;
  236. //! user actions & symptoms
  237. protected string m_UALastMessage;
  238. protected ref Timer m_UALastMessageTimer;
  239. protected int m_PerformedAnimActionID = -1; // animated action being performed, -1 if none
  240. protected int m_ActivePrimarySymptomID = 0; // active primary symptom, 0 if none, symptom has to be overriden to allow sync
  241. bool m_WorkingNVGHeadset; //Deprecated
  242. bool m_LoweredNVGHeadset;
  243. protected ref array<int> m_ActiveNVTypes;
  244. //bool m_PreviousNVGState;
  245. int m_SyncedModifiers;
  246. int m_SyncedModifiersPrev;
  247. PluginAdminLog m_AdminLog;
  248. ref PlayerStomach m_PlayerStomach;
  249. protected static Particle m_ContaminatedAroundPlayer;
  250. protected static Particle m_ContaminatedAroundPlayerTiny;
  251. protected PlayerStat<float> m_StatWater;
  252. protected PlayerStat<float> m_StatToxicity;
  253. protected PlayerStat<float> m_StatEnergy;
  254. protected PlayerStat<float> m_StatHeatComfort;
  255. protected PlayerStat<float> m_StatTremor;
  256. protected PlayerStat<int> m_StatWet
  257. protected PlayerStat<int> m_StatBloodType
  258. protected PlayerStat<float> m_StatDiet
  259. protected PlayerStat<float> m_StatStamina
  260. protected PlayerStat<float> m_StatSpecialty
  261. protected PlayerStat<float> m_StatHeatBuffer
  262. //!effect widgets
  263. protected GameplayEffectWidgets_base m_EffectWidgets;
  264. protected ref array<int> m_ProcessAddEffectWidgets;
  265. protected ref array<int> m_ProcessRemoveEffectWidgets;
  266. //postprocess processing
  267. protected ref array<int> m_ProcessAddGlassesEffects;
  268. protected ref array<int> m_ProcessRemoveGlassesEffects;
  269. protected EMedicalDrugsType m_MedicalDrugsActive;
  270. //! invokers
  271. protected ref ScriptInvoker m_OnUnconsciousStart;
  272. protected ref ScriptInvoker m_OnUnconsciousStop;
  273. void PlayerBase()
  274. {
  275. Init();
  276. }
  277. void Init()
  278. {
  279. SetEventMask(EntityEvent.INIT|EntityEvent.POSTFRAME|EntityEvent.FRAME);
  280. m_StoreLoadVersion = 0;
  281. m_IsCraftingReady = false;
  282. m_Recipes = new array<int>;
  283. m_LastShavedSeconds = 0;
  284. m_BloodType = 0;
  285. m_HasBloodTypeVisible = false;
  286. m_LifeSpanState = 0;
  287. m_LifespanLevelLocal = -1;
  288. m_CorpseState = 0;
  289. m_CorpseStateLocal = 0;
  290. m_HasBloodyHandsVisible = 0;
  291. m_PlayerLoaded = false;
  292. m_PlayerSelected = false;
  293. m_ProcessUIWarning = false;
  294. m_FlagRaisingTendency = true;
  295. m_LiquidTendencyDrain = false;
  296. m_UAParamMessage = new Param1<string>("");
  297. m_UnconParam = new Param1<float>(0);
  298. m_DeathDarkeningParam = new Param1<float>(0);
  299. m_UAParam = new Param2<int,int>(0,0);
  300. m_UAProgressParam = new Param2<float,float>(0,0);
  301. m_QuickBarBase = new QuickBarBase(this);
  302. m_QuickBarBonus = Math.Max(ConfigGetInt("quickBarBonus"), 0);
  303. m_CargoLoad = 0;
  304. m_VisibilityCoef = 1.0;
  305. m_Hud = GetGame().GetMission().GetHud();
  306. m_RecipePick = 0;
  307. m_ActionQBControl = false;
  308. m_QuickBarHold = false;
  309. m_HideHairAnimated = true;
  310. m_WorkingNVGHeadset = false;
  311. m_LoweredNVGHeadset = false;
  312. m_AreHandsLocked = false;
  313. m_ItemsToDelete = new array<EntityAI>;
  314. m_AnimCommandStarting = HumanMoveCommandID.None;
  315. m_EmptyGloves = new HiddenSelectionsData(ConfigGetString("emptyGloves"));
  316. m_CanDisplayHitEffectPPE = true;
  317. m_HeadingRestrictData = new HeadingRestrictData();
  318. #ifdef DIAG_DEVELOPER
  319. m_CanBeTargetedDebug = true;
  320. //RegisterNetSyncVariableBool("m_CanBeTargetedDebug");
  321. #endif
  322. m_AnalyticsTimer = new Timer(CALL_CATEGORY_SYSTEM);
  323. m_StaminaHandler = new StaminaHandler(this);//current stamina calculation
  324. m_InjuryHandler = new InjuryAnimationHandler(this);
  325. m_ShockHandler = new ShockHandler(this); //New shock handler
  326. m_HCAnimHandler = new HeatComfortAnimHandler(this);
  327. m_PlayerStats = new PlayerStats(this);//player stats
  328. m_ArrowManager = new ArrowManagerPlayer(this);
  329. if (GetGame().IsServer())
  330. {
  331. m_PlayerStomach = new PlayerStomach(this);
  332. m_NotifiersManager = new NotifiersManager(this); // player notifiers
  333. m_AgentPool = new PlayerAgentPool(this); // agent pool manager
  334. m_BleedingManagerServer = new BleedingSourcesManagerServer(this);
  335. m_Environment = new Environment(this);//environment effects on player
  336. m_ModifiersManager = new ModifiersManager(this); // player modifiers
  337. m_PlayerSoundManagerServer = new PlayerSoundManagerServer(this);
  338. m_VirtualHud = new VirtualHud(this);
  339. m_AdminLog = PluginAdminLog.Cast(GetPlugin(PluginAdminLog));
  340. }
  341. m_SymptomManager = new SymptomManager(this); // state manager
  342. m_ModuleRecipesManager = PluginRecipesManager.Cast(GetPlugin(PluginRecipesManager));
  343. m_TrasferValues = new TransferValues(this);
  344. m_EmoteManager = new EmoteManager(this);
  345. m_SoftSkillsManager = new SoftSkillsManager(this);//Soft Skills calculation
  346. m_WeaponManager = new WeaponManager(this);
  347. m_DebugMonitorValues = new DebugMonitorValues(this);
  348. m_RGSManager = new RandomGeneratorSyncManager(this);
  349. if (!GetGame().IsDedicatedServer())
  350. {
  351. m_MeleeDebug = false;
  352. m_UALastMessage = "";
  353. m_UALastMessageTimer = new Timer;
  354. m_InventoryActionHandler = new InventoryActionHandler(this);
  355. m_BleedingManagerRemote = new BleedingSourcesManagerRemote(this);
  356. m_PlayerSoundManagerClient = new PlayerSoundManagerClient(this);
  357. m_StanceIndicator = new StanceIndicator(this);
  358. m_ActionsInitialize = false;
  359. ClientData.AddPlayerBase(this);
  360. m_ProcessAddEffectWidgets = new array<int>;
  361. m_ProcessRemoveEffectWidgets = new array<int>;
  362. m_ActiveNVTypes = new array<int>;
  363. m_ProcessAddGlassesEffects = new array<int>;
  364. m_ProcessRemoveGlassesEffects = new array<int>;
  365. }
  366. m_ActionManager = NULL;
  367. m_ConfigEmotesProfile = PluginConfigEmotesProfile.Cast(GetPlugin(PluginConfigEmotesProfile));
  368. if (GetDayZGame().IsDebug())
  369. {
  370. PluginConfigDebugProfileFixed m_ConfigDebugProfileFixed = PluginConfigDebugProfileFixed.Cast(GetPlugin(PluginConfigDebugProfileFixed));
  371. PluginConfigDebugProfile m_ConfigDebugProfile = PluginConfigDebugProfile.Cast(GetPlugin(PluginConfigDebugProfile));
  372. PluginDeveloper m_Developer = PluginDeveloper.Cast(GetPlugin(PluginDeveloper));
  373. PlayerBase player = this;
  374. if (m_ConfigDebugProfile)
  375. {
  376. string default_preset = m_ConfigDebugProfile.GetDefaultPreset();
  377. if (player && default_preset != "")
  378. {
  379. TStringArray preset_array = new TStringArray;
  380. m_ConfigDebugProfileFixed.GetPresetItems(default_preset, preset_array);
  381. bool is_preset_fixed = true;
  382. if (preset_array.Count() == 0)
  383. {
  384. m_ConfigDebugProfile.GetPresetItems(default_preset, preset_array);
  385. is_preset_fixed = false;
  386. }
  387. if (preset_array.Count() > 0)
  388. {
  389. m_Developer.ClearInventory(player);
  390. for (int i = 0; i < preset_array.Count(); i++)
  391. {
  392. float health = -1;
  393. int quantity = -1;
  394. if (is_preset_fixed)
  395. {
  396. health = m_ConfigDebugProfileFixed.GetItemHealth(default_preset, i);
  397. quantity = m_ConfigDebugProfileFixed.GetItemQuantity(default_preset, i);
  398. }
  399. else
  400. {
  401. health = m_ConfigDebugProfile.GetItemHealth(default_preset, i);
  402. quantity = m_ConfigDebugProfile.GetItemQuantity(default_preset, i);
  403. }
  404. m_Developer.SpawnEntityInPlayerInventory(player, preset_array.Get(i), health, quantity);
  405. }
  406. }
  407. }
  408. }
  409. }
  410. m_MedicalDrugsActive = EMedicalDrugsType.NONE;
  411. m_MapNavigationBehaviour = new MapNavigationBehaviour(this);
  412. m_ModulePlayerStatus = PluginPlayerStatus.Cast(GetPlugin(PluginPlayerStatus));
  413. m_ModuleLifespan = PluginLifespan.Cast(GetPlugin(PluginLifespan));
  414. m_BleedingSourcesLow = new array<string>;
  415. m_BleedingSourcesLow.Insert("RightToeBase");
  416. m_BleedingSourcesLow.Insert("RightFoot");
  417. m_BleedingSourcesLow.Insert("LeftToeBase");
  418. m_BleedingSourcesLow.Insert("LeftFoot");
  419. m_BleedingSourcesLow.Insert("RightUpLegRoll");
  420. m_BleedingSourcesLow.Insert("RightUpLeg");
  421. m_BleedingSourcesLow.Insert("RightLegRoll");
  422. m_BleedingSourcesLow.Insert("RightLeg");
  423. m_BleedingSourcesLow.Insert("LeftUpLegRoll");
  424. m_BleedingSourcesLow.Insert("LeftUpLeg");
  425. m_BleedingSourcesLow.Insert("LeftLegRoll");
  426. m_BleedingSourcesLow.Insert("LeftLeg");
  427. m_BleedingSourcesUp = new array<string>;
  428. m_BleedingSourcesUp.Insert("RightForeArmRoll");
  429. m_BleedingSourcesUp.Insert("LeftForeArmRoll");
  430. m_BleedingSourcesUp.Insert("RightForeArm");
  431. m_BleedingSourcesUp.Insert("RightArmRoll");
  432. m_BleedingSourcesUp.Insert("RightArm");
  433. m_BleedingSourcesUp.Insert("RightShoulder");
  434. m_BleedingSourcesUp.Insert("LeftForeArm");
  435. m_BleedingSourcesUp.Insert("LeftArmRoll");
  436. m_BleedingSourcesUp.Insert("LeftArm");
  437. m_BleedingSourcesUp.Insert("LeftShoulder");
  438. m_BleedingSourcesUp.Insert("Spine3");
  439. m_BleedingSourcesUp.Insert("Spine2");
  440. m_BleedingSourcesUp.Insert("Spine1");
  441. m_BleedingSourcesUp.Insert("Spine");
  442. m_BleedingSourcesUp.Insert("Pelvis");
  443. m_BleedingSourcesUp.Insert("Neck");
  444. RegisterNetSyncVariableInt("m_PersistentFlags", 0, 1<<(EnumTools.GetEnumSize(PersistentFlag) + 1));
  445. RegisterNetSyncVariableInt("m_LifeSpanState", LifeSpanState.BEARD_NONE, LifeSpanState.COUNT);
  446. RegisterNetSyncVariableInt("m_BloodType", 0, 128);
  447. RegisterNetSyncVariableInt("m_ShockSimplified",0, SIMPLIFIED_SHOCK_CAP);
  448. RegisterNetSyncVariableInt("m_SoundEvent",0, EPlayerSoundEventID.ENUM_COUNT - 1);
  449. RegisterNetSyncVariableInt("m_SoundEventParam", 0, ((EPlayerSoundEventParam.ENUM_COUNT - 1) * 2) - 1);
  450. RegisterNetSyncVariableInt("m_StaminaState",0, eStaminaState.COUNT - 1);
  451. RegisterNetSyncVariableInt("m_BleedingBits");
  452. RegisterNetSyncVariableInt("m_Shakes", 0, SHAKE_LEVEL_MAX);
  453. RegisterNetSyncVariableInt("m_BreathVapour", 0, BREATH_VAPOUR_LEVEL_MAX);
  454. RegisterNetSyncVariableInt("m_HealthLevel", eInjuryHandlerLevels.PRISTINE, eInjuryHandlerLevels.RUINED);
  455. RegisterNetSyncVariableInt("m_MixedSoundStates", 0, eMixedSoundStates.COUNT - 1);
  456. RegisterNetSyncVariableInt("m_CorpseState",-PlayerConstants.CORPSE_STATE_DECAYED,PlayerConstants.CORPSE_STATE_DECAYED);//do note the negative min, negative sign denotes a special meaning
  457. RegisterNetSyncVariableInt("m_RefreshAnimStateIdx",0,3);
  458. RegisterNetSyncVariableInt("m_BrokenLegState", -eBrokenLegs.BROKEN_LEGS_SPLINT, eBrokenLegs.BROKEN_LEGS_SPLINT);
  459. RegisterNetSyncVariableInt("m_SyncedModifiers", 0, ((eModifierSyncIDs.LAST_INDEX - 1) * 2) - 1);
  460. RegisterNetSyncVariableInt("m_HasBloodyHandsVisible", 0, eBloodyHandsTypes.LAST_INDEX - 1);
  461. RegisterNetSyncVariableInt("m_ActionSoundCategoryHash");
  462. RegisterNetSyncVariableInt("m_PerformedAnimActionID", -1, 2048); // generous upper limit for modding reasons
  463. RegisterNetSyncVariableInt("m_ActivePrimarySymptomID", 0, SymptomIDs.LAST_INDEX);
  464. RegisterNetSyncVariableInt("m_HeatBufferStage", 0, HeatBufferMdfr.NUMBER_OF_STAGES - 1);
  465. RegisterNetSyncVariableFloat("m_HeatBufferDynamicMax", 0.0, 1.0, 2);
  466. RegisterNetSyncVariableBool("m_IsUnconscious");
  467. RegisterNetSyncVariableBool("m_IsRestrained");
  468. RegisterNetSyncVariableBool("m_IsInWater");
  469. RegisterNetSyncVariableBool("m_InsideEffectArea");
  470. RegisterNetSyncVariableBool("m_HasBloodTypeVisible");
  471. RegisterNetSyncVariableBool("m_IsRestrainStarted");
  472. RegisterNetSyncVariableBool("m_IsRestrainPrelocked");
  473. RegisterNetSyncVariableBool("m_HasHeatBuffer");
  474. RegisterNetSyncVariableBool("m_IsInColdArea");
  475. RegisterNetSyncVariableFloat("m_CurrentShock"); //Register shock synchronized variable
  476. m_OriginalSlidePoseAngle = GetSlidePoseAngle();
  477. //! sets default hit position and cache it here (mainly for impact particles)
  478. m_DefaultHitPosition = SetDefaultHitPosition(GetDayZPlayerType().GetDefaultHitPositionComponent());
  479. m_DecayedTexture = ConfigGetString("decayedTexture");
  480. m_FliesIndex = -1;
  481. GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).Call(this.OnPlayerLoaded);
  482. }
  483. ScriptInvoker GetOnUnconsciousStart()
  484. {
  485. if (!m_OnUnconsciousStart)
  486. m_OnUnconsciousStart = new ScriptInvoker();
  487. return m_OnUnconsciousStart;
  488. }
  489. ScriptInvoker GetOnUnconsciousStop()
  490. {
  491. if (!m_OnUnconsciousStop)
  492. m_OnUnconsciousStop = new ScriptInvoker();
  493. return m_OnUnconsciousStop;
  494. }
  495. void AddMedicalDrugsInUse(EMedicalDrugsType drugType)
  496. {
  497. if ((m_MedicalDrugsActive & drugType) != drugType)
  498. m_MedicalDrugsActive = m_MedicalDrugsActive | drugType;
  499. }
  500. void RemoveMedicalDrugsInUse(EMedicalDrugsType drugType)
  501. {
  502. if ((m_MedicalDrugsActive & drugType) == drugType)
  503. m_MedicalDrugsActive &= ~drugType;
  504. }
  505. bool IsChelationActive()
  506. {
  507. return (m_MedicalDrugsActive & EMedicalDrugsType.CHELATION) == EMedicalDrugsType.CHELATION;
  508. }
  509. bool IsAntibioticsActive()
  510. {
  511. return (m_MedicalDrugsActive & EMedicalDrugsType.ANTIBIOTICS) == EMedicalDrugsType.ANTIBIOTICS;
  512. }
  513. void SetSoundCategoryHash(int hash)
  514. {
  515. m_ActionSoundCategoryHash = hash;
  516. SetSynchDirty();
  517. }
  518. void SetPerformedActionID(int id)
  519. {
  520. m_PerformedAnimActionID = id;
  521. SetSynchDirty();
  522. }
  523. int GetPerformedActionID()
  524. {
  525. return m_PerformedAnimActionID;
  526. }
  527. void SetActivePrimarySymptomID(SymptomIDs id)
  528. {
  529. m_ActivePrimarySymptomID = id;
  530. SetSynchDirty();
  531. }
  532. SymptomIDs GetActivePrimarySymptomID()
  533. {
  534. return m_ActivePrimarySymptomID;
  535. }
  536. void RequestTriggerEffect(EffectTrigger trigger, int ppeIdx = -1, int aroundId = ParticleList.CONTAMINATED_AREA_GAS_AROUND, int tinyId = ParticleList.CONTAMINATED_AREA_GAS_TINY, string soundset = "", bool partDynaUpdate = false, int newBirthRate = 0, bool forceUpdate = false)
  537. {
  538. //do note multiple triggers can be calling this method within a single frame depending on the contaminated area setup and dynamic gameplay events(such as gas grenades being deployed)
  539. if (!m_InsideEffectArea)
  540. return;
  541. bool allow = false;
  542. if (!m_CurrentEffectTrigger)
  543. {
  544. allow = true;
  545. }
  546. else if (trigger == m_CurrentEffectTrigger && forceUpdate)
  547. {
  548. allow = true;
  549. //Print("ON Enabling effect FORCED " + trigger);
  550. }
  551. else if (trigger.GetEffectsPriority() > m_CurrentEffectTrigger.GetEffectsPriority())
  552. {
  553. RemoveCurrentEffectTrigger();
  554. allow = true;
  555. }
  556. if (allow)
  557. {
  558. /*
  559. Print("--------------------------------------------------");
  560. Print("ON Enabling effect " + trigger);
  561. Print("------------> soundset " + soundset);
  562. Print("--------------------------------------------------");
  563. */
  564. m_CurrentEffectTrigger = trigger;
  565. SetContaminatedEffectEx( true, ppeIdx, aroundId, tinyId, soundset,partDynaUpdate, newBirthRate );
  566. }
  567. }
  568. void RemoveCurrentEffectTrigger()
  569. {
  570. if (m_CurrentEffectTrigger)
  571. {
  572. /*
  573. Print("--------------------------------------------------");
  574. Print("OFF Disabling effect");
  575. Print("--------------------------------------------------");
  576. */
  577. SetContaminatedEffectEx( false, m_CurrentEffectTrigger.m_PPERequester );
  578. m_CurrentEffectTrigger = null;
  579. }
  580. }
  581. void IncreaseContaminatedAreaCount()
  582. {
  583. if (m_ContaminatedAreaCount == 0)
  584. OnContaminatedAreaEnterServer();
  585. m_ContaminatedAreaCount++;
  586. }
  587. void DecreaseContaminatedAreaCount()
  588. {
  589. m_ContaminatedAreaCount--;
  590. if (m_ContaminatedAreaCount <= 0)
  591. {
  592. m_ContaminatedAreaCount = 0;
  593. OnContaminatedAreaExitServer();
  594. }
  595. }
  596. void IncreaseEffectAreaCount()
  597. {
  598. if (m_EffectAreaCount == 0)
  599. {
  600. m_InsideEffectArea = true;
  601. SetSynchDirty();
  602. OnPlayerIsNowInsideEffectAreaBeginServer();
  603. }
  604. m_EffectAreaCount++;
  605. }
  606. void DecreaseEffectAreaCount()
  607. {
  608. m_EffectAreaCount--;
  609. if (m_EffectAreaCount <= 0)
  610. {
  611. m_EffectAreaCount = 0;
  612. m_InsideEffectArea = false;
  613. SetSynchDirty();
  614. OnPlayerIsNowInsideEffectAreaEndServer();
  615. }
  616. }
  617. void SetInEffectAreaTypeFlag(EEffectAreaType flag)
  618. {
  619. int areaCount = m_EffectAreaOverlap.Get(flag);
  620. if (areaCount > 0)
  621. m_EffectAreaOverlap.Set(flag, m_EffectAreaOverlap.Get(flag) + 1);
  622. else
  623. m_EffectAreaOverlap.Set(flag, 1);
  624. m_InEffectAreaType |= flag;
  625. }
  626. void UnsetInEffectAreaTypeFlag(EEffectAreaType flag)
  627. {
  628. int areaCount = m_EffectAreaOverlap.Get(flag);
  629. if (areaCount > 1)
  630. m_EffectAreaOverlap.Set(flag, m_EffectAreaOverlap.Get(flag) - 1);
  631. else
  632. {
  633. m_EffectAreaOverlap.Set(flag, 0);
  634. m_InEffectAreaType &= ~flag;
  635. }
  636. }
  637. bool IsInEffectArea(EEffectAreaType area)
  638. {
  639. if (m_InEffectAreaType & area)
  640. return true;
  641. return false;
  642. }
  643. // Server side update when player is present in any effect area
  644. protected void OnUpdateEffectAreaServer(float timeSlice)
  645. {
  646. float timeSpent;
  647. if (IsInEffectArea(EEffectAreaType.HOT_SPRING))
  648. {
  649. float waterLevel = GetCurrentWaterLevel();
  650. if (waterLevel > 0.5)
  651. {
  652. timeSpent = m_EffectAreaTimeToTick.Get(EEffectAreaType.HOT_SPRING);
  653. timeSpent += timeSlice;
  654. if (timeSpent > HotSpringTrigger.HEAT_DAMAGE_TICK_TIME)
  655. {
  656. m_EffectAreaTimeToTick.Set(EEffectAreaType.HOT_SPRING, 0);
  657. HotSpringTrigger.ApplyEffects(this);
  658. }
  659. else
  660. m_EffectAreaTimeToTick.Set(EEffectAreaType.HOT_SPRING, timeSpent);
  661. }
  662. }
  663. if (IsInEffectArea(EEffectAreaType.VOLCANIC))
  664. {
  665. timeSpent = m_EffectAreaTimeToTick.Get(EEffectAreaType.VOLCANIC);
  666. timeSpent += timeSlice;
  667. if (timeSpent > VolcanicTrigger.HEAT_DAMAGE_TICK_TIME)
  668. {
  669. m_EffectAreaTimeToTick.Set(EEffectAreaType.VOLCANIC, 0);
  670. VolcanicTrigger.ApplyEffects(this);
  671. }
  672. else
  673. m_EffectAreaTimeToTick.Set(EEffectAreaType.VOLCANIC, timeSpent);
  674. }
  675. }
  676. protected void OnContaminatedAreaEnterServer()
  677. {
  678. GetModifiersManager().ActivateModifier( eModifiers.MDF_AREAEXPOSURE );
  679. //Print("Contaminated ENTERED <------------------------------------------------------------- FINAL");
  680. }
  681. protected void OnContaminatedAreaExitServer()
  682. {
  683. GetModifiersManager().DeactivateModifier( eModifiers.MDF_AREAEXPOSURE );
  684. //Print("Contaminated LEFT <------------------------------------------------------------- FINAL");
  685. }
  686. protected void OnPlayerIsNowInsideEffectAreaBeginServer()
  687. {
  688. //Print("ANY EFFECT AREA ENTERED <------------------------------------------------------------- FINAL");
  689. }
  690. protected void OnPlayerIsNowInsideEffectAreaEndServer()
  691. {
  692. //Print("ANY EFFECT AREA LEFT <------------------------------------------------------------- FINAL");
  693. }
  694. protected void OnPlayerIsNowInsideEffectAreaBeginClient()
  695. {
  696. //Print("ANY EFFECT AREA ENTERED CLIENT <------------------------------------------------------------- FINAL");
  697. }
  698. protected void OnPlayerIsNowInsideEffectAreaEndClient()
  699. {
  700. RemoveCurrentEffectTrigger();
  701. //Print("ANY EFFECT AREA LEFT CLIENT <------------------------------------------------------------- FINAL");
  702. }
  703. //! Returns item that's on this player's attachment slot. Parameter slot_type should be a string from config parameter 'itemInfo[]' like "Legs", "Headgear" and so on.
  704. ItemBase GetItemOnSlot(string slot_type)
  705. {
  706. int slot_id = InventorySlots.GetSlotIdFromString(slot_type);
  707. EntityAI item_EAI = this.GetInventory().FindAttachment(slot_id);
  708. ItemBase item_IB = ItemBase.Cast(item_EAI);
  709. if (item_EAI && !item_IB)
  710. {
  711. string str = "Warning! GetItemOnSlot() >> found item on slot " + slot_type + " can't be cast to ItemBase! Found item is " + item_EAI.GetType() + " and the player is " + GetType() + "!";
  712. Error(str);
  713. return null;
  714. }
  715. return item_IB;
  716. }
  717. //! Returns item on player's head. For an example, a headtorch.
  718. ItemBase GetItemOnHead()
  719. {
  720. return GetItemOnSlot("Headgear");
  721. }
  722. override int GetQuickBarBonus()
  723. {
  724. return m_QuickBarBonus;
  725. }
  726. //--------------------------------------------------------------------------
  727. // Inventory overrides
  728. //--------------------------------------------------------------------------
  729. override bool CanDropEntity (notnull EntityAI item)
  730. {
  731. if (GetInventory().HasInventoryReservation(item, null))
  732. {
  733. return false;
  734. }
  735. if (IsRestrained())
  736. {
  737. if (GetHumanInventory().GetEntityInHands() == item)
  738. return false;
  739. }
  740. return true;
  741. }
  742. //--------------------------------------------------------------------------
  743. // PLAYER DAMAGE EVENT HANDLING
  744. //--------------------------------------------------------------------------
  745. int GetBreathVapourLevel()
  746. {
  747. return m_BreathVapour;
  748. }
  749. // adds state to and syncs sound states variable which is used to generate sound client-side
  750. void UnsetMixedSoundState(eMixedSoundStates state)
  751. {
  752. int bit_mask_remove = ~state;
  753. eMixedSoundStates new_states = m_MixedSoundStates & bit_mask_remove;
  754. if (new_states != m_MixedSoundStates)
  755. {
  756. m_MixedSoundStates = new_states;
  757. SetSynchDirty();
  758. }
  759. }
  760. // adds state to and syncs sound states variable which is used to generate sound client-side
  761. void SetMixedSoundState(eMixedSoundStates state)
  762. {
  763. eMixedSoundStates new_states = m_MixedSoundStates | state;
  764. if (new_states != m_MixedSoundStates)
  765. {
  766. m_MixedSoundStates = new_states;
  767. SetSynchDirty();
  768. }
  769. }
  770. override bool IsPlayer()
  771. {
  772. return true;
  773. }
  774. bool IsBleeding()
  775. {
  776. return (m_BleedingBits != 0);
  777. }
  778. void SetBleedingBits(int bits)
  779. {
  780. if (m_BleedingBits != bits)
  781. {
  782. if (m_BleedingBits == 0)
  783. {
  784. OnBleedingBegin();
  785. }
  786. else if (bits == 0)
  787. {
  788. OnBleedingEnd();
  789. }
  790. }
  791. m_BleedingBits = bits;
  792. SetSynchDirty();
  793. }
  794. int GetBleedingBits()
  795. {
  796. return m_BleedingBits;
  797. }
  798. void IncreaseDiseaseCount()
  799. {
  800. m_DiseaseCount++;
  801. }
  802. void DecreaseDiseaseCount()
  803. {
  804. m_DiseaseCount--;
  805. }
  806. void IncreaseHealingsCount()
  807. {
  808. m_HealingsCount++;
  809. }
  810. void DecreaseHealingsCount()
  811. {
  812. m_HealingsCount--;
  813. }
  814. bool HasHealings()
  815. {
  816. return m_HealingsCount;//0 for no healings, 1+ for healings, gets truncated to 1
  817. }
  818. bool HasDisease()
  819. {
  820. return m_DiseaseCount;//0 for no disease, 1+ for disease, gets truncated to 1
  821. }
  822. EPulseType GetPulseType()
  823. {
  824. return m_PulseType;
  825. }
  826. void SetPulseType(EPulseType pulse_type)
  827. {
  828. m_PulseType = pulse_type;
  829. }
  830. void QueueAddEffectWidget(array<int> effects)
  831. {
  832. m_ProcessAddEffectWidgets.InsertArray(effects);
  833. }
  834. void QueueRemoveEffectWidget(array<int> effects)
  835. {
  836. m_ProcessRemoveEffectWidgets.InsertArray(effects);
  837. }
  838. void QueueAddGlassesEffect(int id)
  839. {
  840. m_ProcessAddGlassesEffects.Insert(id);
  841. }
  842. void QueueRemoveGlassesEffect(int id)
  843. {
  844. m_ProcessRemoveGlassesEffects.Insert(id);
  845. }
  846. DamageDealtEffect GetDamageDealtEffect()
  847. {
  848. return m_DamageDealtEffect;
  849. }
  850. override void SpawnDamageDealtEffect()
  851. {
  852. if (m_DamageDealtEffect)
  853. {
  854. delete m_DamageDealtEffect;
  855. }
  856. if (m_CanDisplayHitEffectPPE)
  857. {
  858. m_DamageDealtEffect = new DamageDealtEffect();
  859. }
  860. }
  861. void SpawnDamageDealtEffect2(Param param1 = null, Param param2 = null)
  862. {
  863. if (m_EffectRadial)
  864. {
  865. delete m_EffectRadial;
  866. }
  867. m_EffectRadial = new EffectRadial(param1,param2);
  868. }
  869. FlashbangEffect GetFlashbangEffect()
  870. {
  871. return m_FlashbangEffect;
  872. }
  873. void SpawnFlashbangEffect(PlayerBase player, bool visual)
  874. {
  875. if (m_FlashbangEffect)
  876. {
  877. m_FlashbangEffect.Stop();
  878. delete m_FlashbangEffect;
  879. }
  880. m_FlashbangEffect = new FlashbangEffect(player, visual);
  881. }
  882. ShockDealtEffect GetShockEffect()
  883. {
  884. return m_ShockDealtEffect;
  885. }
  886. void SpawnShockEffect(float intensity_max)
  887. {
  888. if (m_ShockDealtEffect)
  889. {
  890. delete m_ShockDealtEffect;
  891. }
  892. m_ShockDealtEffect = new ShockDealtEffect(intensity_max);
  893. }
  894. override void EEKilled(Object killer)
  895. {
  896. //Print(Object.GetDebugName(this) + " STS=" + GetSimulationTimeStamp() + " event EEKilled, player has died at STS=" + GetSimulationTimeStamp());
  897. if (m_AdminLog)
  898. {
  899. m_AdminLog.PlayerKilled(this, killer);
  900. }
  901. if (GetBleedingManagerServer())
  902. delete GetBleedingManagerServer();
  903. // kill character in database
  904. if (GetHive())
  905. {
  906. GetHive().CharacterKill(this);
  907. }
  908. // disable voice communication
  909. GetGame().EnableVoN(this, false);
  910. if (!GetGame().IsDedicatedServer())
  911. ClientData.RemovePlayerBase(this);
  912. GetSymptomManager().OnPlayerKilled();
  913. if (GetEconomyProfile() && !m_CorpseProcessing && m_CorpseState == 0 && GetGame().GetMission().InsertCorpse(this))
  914. {
  915. m_CorpseProcessing = true;
  916. //Print("EEKilled - processing corpse");
  917. }
  918. if (GetGame().IsMultiplayer() && GetGame().IsServer())
  919. {
  920. if (GetGame().GetMission())
  921. {
  922. GetGame().GetMission().SyncRespawnModeInfo(GetIdentity());
  923. }
  924. }
  925. super.EEKilled(killer);
  926. }
  927. override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
  928. {
  929. super.EEHitBy(damageResult, damageType, source, component, dmgZone, ammo, modelPos, speedCoef);
  930. if (m_AdminLog)
  931. {
  932. m_AdminLog.PlayerHitBy(damageResult, damageType, this, source, component, dmgZone, ammo);
  933. }
  934. if (damageResult != null && damageResult.GetDamage(dmgZone, "Shock") > 0)
  935. {
  936. m_LastShockHitTime = GetGame().GetTime();
  937. if (!IsUnconscious())
  938. {
  939. if (GetGame().ConfigIsExisting("cfgAmmo " + ammo + " unconRefillModifier"))
  940. {
  941. m_UnconRefillModifier = GetGame().ConfigGetInt("cfgAmmo " + ammo + " unconRefillModifier");
  942. }
  943. else
  944. {
  945. m_UnconRefillModifier = 1;
  946. }
  947. }
  948. }
  949. //! DT_EXPLOSION & FlashGrenade
  950. if (damageType == DT_EXPLOSION && ammo == "FlashGrenade_Ammo")
  951. {
  952. GetStaminaHandler().DepleteStamina(EStaminaModifiers.OVERALL_DRAIN);
  953. }
  954. //new bleeding computation
  955. //---------------------------------------
  956. if (damageResult != null && GetBleedingManagerServer())
  957. {
  958. float dmg = damageResult.GetDamage(dmgZone, "Blood");
  959. GetBleedingManagerServer().ProcessHit(dmg, source, component, dmgZone, ammo, modelPos);
  960. }
  961. //---------------------------------------
  962. #ifdef DIAG_DEVELOPER
  963. if (DiagMenu.GetBool(DiagMenuIDs.MELEE_DEBUG))
  964. Print("EEHitBy() | " + GetDisplayName() + " hit by " + source.GetDisplayName() + " to " + dmgZone);
  965. PluginRemotePlayerDebugServer plugin_remote_server = PluginRemotePlayerDebugServer.Cast(GetPlugin(PluginRemotePlayerDebugServer));
  966. if (plugin_remote_server)
  967. {
  968. plugin_remote_server.OnDamageEvent(this, damageResult);
  969. }
  970. #endif
  971. if (GetGame().IsDebugMonitor())
  972. m_DebugMonitorValues.SetLastDamage(source.GetDisplayName());
  973. if (m_ActionManager)
  974. m_ActionManager.Interrupt();
  975. int transferShockToDamageCoef = g_Game.ConfigGetInt(string.Format("%1 %2 DamageApplied transferShockToDamage", CFG_AMMO, ammo));
  976. if (transferShockToDamageCoef == 1)
  977. {
  978. //Print("PlayerBase | EEHitBy | nonlethal hit");
  979. AddHealth("", "Health", -ConvertNonlethalDamage(damageResult.GetDamage(dmgZone, "Shock"), damageType));
  980. if (dmgZone != "Head")
  981. AddHealth(dmgZone, "Health", -damageResult.GetDamage(dmgZone, "Shock")); //Also deal damage to zone health, no dmg reduction
  982. }
  983. if (GetGame().IsServer())
  984. {
  985. if (GetHealth("RightLeg", "Health") <= 1 || GetHealth("LeftLeg", "Health") <= 1 || GetHealth("RightFoot", "Health") <= 1 || GetHealth("LeftFoot", "Health") <= 1)
  986. {
  987. if (GetModifiersManager().IsModifierActive(eModifiers.MDF_BROKEN_LEGS))//effectively resets the modifier
  988. {
  989. GetModifiersManager().DeactivateModifier(eModifiers.MDF_BROKEN_LEGS);
  990. }
  991. GetModifiersManager().ActivateModifier(eModifiers.MDF_BROKEN_LEGS);
  992. }
  993. if (ammo == "Bullet_CupidsBolt" && IsAlive())
  994. {
  995. DamageSystem.ResetAllZones(this);
  996. m_ModifiersManager.ResetAll();
  997. m_ModifiersManager.ActivateModifier(eModifiers.MDF_IMMUNITYBOOST);
  998. // bleeding sources
  999. if (m_BleedingManagerServer)
  1000. m_BleedingManagerServer.RemoveAllSources();
  1001. // Stats
  1002. if (GetPlayerStats())
  1003. {
  1004. int bloodType = GetStatBloodType().Get();
  1005. float energyValue = GetStatEnergy().Get();
  1006. float waterValue = GetStatWater().Get();
  1007. float heatBuffer = GetStatHeatBuffer().Get();
  1008. float heatComfort = GetStatHeatComfort().Get();
  1009. GetPlayerStats().ResetAllStats();
  1010. GetStatBloodType().Set(bloodType);
  1011. GetStatWater().Set(waterValue);
  1012. GetStatEnergy().Set(energyValue);
  1013. GetStatHeatBuffer().Set(heatBuffer);
  1014. GetStatHeatComfort().Set(heatComfort);
  1015. }
  1016. // Agents
  1017. if (m_AgentPool)
  1018. m_AgentPool.RemoveAllAgents();
  1019. if (m_StaminaHandler)
  1020. m_StaminaHandler.SetStamina(GameConstants.STAMINA_MAX);
  1021. // uncon
  1022. if (IsUnconscious())
  1023. DayZPlayerSyncJunctures.SendPlayerUnconsciousness(this, false);
  1024. }
  1025. }
  1026. m_ShockHandler.CheckValue(true);
  1027. //analytics
  1028. GetGame().GetAnalyticsServer().OnEntityHit(source, this);
  1029. }
  1030. override void EEHitByRemote(int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos)
  1031. {
  1032. super.EEHitByRemote(damageType, source, component, dmgZone, ammo, modelPos);
  1033. if (m_MeleeFightLogic.IsInBlock())
  1034. {
  1035. EffectSound sound = SEffectManager.PlaySoundOnObject("BlockingAttack_SoundSet", this);
  1036. sound.SetAutodestroy(true);
  1037. }
  1038. }
  1039. override void EEDelete(EntityAI parent)
  1040. {
  1041. SEffectManager.DestroyEffect(m_FliesEff);
  1042. StopSoundSet(m_SoundFliesEffect);
  1043. if (GetArrowManager())
  1044. GetArrowManager().ClearArrows();
  1045. }
  1046. override protected float ConvertNonlethalDamage(float damage, DamageType damageType)
  1047. {
  1048. if (damageType == DamageType.FIRE_ARM)
  1049. return damage * GameConstants.NL_DAMAGE_FIREARM_CONVERSION_PLAYERS;
  1050. return super.ConvertNonlethalDamage(damage, damageType);
  1051. }
  1052. /** Call only on client or single player PlayerBase
  1053. * (as GetGame().GetPlayer())
  1054. */
  1055. override void OnReceivedHit(ImpactEffectsData hitData)
  1056. {
  1057. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  1058. {
  1059. float shakeStrength = Math.InverseLerp(0, 500, hitData.m_InSpeed.Length());
  1060. GetCurrentCamera().SpawnCameraShake(shakeStrength);
  1061. OnPlayerRecievedHit();
  1062. }
  1063. if (hitData.m_AmmoType == "Bullet_CupidsBolt")
  1064. Ammo_CupidsBolt.PlayOnHitParticle(hitData.m_Position);
  1065. }
  1066. // DEPRECATED by method OnReceivedHit
  1067. override void OnPlayerRecievedHit()
  1068. {
  1069. #ifndef NO_GUI
  1070. if (m_MeleeFightLogic.IsInBlock())
  1071. {
  1072. EffectSound sound = SEffectManager.PlaySoundOnObject("BlockingAttack_SoundSet", this);
  1073. sound.SetAutodestroy(true);
  1074. return;
  1075. }
  1076. SpawnDamageDealtEffect();
  1077. CachedObjectsParams.PARAM2_FLOAT_FLOAT.param1 = 32;
  1078. CachedObjectsParams.PARAM2_FLOAT_FLOAT.param2 = 0.3;
  1079. SpawnDamageDealtEffect2(CachedObjectsParams.PARAM2_FLOAT_FLOAT);
  1080. CloseMapEx(true);
  1081. #endif
  1082. }
  1083. void OnPlayerReceiveFlashbangHitStart(bool visual)
  1084. {
  1085. SpawnFlashbangEffect(this, visual);
  1086. }
  1087. void OnPlayerReceiveFlashbangHitEnd() {}
  1088. //--------------------------------------------------------------------------
  1089. //! Melee helpers
  1090. //--------------------------------------------------------------------------
  1091. //! select & return hit component for attacking AI
  1092. override string GetHitComponentForAI()
  1093. {
  1094. return GetDayZPlayerType().GetHitComponentForAI();
  1095. }
  1096. //! returns default hit component (fallback)
  1097. override string GetDefaultHitComponent()
  1098. {
  1099. return GetDayZPlayerType().GetDefaultHitComponent();
  1100. }
  1101. override vector GetDefaultHitPosition()
  1102. {
  1103. return m_DefaultHitPosition;
  1104. }
  1105. //! returns list of suitable finisher hit components (defined on base entity/entity type)
  1106. override array<string> GetSuitableFinisherHitComponents()
  1107. {
  1108. return GetDayZPlayerType().GetSuitableFinisherHitComponents();
  1109. }
  1110. protected vector SetDefaultHitPosition(string pSelection)
  1111. {
  1112. return GetSelectionPositionMS(pSelection);
  1113. }
  1114. //--------------------------------------------------------------------------
  1115. //!DEPRECATED!
  1116. void AddPossibleCoverFaceForShave()
  1117. {
  1118. m_FaceCoveredForShaveLayers++;
  1119. }
  1120. //!DEPRECATED!
  1121. void RemovePossibleCoverFaceForShave()
  1122. {
  1123. m_FaceCoveredForShaveLayers--;
  1124. }
  1125. //--------------------------------------------------------------------------
  1126. override void EEItemAttached(EntityAI item, string slot_name)
  1127. {
  1128. super.EEItemAttached(item, slot_name);
  1129. ItemBase itemIB = ItemBase.Cast(item);
  1130. SwitchItemSelectionTexture(item, slot_name);
  1131. Param1<PlayerBase> p = new Param1<PlayerBase>(this);
  1132. item.SwitchItemSelectionTextureEx(EItemManipulationContext.ATTACHING, p);
  1133. m_QuickBarBase.updateSlotsCount();
  1134. CalculateVisibilityForAI();
  1135. UpdateShoulderProxyVisibility(item, slot_name);
  1136. HideHairSelections(itemIB,true);
  1137. GetGame().GetAnalyticsClient().OnItemAttachedAtPlayer(item, slot_name);
  1138. Clothing clothing = Clothing.Cast(item);
  1139. if (clothing)
  1140. {
  1141. if (!GetGame().IsDedicatedServer())
  1142. {
  1143. if (clothing.GetEffectWidgetTypes())
  1144. {
  1145. QueueAddEffectWidget(clothing.GetEffectWidgetTypes());
  1146. }
  1147. if (clothing.GetGlassesEffectID() > -1)
  1148. {
  1149. QueueAddGlassesEffect(clothing.GetGlassesEffectID());
  1150. }
  1151. GetGame().GetCallQueue(CALL_CATEGORY_GUI).CallLater(UpdateCorpseStateVisual, 200, false);//sometimes it takes a while to load in
  1152. UpdateCorpseStateVisual();//....but if possible, we don't want a delay
  1153. }
  1154. else if (GetGame().IsServer())
  1155. {
  1156. if (clothing.IsGasMask())
  1157. {
  1158. GetModifiersManager().ActivateModifier(eModifiers.MDF_MASK);
  1159. }
  1160. }
  1161. clothing.UpdateNVGStatus(this,true);
  1162. }
  1163. AdjustBandana(item,slot_name);
  1164. AdjustShemag(item,slot_name);
  1165. }
  1166. override void EEItemDetached(EntityAI item, string slot_name)
  1167. {
  1168. super.EEItemDetached(item, slot_name);
  1169. ItemBase item_base = ItemBase.Cast(item);
  1170. SwitchItemSelectionTexture(item, slot_name);
  1171. item.SwitchItemSelectionTextureEx(EItemManipulationContext.DETACHING);
  1172. m_QuickBarBase.updateSlotsCount();
  1173. CalculateVisibilityForAI();
  1174. HideHairSelections(item_base,false);
  1175. Clothing clothing = Clothing.Cast(item);
  1176. if (clothing)
  1177. {
  1178. if (!GetGame().IsDedicatedServer())
  1179. {
  1180. if (clothing.GetEffectWidgetTypes())
  1181. {
  1182. QueueRemoveEffectWidget(clothing.GetEffectWidgetTypes());
  1183. }
  1184. if (clothing.GetGlassesEffectID() > -1)
  1185. {
  1186. QueueRemoveGlassesEffect(clothing.GetGlassesEffectID());
  1187. }
  1188. }
  1189. if (GetGame().IsServer())
  1190. {
  1191. if (clothing.IsGasMask())
  1192. {
  1193. GetModifiersManager().DeactivateModifier(eModifiers.MDF_MASK);
  1194. }
  1195. }
  1196. clothing.UpdateNVGStatus(this);
  1197. GetGame().GetCallQueue(CALL_CATEGORY_GUI).CallLater(UpdateCorpseStateVisual, 200, false);//sometimes it takes a while to load in
  1198. UpdateCorpseStateVisual();//....but if possible, we don't want a delay
  1199. }
  1200. }
  1201. void UpdateShoulderProxyVisibility(EntityAI item, string slot_name)
  1202. {
  1203. string slot = slot_name;
  1204. bool boo;
  1205. boo = item.IsWeapon();
  1206. if (slot == "Melee")
  1207. {
  1208. SetSimpleHiddenSelectionState(SIMPLE_SELECTION_MELEE_RIFLE,boo);
  1209. SetSimpleHiddenSelectionState(SIMPLE_SELECTION_MELEE_MELEE,!boo);
  1210. }
  1211. else if (slot == "Shoulder")
  1212. {
  1213. SetSimpleHiddenSelectionState(SIMPLE_SELECTION_SHOULDER_RIFLE,boo);
  1214. SetSimpleHiddenSelectionState(SIMPLE_SELECTION_SHOULDER_MELEE,!boo);
  1215. }
  1216. }
  1217. override void SwitchItemSelectionTexture(EntityAI item, string slot_name)
  1218. {
  1219. super.SwitchItemSelectionTexture(item,slot_name);
  1220. //shirt + armband
  1221. EntityAI armband = FindAttachmentBySlotName("Armband");
  1222. if (slot_name == "Body" && armband)
  1223. {
  1224. Param1<PlayerBase> p = new Param1<PlayerBase>(this);
  1225. armband.SwitchItemSelectionTextureEx(EItemManipulationContext.UPDATE,p);
  1226. }
  1227. }
  1228. void RemoveAllItems()
  1229. {
  1230. array<EntityAI> itemsArray = new array<EntityAI>;
  1231. ItemBase item;
  1232. GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER, itemsArray);
  1233. for (int i = 0; i < itemsArray.Count(); i++)
  1234. {
  1235. Class.CastTo(item, itemsArray.Get(i));
  1236. if (item && !item.IsInherited(SurvivorBase)) GetInventory().LocalDestroyEntity(item);
  1237. }
  1238. }
  1239. bool GetHitPPEEnabled()
  1240. {
  1241. return m_CanDisplayHitEffectPPE;
  1242. }
  1243. void SetHitPPEEnabled(bool enabled)
  1244. {
  1245. m_CanDisplayHitEffectPPE = enabled;
  1246. }
  1247. bool IsMale()
  1248. {
  1249. if (ConfigGetBool("woman") != 1)
  1250. {
  1251. return true;
  1252. }
  1253. return false;
  1254. }
  1255. int GetVoiceType()
  1256. {
  1257. int voice_type = ConfigGetInt("voiceType");
  1258. if (voice_type == 0)
  1259. {
  1260. voice_type = 1;
  1261. }
  1262. return voice_type;
  1263. }
  1264. PlayerSoundManagerServer GetPlayerSoundManagerServer()
  1265. {
  1266. return m_PlayerSoundManagerServer;
  1267. }
  1268. UndergroundHandlerClient GetUndergroundHandler()
  1269. {
  1270. if (!m_UndergroundHandler && IsAlive())
  1271. {
  1272. m_UndergroundHandler = new UndergroundHandlerClient(this);
  1273. }
  1274. return m_UndergroundHandler;
  1275. }
  1276. UndergroundBunkerHandlerClient GetUndergroundBunkerHandler()
  1277. {
  1278. if (!m_UndergroundBunkerHandler && IsAlive())
  1279. {
  1280. m_UndergroundBunkerHandler = new UndergroundBunkerHandlerClient(this);
  1281. }
  1282. return m_UndergroundBunkerHandler;
  1283. }
  1284. void KillUndergroundHandler()
  1285. {
  1286. m_UndergroundHandler = null;
  1287. m_UndergroundBunkerHandler = null;
  1288. }
  1289. // --------------------------------------------------
  1290. // User Actions
  1291. //---------------------------------------------------
  1292. void SetActions(out TInputActionMap InputActionMap)
  1293. {
  1294. AddAction(ActionOpenDoors, InputActionMap);
  1295. AddAction(ActionCloseDoors, InputActionMap);
  1296. AddAction(ActionLockedDoors, InputActionMap);
  1297. AddAction(ActionEnterLadder, InputActionMap);
  1298. AddAction(ActionExitLadder, InputActionMap);
  1299. //-----------CheckIfCanMOveToTarget----------
  1300. AddAction(ActionStartEngine, InputActionMap);
  1301. AddAction(ActionStartEngineBoat, InputActionMap);
  1302. AddAction(ActionStopEngine, InputActionMap);
  1303. AddAction(ActionStopEngineBoat, InputActionMap);
  1304. AddAction(ActionSwitchSeats, InputActionMap);
  1305. AddAction(ActionOpenCarDoors,InputActionMap);
  1306. AddAction(ActionCloseCarDoors,InputActionMap);
  1307. AddAction(ActionUncoverHeadSelf, InputActionMap);
  1308. AddAction(ActionDrinkPondContinuous, InputActionMap);
  1309. AddAction(ActionEatSnowContinuous, InputActionMap);
  1310. AddAction(ActionIgniteFireplaceByAir, InputActionMap);
  1311. AddAction(ActionMineBushByHand, InputActionMap);
  1312. AddAction(ActionUngagSelf, InputActionMap);
  1313. AddAction(ActionWashHandsWater, InputActionMap);
  1314. AddAction(ActionWashHandsSnow, InputActionMap);
  1315. AddAction(ActionGetOutTransport, InputActionMap);
  1316. AddAction(ActionUnrestrainTargetHands, InputActionMap);
  1317. AddAction(ActionTakeArrow, InputActionMap);
  1318. AddAction(ActionTakeArrowToHands, InputActionMap);
  1319. AddAction(ActionOperatePanelPowerStation, InputActionMap);
  1320. }
  1321. void SetActions() // Backwards compatibility, not recommended to use
  1322. {
  1323. }
  1324. void SetActionsRemoteTarget(out TInputActionMap InputActionMap)
  1325. {
  1326. AddAction(ActionCPR, InputActionMap);
  1327. AddAction(ActionUncoverHeadTarget, InputActionMap);
  1328. AddAction(ActionUngagTarget, InputActionMap);
  1329. AddAction(ActionPullBodyFromTransport, InputActionMap);
  1330. AddAction(ActionCheckPulseTarget, InputActionMap);
  1331. }
  1332. void SetActionsRemoteTarget() // Backwards compatibility, not recommended to use
  1333. {
  1334. }
  1335. void InitializeActions()
  1336. {
  1337. // Backwards compatibility
  1338. if (IsControlledPlayer())
  1339. {
  1340. m_InputActionMap = new TInputActionMap;
  1341. SetActions();
  1342. }
  1343. else
  1344. {
  1345. m_InputActionMap = new TInputActionMap;
  1346. SetActionsRemoteTarget();
  1347. }
  1348. //////////////////////////
  1349. m_InputActionMapControled = new TInputActionMap;
  1350. SetActions(m_InputActionMapControled);
  1351. m_InputActionMapAsTarget = new TInputActionMap;
  1352. SetActionsRemoteTarget(m_InputActionMapAsTarget);
  1353. }
  1354. override void GetActions(typename action_input_type, out array<ActionBase_Basic> actions)
  1355. {
  1356. if (!m_ActionsInitialize)
  1357. {
  1358. m_ActionsInitialize = true;
  1359. InitializeActions();
  1360. }
  1361. // Backwards compatibility
  1362. array<ActionBase_Basic> bcActions = m_InputActionMap.Get(action_input_type);
  1363. if (!bcActions)
  1364. {
  1365. if (IsControlledPlayer())
  1366. actions = m_InputActionMapControled.Get(action_input_type);
  1367. else
  1368. actions = m_InputActionMapAsTarget.Get(action_input_type);
  1369. }
  1370. else
  1371. {
  1372. if (!actions)
  1373. actions = new array<ActionBase_Basic>();
  1374. if (IsControlledPlayer())
  1375. actions.InsertAll(m_InputActionMapControled.Get(action_input_type));
  1376. else
  1377. actions.InsertAll(m_InputActionMapAsTarget.Get(action_input_type));
  1378. actions.InsertAll(bcActions);
  1379. }
  1380. }
  1381. void AddAction(typename actionName, out TInputActionMap InputActionMap)
  1382. {
  1383. ActionBase action = GetActionManager().GetAction(actionName);
  1384. typename ai = action.GetInputType();
  1385. if (!ai)
  1386. {
  1387. m_ActionsInitialize = false;
  1388. return;
  1389. }
  1390. ref array<ActionBase_Basic> action_array = InputActionMap.Get(ai);
  1391. if (!action_array)
  1392. {
  1393. action_array = new array<ActionBase_Basic>;
  1394. InputActionMap.Insert(ai, action_array);
  1395. }
  1396. action_array.Insert(action);
  1397. }
  1398. void AddAction(typename actionName) // Backwards compatibility, not recommended to use
  1399. {
  1400. AddAction(actionName, m_InputActionMap);
  1401. }
  1402. void RemoveAction(typename actionName, out TInputActionMap InputActionMap)
  1403. {
  1404. ActionBase action = GetActionManager().GetAction(actionName);
  1405. typename ai = action.GetInputType();
  1406. ref array<ActionBase_Basic> action_array = InputActionMap.Get(ai);
  1407. if (action_array)
  1408. {
  1409. for (int i = 0; i < action_array.Count(); i++)
  1410. {
  1411. if (action == action_array.Get(i))
  1412. {
  1413. action_array.Remove(i);
  1414. }
  1415. }
  1416. action_array = new array<ActionBase_Basic>;
  1417. InputActionMap.Insert(ai, action_array);
  1418. }
  1419. action_array.Insert(action);
  1420. }
  1421. void RemoveAction(typename actionName) // Backwards compatibility, not recommended to use
  1422. {
  1423. RemoveAction(actionName, m_InputActionMap);
  1424. }
  1425. int GetCurrentRecipe()
  1426. {
  1427. return m_RecipePick;
  1428. }
  1429. void SetNextRecipe()
  1430. {
  1431. m_RecipePick++;
  1432. }
  1433. void SetFirstRecipe()
  1434. {
  1435. m_RecipePick = 0;
  1436. }
  1437. //---------------------------------------------------
  1438. ActionManagerBase GetActionManager()
  1439. {
  1440. return m_ActionManager;
  1441. }
  1442. EmoteManager GetEmoteManager()
  1443. {
  1444. return m_EmoteManager;
  1445. }
  1446. RandomGeneratorSyncManager GetRandomGeneratorSyncManager()
  1447. {
  1448. return m_RGSManager;
  1449. }
  1450. //!called every command handler tick when player is on ladder
  1451. override void OnLadder(float delta_time, HumanMovementState pState)
  1452. {
  1453. ProcessHandDamage(delta_time, pState);
  1454. }
  1455. void ProcessHandDamage(float delta_time, HumanMovementState pState)
  1456. {
  1457. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER || !GetGame().IsMultiplayer())
  1458. {
  1459. if (pState.m_iMovement == DayZPlayerConstants.MOVEMENTIDX_SLIDE)
  1460. {
  1461. //Print("sliding down");
  1462. EntityAI gloves = GetInventory().FindAttachment(InventorySlots.GLOVES);
  1463. if (gloves && gloves.GetHealthLevel() < 4)
  1464. {
  1465. gloves.AddHealth("","", PlayerConstants.GLOVES_DAMAGE_SLIDING_LADDER_PER_SEC * delta_time);
  1466. return;
  1467. }
  1468. if (Math.RandomFloat01() < PlayerConstants.CHANCE_TO_BLEED_SLIDING_LADDER_PER_SEC * delta_time)
  1469. {
  1470. if (Math.RandomFloat01() < 0.5)
  1471. {
  1472. if (GetBleedingManagerServer().AttemptAddBleedingSourceBySelection("LeftForeArmRoll"))
  1473. {
  1474. SendSoundEvent(EPlayerSoundEventID.INJURED_LIGHT);
  1475. }
  1476. }
  1477. else
  1478. {
  1479. if (GetBleedingManagerServer().AttemptAddBleedingSourceBySelection("RightForeArmRoll"))
  1480. {
  1481. SendSoundEvent(EPlayerSoundEventID.INJURED_LIGHT);
  1482. }
  1483. }
  1484. }
  1485. }
  1486. }
  1487. }
  1488. override void ProcessFeetDamageServer(int pUserInt)
  1489. {
  1490. //InventorySlots.HEADGEAR
  1491. EntityAI shoes = GetInventory().FindAttachment(InventorySlots.FEET);
  1492. string surface; int liquid;
  1493. GetGame().SurfaceUnderObject(this, surface, liquid);
  1494. float modifier_surface = Surface.GetParamFloat(surface, "footDamage");
  1495. if (shoes && shoes.GetHealthLevel() < 4)
  1496. {
  1497. shoes.AddHealth("", "", -1 * modifier_surface * PlayerConstants.SHOES_MOVEMENT_DAMAGE_PER_STEP * (float)PlayerConstants.CHECK_EVERY_N_STEP);
  1498. return;
  1499. }
  1500. float rnd = Math.RandomFloat01();
  1501. float modifier_movement = GetFeetDamageMoveModifier();
  1502. float chance = modifier_movement * modifier_surface * PlayerConstants.BAREFOOT_MOVEMENT_BLEED_MODIFIER * (float)PlayerConstants.CHECK_EVERY_N_STEP;
  1503. if (rnd < chance)
  1504. {
  1505. if (pUserInt % 2 == 0)
  1506. {
  1507. if (GetBleedingManagerServer().AttemptAddBleedingSourceBySelection("RightFoot"))
  1508. SendSoundEvent(EPlayerSoundEventID.INJURED_LIGHT);
  1509. }
  1510. else
  1511. {
  1512. if (GetBleedingManagerServer().AttemptAddBleedingSourceBySelection("LeftFoot"))
  1513. SendSoundEvent(EPlayerSoundEventID.INJURED_LIGHT);
  1514. }
  1515. }
  1516. }
  1517. float GetFeetDamageMoveModifier()
  1518. {
  1519. float modifier;
  1520. switch(m_MovementState.m_iMovement)
  1521. {
  1522. case DayZPlayerConstants.MOVEMENTIDX_SPRINT:
  1523. modifier = 1;
  1524. break
  1525. case DayZPlayerConstants.MOVEMENTIDX_RUN:
  1526. modifier = 0.5;
  1527. break
  1528. case DayZPlayerConstants.MOVEMENTIDX_WALK:
  1529. modifier = 0;
  1530. break
  1531. }
  1532. return modifier;
  1533. }
  1534. void SetStamina(int value, int range)
  1535. {
  1536. if (m_ModulePlayerStatus)
  1537. m_ModulePlayerStatus.SetStamina(value, range);
  1538. }
  1539. #ifdef DIAG_DEVELOPER
  1540. void SetStaminaDisabled(bool value)
  1541. {
  1542. if (m_StaminaHandler)
  1543. m_StaminaHandler.SetStaminaDisabled(value);
  1544. }
  1545. #endif
  1546. void SetQuickRestrain(bool enable)
  1547. {
  1548. m_AllowQuickRestrain = enable;
  1549. }
  1550. void SetQuickFishing(bool enable)
  1551. {
  1552. m_AllowQuickFishing = enable;
  1553. }
  1554. bool IsQuickRestrain()
  1555. {
  1556. return m_AllowQuickRestrain;
  1557. }
  1558. bool IsQuickFishing()
  1559. {
  1560. return m_AllowQuickFishing;
  1561. }
  1562. PlayerStats GetPlayerStats()
  1563. {
  1564. return m_PlayerStats;
  1565. }
  1566. CraftingManager GetCraftingManager()
  1567. {
  1568. return m_CraftingManager;
  1569. }
  1570. StaminaHandler GetStaminaHandler()
  1571. {
  1572. return m_StaminaHandler;
  1573. }
  1574. override WeaponManager GetWeaponManager()
  1575. {
  1576. return m_WeaponManager;
  1577. }
  1578. override ArrowManagerBase GetArrowManager()
  1579. {
  1580. return m_ArrowManager;
  1581. }
  1582. bool CanBeRestrained()
  1583. {
  1584. if (IsInVehicle() || IsRaised() || IsSwimming() || IsClimbing() || IsClimbingLadder() || IsRestrained() || !GetWeaponManager() || GetWeaponManager().IsRunning() || !GetActionManager() || GetActionManager().GetRunningAction() != null || IsMapOpen())
  1585. {
  1586. return false;
  1587. }
  1588. if (GetThrowing() && GetThrowing().IsThrowingModeEnabled())
  1589. {
  1590. return false;
  1591. }
  1592. return true;
  1593. }
  1594. void SetRestrainStarted(bool restrain_started)
  1595. {
  1596. m_IsRestrainStarted = restrain_started;
  1597. SetSynchDirty();
  1598. }
  1599. bool IsRestrainStarted()
  1600. {
  1601. return m_IsRestrainStarted;
  1602. }
  1603. void SetRestrainPrelocked(bool restrain_prelock)
  1604. {
  1605. m_IsRestrainPrelocked = restrain_prelock;
  1606. SetSynchDirty();
  1607. }
  1608. bool IsRestrainPrelocked()
  1609. {
  1610. return m_IsRestrainPrelocked;
  1611. }
  1612. void SetRestrained(bool is_restrained)
  1613. {
  1614. m_IsRestrained = is_restrained;
  1615. SetSynchDirty();
  1616. }
  1617. override bool IsRestrained()
  1618. {
  1619. return m_IsRestrained;
  1620. }
  1621. void OnRestrainStartedChangeClient()
  1622. {
  1623. if (m_IsRestrainStarted && IsControlledPlayer())
  1624. {
  1625. if (GetGame().GetUIManager().IsMenuOpen(MENU_RADIAL_QUICKBAR))
  1626. GetGame().GetUIManager().FindMenu(MENU_RADIAL_QUICKBAR).Close();
  1627. if (GetGame().GetUIManager().IsMenuOpen(MENU_INVENTORY))
  1628. GetGame().GetMission().HideInventory();
  1629. }
  1630. }
  1631. void OnRestrainChangeClient()
  1632. {
  1633. if (m_IsRestrained && IsControlledPlayer())
  1634. {
  1635. if (GetGame().GetUIManager().IsMenuOpen(MENU_RADIAL_QUICKBAR))
  1636. GetGame().GetUIManager().FindMenu(MENU_RADIAL_QUICKBAR).Close();
  1637. if (GetGame().GetUIManager().IsMenuOpen(MENU_INVENTORY))
  1638. GetGame().GetMission().HideInventory();
  1639. }
  1640. }
  1641. override bool IsInventoryVisible()
  1642. {
  1643. return true;
  1644. }
  1645. bool CanManipulateInventory()
  1646. {
  1647. if (IsControlledPlayer())
  1648. {
  1649. return !IsRestrained() && !IsRestrainPrelocked() && !IsRestrainStarted();
  1650. }
  1651. return true;
  1652. }
  1653. override bool CanReleaseAttachment (EntityAI attachment)
  1654. {
  1655. return super.CanReleaseAttachment(attachment);
  1656. }
  1657. override bool CanReleaseCargo (EntityAI cargo)
  1658. {
  1659. return super.CanReleaseCargo(cargo);
  1660. }
  1661. override bool CanReceiveItemIntoCargo(EntityAI item)
  1662. {
  1663. return super.CanReceiveItemIntoCargo(item);
  1664. }
  1665. override bool CanSwapItemInCargo (EntityAI child_entity, EntityAI new_entity)
  1666. {
  1667. return super.CanSwapItemInCargo(child_entity, new_entity);
  1668. }
  1669. override bool CanReceiveItemIntoHands(EntityAI item_to_hands)
  1670. {
  1671. if (IsInVehicle())
  1672. return false;
  1673. if (!CanPickupHeavyItem(item_to_hands))
  1674. return false;
  1675. return super.CanReceiveItemIntoHands(item_to_hands);
  1676. }
  1677. override bool CanSaveItemInHands(EntityAI item_in_hands)
  1678. {
  1679. return super.CanSaveItemInHands(item_in_hands);
  1680. }
  1681. override bool CanReleaseFromHands(EntityAI handheld)
  1682. {
  1683. return super.CanReleaseFromHands(handheld);
  1684. }
  1685. int GetCraftingRecipeID()
  1686. {
  1687. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  1688. {
  1689. return GetCraftingManager().GetRecipeID();
  1690. }
  1691. else
  1692. {
  1693. return m_RecipeID;
  1694. }
  1695. }
  1696. void SetCraftingRecipeID(int recipeID)
  1697. {
  1698. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  1699. {
  1700. GetCraftingManager().SetRecipeID(recipeID);
  1701. }
  1702. else
  1703. {
  1704. m_RecipeID = recipeID;
  1705. }
  1706. }
  1707. // --------------------------------------------------
  1708. // Action data for base building actions
  1709. //---------------------------------------------------
  1710. ConstructionActionData GetConstructionActionData()
  1711. {
  1712. return m_ConstructionActionData;
  1713. }
  1714. void ResetConstructionActionData()
  1715. {
  1716. if (m_ConstructionActionData)
  1717. {
  1718. m_ConstructionActionData.ResetActionIndexes();
  1719. }
  1720. }
  1721. // --------------------------------------------------
  1722. // Action data for fireplace (indoor)
  1723. //---------------------------------------------------
  1724. vector GetLastFirePoint()
  1725. {
  1726. return m_LastFirePoint;
  1727. }
  1728. float GetLastFirePointRot()
  1729. {
  1730. return m_LastFirePointRot;
  1731. }
  1732. int GetLastFirePointIndex()
  1733. {
  1734. return m_LastFirePointIndex;
  1735. }
  1736. void SetLastFirePoint(vector last_fire_point)
  1737. {
  1738. m_LastFirePoint = last_fire_point;
  1739. }
  1740. void SetLastFirePointRot(float last_fire_point_rot)
  1741. {
  1742. m_LastFirePointRot = last_fire_point_rot;
  1743. }
  1744. void SetLastFirePointIndex(int last_fire_point_index)
  1745. {
  1746. m_LastFirePointIndex = last_fire_point_index;
  1747. }
  1748. // --------------------------------------------------
  1749. // QuickBar
  1750. //---------------------------------------------------
  1751. void RemoveQuickBarEntityShortcut(EntityAI entity)
  1752. {
  1753. int index = m_QuickBarBase.FindEntityIndex(entity);
  1754. if (index != -1)
  1755. m_QuickBarBase.SetEntityShortcut(entity,-1);
  1756. }
  1757. //---------------------------------------------------
  1758. void SetEnableQuickBarEntityShortcut(EntityAI entity, bool value)
  1759. {
  1760. int index = m_QuickBarBase.FindEntityIndex(entity);
  1761. if (index != -1)
  1762. m_QuickBarBase.SetShotcutEnable(index,value);
  1763. }
  1764. //---------------------------------------------------
  1765. int FindQuickBarEntityIndex(EntityAI entity)
  1766. {
  1767. int index;
  1768. index = m_QuickBarBase.FindEntityIndex(entity);
  1769. if (m_QuickBarBase.GetEntity(index) == NULL)
  1770. return -1;
  1771. return index;
  1772. }
  1773. //---------------------------------------------------
  1774. int GetQuickBarSize()
  1775. {
  1776. return m_QuickBarBase.GetSize();
  1777. }
  1778. //---------------------------------------------------
  1779. EntityAI GetQuickBarEntity(int index)
  1780. {
  1781. return m_QuickBarBase.GetEntity(index);
  1782. }
  1783. //---------------------------------------------------
  1784. void UpdateQuickBarEntityVisibility(EntityAI entity)
  1785. {
  1786. int i = FindQuickBarEntityIndex(entity);
  1787. if (i >= 0)
  1788. m_QuickBarBase.UpdateShotcutVisibility(i);
  1789. }
  1790. //---------------------------------------------------
  1791. void SetQuickBarEntityShortcut(EntityAI entity, int index, bool force = false)
  1792. {
  1793. m_QuickBarBase.SetEntityShortcut(entity, index, force);
  1794. }
  1795. //---------------------------------------------------
  1796. void OnQuickbarSetEntityRequest(ParamsReadContext ctx)
  1797. {
  1798. m_QuickBarBase.OnSetEntityRequest(ctx);
  1799. }
  1800. //---------------------------------------------------
  1801. // Applies splint on all limbs.
  1802. void ApplySplint()
  1803. {
  1804. float add_health_coef = 0.33;
  1805. // The idea is to slightly increase health of broken limb so the player is still limping. Using more splints will help but each time less. 100% recovery can be achieved only through long term healing.
  1806. if (GetBrokenLegs() == eBrokenLegs.BROKEN_LEGS)
  1807. {
  1808. AddHealth("LeftLeg", "Health", (GetMaxHealth("LeftLeg", "Health") - GetHealth("LeftLeg", "Health") ) * add_health_coef );
  1809. AddHealth("RightLeg", "Health", (GetMaxHealth("RightLeg", "Health") - GetHealth("RightLeg", "Health")) * add_health_coef );
  1810. AddHealth("RightFoot", "Health", (GetMaxHealth("RightFoot", "Health") - GetHealth("RightFoot", "Health")) * add_health_coef );
  1811. AddHealth("LeftFoot", "Health", (GetMaxHealth("LeftFoot", "Health") - GetHealth("LeftFoot", "Health")) * add_health_coef );
  1812. }
  1813. }
  1814. void ProcessDrowning(float dT)
  1815. {
  1816. GetStaminaHandler().DepleteStamina(EStaminaModifiers.DROWN,dT);
  1817. #ifndef SERVER
  1818. //PP EFFECTS
  1819. PPERequester_Drowning req = PPERequester_Drowning.Cast(PPERequesterBank.GetRequester(PPERequesterBank.REQ_DROWNING));
  1820. req.SetStamina01(GetStaminaHandler().GetStaminaNormalized());
  1821. #endif
  1822. }
  1823. void SpawnDrowningBubbles()
  1824. {
  1825. if (!GetDrowningWaterLevelCheck())
  1826. return;
  1827. float bubbleFrequency = Math.Lerp(PlayerConstants.DROWNING_BUBBLE_FREQUENCY_MIN, PlayerConstants.DROWNING_BUBBLE_FREQUENCY_MAX, GetStaminaHandler().GetSyncedStaminaNormalized());
  1828. int boneIdx = GetBoneIndexByName("Head");
  1829. if (boneIdx != -1)
  1830. {
  1831. Particle p = ParticleManager.GetInstance().PlayInWorld(ParticleList.DROWNING_BUBBLES, "-0.03 0.15 0");
  1832. if (p)
  1833. AddChild(p, boneIdx);
  1834. GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(SpawnDrowningBubbles, bubbleFrequency);
  1835. }
  1836. }
  1837. void ProcessHoldBreath(float dT)
  1838. {
  1839. if (IsTryingHoldBreath() && CanStartConsumingStamina(EStaminaConsumers.HOLD_BREATH))
  1840. {
  1841. if (!m_IsHoldingBreath)
  1842. {
  1843. OnHoldBreathStart();
  1844. m_IsHoldingBreath = true;
  1845. }
  1846. }
  1847. else if (!IsTryingHoldBreath() || !CanConsumeStamina(EStaminaConsumers.HOLD_BREATH))
  1848. {
  1849. if (m_IsHoldingBreath) OnHoldBreathEnd();
  1850. m_IsHoldingBreath = false;
  1851. }
  1852. }
  1853. void OnHoldBreathStart()
  1854. {
  1855. //SendSoundEvent(SoundSetMap.GetSoundSetID("holdBreath_male_Char_SoundSet"));
  1856. RequestSoundEventEx(EPlayerSoundEventID.HOLD_BREATH, true, EPlayerSoundEventParam.SKIP_CONTROLLED_PLAYER);
  1857. }
  1858. void OnHoldBreathExhausted()
  1859. {
  1860. RequestSoundEventEx(EPlayerSoundEventID.EXHAUSTED_BREATH, true, EPlayerSoundEventParam.SKIP_CONTROLLED_PLAYER);
  1861. }
  1862. void OnHoldBreathEnd()
  1863. {
  1864. //SendSoundEvent(SoundSetMap.GetSoundSetID("releaseBreath_male_Char_SoundSet"));
  1865. RequestSoundEventEx(EPlayerSoundEventID.RELEASE_BREATH, true, EPlayerSoundEventParam.SKIP_CONTROLLED_PLAYER);
  1866. }
  1867. override bool IsHoldingBreath()
  1868. {
  1869. return m_IsHoldingBreath;
  1870. }
  1871. override bool IsRefresherSignalingViable()
  1872. {
  1873. return false;
  1874. }
  1875. override bool IsSelfAdjustingTemperature()
  1876. {
  1877. return IsAlive();
  1878. }
  1879. eMixedSoundStates GetMixedSoundStates()
  1880. {
  1881. return m_MixedSoundStates;
  1882. }
  1883. AbstractWave SaySoundSet(string name)
  1884. {
  1885. if (m_SaySoundLastSetName != name)
  1886. {
  1887. m_SaySoundParams = new SoundParams(name);
  1888. m_SaySoundBuilder = new SoundObjectBuilder(m_SaySoundParams);
  1889. m_SaySoundLastSetName = name;
  1890. }
  1891. m_SaySoundObject = m_SaySoundBuilder.BuildSoundObject();
  1892. m_SaySoundObject.SetPosition(GetPosition());
  1893. return GetGame().GetSoundScene().Play3D(m_SaySoundObject, m_SaySoundBuilder);
  1894. }
  1895. EntityAI FindCargoByBaseType(string searched_item)
  1896. {
  1897. EntityAI attachment;
  1898. string item_name;
  1899. int attcount = this.GetInventory().AttachmentCount();
  1900. for (int att = 0; att < attcount; att++)
  1901. {
  1902. attachment = GetInventory().GetAttachmentFromIndex(att);
  1903. if (attachment.IsItemBase())
  1904. {
  1905. item_name = attachment.GetType();
  1906. if (GetGame().IsKindOf(item_name, searched_item))
  1907. {
  1908. return attachment;
  1909. }
  1910. }
  1911. }
  1912. return NULL;
  1913. }
  1914. void InitEditor()
  1915. {
  1916. if (GetGame().IsDebug())
  1917. {
  1918. if (!GetGame().IsMultiplayer() && GetGame().GetPlayer() && GetGame().GetPlayer().GetID() == this.GetID())
  1919. {
  1920. PluginSceneManager scene_editor = PluginSceneManager.Cast(GetPlugin(PluginSceneManager));
  1921. scene_editor.InitLoad();
  1922. }
  1923. }
  1924. }
  1925. //---------------------------------------------------------------------------------------------------------------------------
  1926. void OnPlayerLoaded()
  1927. {
  1928. InitEditor();
  1929. //! initialize EnvironmentExposure data; waits for PlayerStats load
  1930. if (m_Environment)
  1931. m_Environment.Init();
  1932. if (GetGame().IsMultiplayer() || GetGame().IsServer())
  1933. {
  1934. if (m_ModuleLifespan)
  1935. {
  1936. m_ModuleLifespan.SynchLifespanVisual(this, m_LifeSpanState, m_HasBloodyHandsVisible, m_HasBloodTypeVisible, m_BloodType);
  1937. }
  1938. }
  1939. if (IsControlledPlayer())//true only on client for the controlled character
  1940. {
  1941. if (!m_VirtualHud)
  1942. m_VirtualHud = new VirtualHud(this);
  1943. if (m_Hud)
  1944. {
  1945. m_Hud.UpdateBloodName();
  1946. PPERequesterBank.GetRequester(PPERequester_DeathDarkening).Stop();
  1947. PPERequesterBank.GetRequester(PPERequester_ShockHitReaction).Stop();
  1948. PPERequesterBank.GetRequester(PPERequester_UnconEffects).Stop();
  1949. GetGame().GetUIManager().CloseAll();
  1950. GetGame().GetMission().SetPlayerRespawning(false);
  1951. GetGame().GetMission().OnPlayerRespawned(this);
  1952. m_Hud.ShowHudUI(true);
  1953. m_Hud.ShowQuickbarUI(true);
  1954. m_Hud.UpdateQuickbarGlobalVisibility();
  1955. m_Hud.InitHeatBufferUI(this);
  1956. }
  1957. m_EffectWidgets = GetGame().GetMission().GetEffectWidgets();
  1958. }
  1959. if (!GetGame().IsDedicatedServer())
  1960. {
  1961. GetGame().GetCallQueue(CALL_CATEGORY_GUI).CallLater(UpdateCorpseStateVisual, 2000, false);//sometimes it takes a while to load in
  1962. m_PlayerSoundEventHandler = new PlayerSoundEventHandler(this);
  1963. m_ReplaceSoundEventHandler = new ReplaceSoundEventHandler(this);
  1964. }
  1965. int slotId = InventorySlots.GetSlotIdFromString("Head");
  1966. m_CharactersHead = Head_Default.Cast(GetInventory().FindPlaceholderForSlot(slotId));
  1967. CheckHairClippingOnCharacterLoad();
  1968. UpdateHairSelectionVisibility();
  1969. PreloadDecayTexture();
  1970. Weapon_Base wpn = Weapon_Base.Cast(GetItemInHands());
  1971. if (wpn)
  1972. {
  1973. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_REMOTE)
  1974. {
  1975. wpn.DelayedValidateAndRepair();
  1976. }
  1977. else
  1978. {
  1979. wpn.ValidateAndRepair();
  1980. }
  1981. }
  1982. m_PlayerLoaded = true;
  1983. }
  1984. void SetPlayerDisconnected(bool state)
  1985. {
  1986. m_PlayerDisconnectProcessed = state;
  1987. }
  1988. bool IsPlayerDisconnected()
  1989. {
  1990. return m_PlayerDisconnectProcessed;
  1991. }
  1992. // --------------------------------------------------
  1993. // Advanced placement
  1994. //---------------------------------------------------
  1995. //get hologram
  1996. Hologram GetHologramServer()
  1997. {
  1998. return m_HologramServer;
  1999. }
  2000. Hologram GetHologramLocal()
  2001. {
  2002. return m_HologramLocal;
  2003. }
  2004. void PlacingStartServer(ItemBase item)
  2005. {
  2006. if (item)
  2007. {
  2008. m_HologramServer = new Hologram(this, GetLocalProjectionPosition(), item);
  2009. GetHologramServer().SetProjectionPosition(GetLocalProjectionPosition());
  2010. GetHologramServer().SetProjectionOrientation(GetLocalProjectionOrientation());
  2011. GetHologramServer().GetProjectionEntity().OnPlacementStarted(this);
  2012. GetHologramServer().CheckPowerSource();
  2013. GetHologramServer().RefreshVisual();
  2014. }
  2015. }
  2016. void PlacingStartLocal(ItemBase item)
  2017. {
  2018. if (GetGame().IsMultiplayer() && GetGame().IsServer())
  2019. return;
  2020. if (item)
  2021. {
  2022. m_HologramLocal = new Hologram(this, GetLocalProjectionPosition(), item);
  2023. GetHologramLocal().GetProjectionEntity().OnPlacementStarted(this);
  2024. }
  2025. }
  2026. void PlacingCancelServer()
  2027. {
  2028. EntityAI entityInHands = GetHumanInventory().GetEntityInHands();
  2029. if (IsPlacingServer())
  2030. {
  2031. GetHologramServer().CheckPowerSource();
  2032. GetHologramServer().GetParentEntity().OnPlacementCancelled(this);
  2033. delete m_HologramServer;
  2034. return;
  2035. }
  2036. else if (entityInHands && entityInHands.HasEnergyManager())
  2037. {
  2038. if (entityInHands.GetCompEM().IsPlugged())
  2039. entityInHands.OnPlacementCancelled(this);
  2040. }
  2041. }
  2042. //Called when item placement is canceled, will prevent quickbar usage until the item the player was placing is back in hands
  2043. void LockHandsUntilItemHeld()
  2044. {
  2045. m_AreHandsLocked = true;
  2046. }
  2047. void PlacingCancelLocal()
  2048. {
  2049. EntityAI entityInHands = GetHumanInventory().GetEntityInHands();
  2050. if (entityInHands && entityInHands.HasEnergyManager())
  2051. {
  2052. if (entityInHands.GetCompEM().IsPlugged())
  2053. entityInHands.OnPlacementCancelled(this);
  2054. }
  2055. delete m_HologramLocal;
  2056. }
  2057. void PlacingCompleteServer()
  2058. {
  2059. SetLocalProjectionPosition(vector.Zero);
  2060. delete m_HologramServer;
  2061. }
  2062. void PlacingCompleteLocal()
  2063. {
  2064. SetLocalProjectionPosition(vector.Zero);
  2065. delete m_HologramLocal;
  2066. }
  2067. bool IsPlacingServer()
  2068. {
  2069. if (m_HologramServer)
  2070. return true;
  2071. return false;
  2072. }
  2073. bool IsPlacingLocal()
  2074. {
  2075. if (m_HologramLocal)
  2076. return true;
  2077. return false;
  2078. }
  2079. void SetDrowning(bool enable)
  2080. {
  2081. if (enable != m_IsDrowning)
  2082. {
  2083. if (enable)
  2084. OnDrowningStart();
  2085. else
  2086. OnDrowningEnd();
  2087. }
  2088. m_IsDrowning = enable;
  2089. }
  2090. void OnDrowningStart()
  2091. {
  2092. #ifndef SERVER
  2093. if (IsControlledPlayer())
  2094. {
  2095. PPERequester_Drowning req = PPERequester_Drowning.Cast(PPERequesterBank.GetRequester(PPERequesterBank.REQ_DROWNING));
  2096. req.Start();
  2097. }
  2098. //Particles
  2099. SpawnDrowningBubbles();
  2100. #endif
  2101. }
  2102. void OnDrowningEnd()
  2103. {
  2104. #ifndef SERVER
  2105. if (IsControlledPlayer())
  2106. {
  2107. PPERequester_Drowning req = PPERequester_Drowning.Cast(PPERequesterBank.GetRequester(PPERequesterBank.REQ_DROWNING));
  2108. req.Stop();
  2109. }
  2110. GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(SpawnDrowningBubbles);
  2111. #endif
  2112. }
  2113. bool TogglePlacingServer(int userDataType, ParamsReadContext ctx)
  2114. {
  2115. if (userDataType == INPUT_UDT_ADVANCED_PLACEMENT)
  2116. {
  2117. PlacingCancelServer();
  2118. return true;
  2119. }
  2120. return false;
  2121. }
  2122. void RequestResetADSSync()
  2123. {
  2124. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT && GetGame().IsMultiplayer())
  2125. {
  2126. if (ScriptInputUserData.CanStoreInputUserData())
  2127. {
  2128. ScriptInputUserData ctx = new ScriptInputUserData;
  2129. ctx.Write(INPUT_UDT_RESET_ADS);
  2130. ctx.Send();
  2131. }
  2132. }
  2133. else if (!GetGame().IsMultiplayer())
  2134. {
  2135. m_ResetADS = true;
  2136. }
  2137. }
  2138. //! server only
  2139. bool ResetADSPlayerSync(int userDataType, ParamsReadContext ctx)
  2140. {
  2141. if (userDataType == INPUT_UDT_RESET_ADS)
  2142. {
  2143. ScriptJunctureData pCtx = new ScriptJunctureData;
  2144. SendSyncJuncture(DayZPlayerSyncJunctures.SJ_ADS_RESET,pCtx);
  2145. return true;
  2146. }
  2147. return false;
  2148. }
  2149. override bool CanPlaceItem(EntityAI item)
  2150. {
  2151. if (m_UndergroundPresence > EUndergroundPresence.NONE)
  2152. {
  2153. TStringSet disallowedUndergroundTypes = CfgGameplayHandler.GetDisallowedTypesInUnderground();
  2154. foreach (string t: disallowedUndergroundTypes)
  2155. {
  2156. if (item.IsKindOf(t))
  2157. return false;
  2158. }
  2159. }
  2160. return true;
  2161. }
  2162. void SetUnderground(EUndergroundPresence presence)
  2163. {
  2164. m_UndergroundPresence = presence;
  2165. }
  2166. void TogglePlacingLocal(ItemBase item = null)
  2167. {
  2168. if (IsPlacingLocal())
  2169. {
  2170. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT && GetGame().IsMultiplayer())
  2171. {
  2172. if (ScriptInputUserData.CanStoreInputUserData())
  2173. {
  2174. ScriptInputUserData ctx = new ScriptInputUserData;
  2175. ctx.Write(INPUT_UDT_ADVANCED_PLACEMENT);
  2176. ctx.Send();
  2177. }
  2178. }
  2179. PlacingCancelLocal();
  2180. }
  2181. else if (!item)
  2182. {
  2183. PlacingStartLocal(GetItemInHands());
  2184. }
  2185. else
  2186. {
  2187. PlacingStartLocal(item);
  2188. }
  2189. }
  2190. void SetLocalProjectionPosition(vector local_position)
  2191. {
  2192. m_LocalProjectionPosition = local_position;
  2193. }
  2194. void SetLocalProjectionOrientation(vector local_orientation)
  2195. {
  2196. m_LocalProjectionOrientation = local_orientation;
  2197. }
  2198. vector GetLocalProjectionPosition()
  2199. {
  2200. return m_LocalProjectionPosition;
  2201. }
  2202. vector GetLocalProjectionOrientation()
  2203. {
  2204. return m_LocalProjectionOrientation;
  2205. }
  2206. void SetInColdArea(bool state)
  2207. {
  2208. if (m_IsInColdArea != state)
  2209. {
  2210. m_IsInColdArea = state;
  2211. SetSynchDirty();
  2212. }
  2213. }
  2214. bool GetInColdArea()
  2215. {
  2216. return m_IsInColdArea;
  2217. }
  2218. // ------------------------------------------------------------------------
  2219. //! water contact (driven by Environment)
  2220. void SetInWater(bool pState)
  2221. {
  2222. m_IsInWater = pState;
  2223. SetSynchDirty();
  2224. }
  2225. bool IsInWater()
  2226. {
  2227. return m_IsInWater;
  2228. }
  2229. // -------------------------------------------------------------------------
  2230. void ~PlayerBase()
  2231. {
  2232. if (GetGame() && (!GetGame().IsDedicatedServer()))
  2233. {
  2234. ClientData.RemovePlayerBase(this);
  2235. SetContaminatedEffectEx(false);
  2236. }
  2237. SEffectManager.DestroyEffect(m_FliesEff);
  2238. StopSoundSet(m_SoundFliesEffect);
  2239. }
  2240. void OnCameraChanged(DayZPlayerCameraBase new_camera)
  2241. {
  2242. m_CameraSwayModifier = new_camera.GetWeaponSwayModifier();
  2243. m_CurrentCamera = new_camera;
  2244. }
  2245. DayZPlayerCamera GetCurrentPlayerCamera()
  2246. {
  2247. return m_CurrentCamera;
  2248. }
  2249. bool IsCurrentCameraAimedAtGround()
  2250. {
  2251. if (!m_CurrentCamera)
  2252. return false;
  2253. return m_CurrentCamera.GetCurrentPitch() < PlayerConstants.CAMERA_THRESHOLD_PITCH;
  2254. }
  2255. BleedingSourcesManagerServer GetBleedingManagerServer()
  2256. {
  2257. return m_BleedingManagerServer;
  2258. }
  2259. BleedingSourcesManagerRemote GetBleedingManagerRemote()
  2260. {
  2261. return m_BleedingManagerRemote;
  2262. }
  2263. SymptomManager GetSymptomManager()
  2264. {
  2265. return m_SymptomManager;
  2266. }
  2267. VirtualHud GetVirtualHud()
  2268. {
  2269. if (!m_VirtualHud)
  2270. {
  2271. m_VirtualHud = new VirtualHud(this);
  2272. }
  2273. return m_VirtualHud;
  2274. }
  2275. TransferValues GetTransferValues()
  2276. {
  2277. return m_TrasferValues;
  2278. }
  2279. DebugMonitorValues GetDebugMonitorValues()
  2280. {
  2281. return m_DebugMonitorValues;
  2282. }
  2283. //--------------------------------------------------------------------------
  2284. void OnScheduledTick(float deltaTime)
  2285. {
  2286. if (!IsPlayerSelected() || !IsAlive())
  2287. return;
  2288. if (m_ModifiersManager)
  2289. m_ModifiersManager.OnScheduledTick(deltaTime);
  2290. if (m_NotifiersManager)
  2291. m_NotifiersManager.OnScheduledTick();
  2292. if (m_TrasferValues)
  2293. m_TrasferValues.OnScheduledTick(deltaTime);
  2294. if (m_VirtualHud)
  2295. m_VirtualHud.OnScheduledTick();
  2296. if (GetBleedingManagerServer())
  2297. GetBleedingManagerServer().OnTick(deltaTime);
  2298. if (m_Environment)
  2299. m_Environment.Update(deltaTime);
  2300. // Check if electric device needs to be unplugged
  2301. ItemBase heldItem = GetItemInHands();
  2302. if (heldItem && heldItem.HasEnergyManager() && heldItem.GetCompEM().IsPlugged())
  2303. {
  2304. // Now we know we are working with an electric device which is plugged into a power source.
  2305. EntityAI placed_entity = heldItem;
  2306. // Unplug the device when the player is too far from the power source.
  2307. placed_entity.GetCompEM().UpdatePlugState();
  2308. }
  2309. }
  2310. void OnCommandHandlerTick(float delta_time, int pCurrentCommandID)
  2311. {
  2312. if (!IsAlive())
  2313. {
  2314. if (!m_DeathSyncSent && m_KillerData)
  2315. {
  2316. SyncEvents.SendEntityKilled(this, m_KillerData.m_Killer, m_KillerData.m_MurderWeapon, m_KillerData.m_KillerHiTheBrain);
  2317. m_DeathSyncSent = true;
  2318. }
  2319. return;
  2320. }
  2321. if (m_DebugMonitorValues)
  2322. m_DebugMonitorValues.OnScheduledTick(delta_time);
  2323. if (GetSymptomManager())
  2324. GetSymptomManager().OnTick(delta_time, pCurrentCommandID, m_MovementState);//needs to stay in command handler tick as it's playing animations
  2325. //if (GetBleedingManagerServer()) GetBleedingManagerServer().OnTick(delta_time);
  2326. DayZPlayerInstanceType instType = GetInstanceType();
  2327. if (instType == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  2328. {
  2329. if (m_PlayerSoundEventHandler)
  2330. m_PlayerSoundEventHandler.OnTick(delta_time);
  2331. if (m_ProcessRemoveEffectWidgets && m_ProcessRemoveEffectWidgets.Count() > 0)
  2332. {
  2333. m_EffectWidgets.RemoveActiveEffects(m_ProcessRemoveEffectWidgets);
  2334. }
  2335. if (m_ProcessAddEffectWidgets && m_ProcessAddEffectWidgets.Count() > 0)
  2336. {
  2337. m_EffectWidgets.AddActiveEffects(m_ProcessAddEffectWidgets);
  2338. }
  2339. HandleGlassesEffect();
  2340. if (m_ContaminatedAreaEffectEnabled)
  2341. ContaminatedParticleAdjustment();
  2342. #ifdef DIAG_DEVELOPER
  2343. if (m_WeaponDebug)
  2344. {
  2345. m_WeaponDebug.OnCommandHandlerUpdate();
  2346. }
  2347. #endif
  2348. m_ProcessAddEffectWidgets.Clear(); //clears array for remotes as well
  2349. m_ProcessRemoveEffectWidgets.Clear(); //clears array for remotes as well
  2350. }
  2351. m_AnimCommandStarting = HumanMoveCommandID.None;
  2352. if (CfgGameplayHandler.GetAllowStaminaAffectInertia())
  2353. UpdateMovementInertia();
  2354. }
  2355. //! Update movement inertia based on stamina available
  2356. void UpdateMovementInertia()
  2357. {
  2358. HumanCommandMove hcm = GetCommand_Move();
  2359. if (hcm)
  2360. {
  2361. float staminaPercentage = GetStaminaHandler().GetSyncedStaminaNormalized();
  2362. hcm.SetTurnSpanSprintModifier(2 - staminaPercentage);
  2363. hcm.SetRunSprintFilterModifier((2 - staminaPercentage) * 0.5);
  2364. hcm.SetDirectionSprintFilterModifier(2 - staminaPercentage);
  2365. }
  2366. }
  2367. bool m_ShowDbgUI = true;
  2368. int m_DbgListSelection = 0;
  2369. float m_DbgSliderValue = 0.0;
  2370. ref array<string> m_DbgOptions = {"jedna", "dva", "tri"};
  2371. NotifiersManager GetNotifiersManager()
  2372. {
  2373. return m_NotifiersManager;
  2374. }
  2375. //--------------------------------------------------------------------------
  2376. void OnTick()
  2377. {
  2378. float deltaT = (GetGame().GetTime() - m_LastTick) * 0.001;
  2379. if (m_LastTick < 0)
  2380. deltaT = 0; //first tick protection
  2381. m_LastTick = GetGame().GetTime();
  2382. OnScheduledTick(deltaT);
  2383. }
  2384. // -------------------------------------------------------------------------
  2385. override void EEItemIntoHands(EntityAI item)
  2386. {
  2387. super.EEItemIntoHands(item);
  2388. if (item)
  2389. {
  2390. MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(item, {Bolt_Base});
  2391. Weapon_Base w;
  2392. if (Class.CastTo(w, item))
  2393. {
  2394. w.ResetWeaponAnimState();
  2395. HumanCommandMove cm = GetCommand_Move();
  2396. if (cm)
  2397. {
  2398. cm.SetMeleeBlock(false);
  2399. GetMeleeFightLogic().SetBlock(false);
  2400. }
  2401. }
  2402. //! fixes situation where raise is canceling some manipulation with heavy item(ex. TakeItemToHands), forces normal stance
  2403. if (item.IsHeavyBehaviour() && IsRaised())
  2404. {
  2405. HumanCommandMove cm2 = GetCommand_Move();
  2406. if (cm2)
  2407. {
  2408. cm2.ForceStance(DayZPlayerConstants.STANCEIDX_ERECT);
  2409. }
  2410. }
  2411. OnItemInHandsChanged();
  2412. }
  2413. }
  2414. override void EEItemOutOfHands(EntityAI item)
  2415. {
  2416. super.EEItemOutOfHands(item);
  2417. if (IsPlacingLocal())
  2418. {
  2419. GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).Call(TogglePlacingLocal);
  2420. }
  2421. OnItemInHandsChanged();
  2422. }
  2423. PlayerStomach GetStomach()
  2424. {
  2425. return m_PlayerStomach;
  2426. }
  2427. override void CommandHandler(float pDt, int pCurrentCommandID, bool pCurrentCommandFinished)
  2428. {
  2429. EvaluateDamageHit(pCurrentCommandID);
  2430. // lower implement
  2431. super.CommandHandler(pDt,pCurrentCommandID,pCurrentCommandFinished);
  2432. vector playerPosition = PhysicsGetPositionWS();
  2433. HumanInputController hic = GetInputController();
  2434. CheckZeroSoundEvent();
  2435. CheckSendSoundEvent();
  2436. ProcessADDModifier();
  2437. if (m_BrokenLegsJunctureReceived)//was there a change in broken legs state ?
  2438. {
  2439. m_BrokenLegsJunctureReceived = false;
  2440. bool initial = m_BrokenLegState < 0;//negative values indicate initial activation
  2441. if (GetBrokenLegs() == eBrokenLegs.BROKEN_LEGS)
  2442. {
  2443. DropHeavyItem();
  2444. if (initial)
  2445. {
  2446. BrokenLegForceProne();
  2447. hic.ResetADS();
  2448. GetUApi().GetInputByID(UATempRaiseWeapon).Supress();
  2449. ExitSights();
  2450. }
  2451. }
  2452. }
  2453. GetDayZPlayerInventory().HandleInventory(pDt);
  2454. if (IsFireWeaponRaised() || m_IsHoldingBreath)
  2455. {
  2456. ProcessHoldBreath(pDt);
  2457. }
  2458. ActionManagerBase mngr = GetActionManager();
  2459. if (m_AreHandsLocked && GetHumanInventory().GetEntityInHands())
  2460. {
  2461. m_AreHandsLocked = false;
  2462. }
  2463. // freelook camera memory for weapon raycast
  2464. if (hic.CameraIsFreeLook() && m_DirectionToCursor == vector.Zero)
  2465. {
  2466. m_DirectionToCursor = GetGame().GetCurrentCameraDirection();
  2467. }
  2468. else if (!hic.CameraIsFreeLook() && m_DirectionToCursor != vector.Zero)
  2469. {
  2470. m_DirectionToCursor = vector.Zero;
  2471. }
  2472. if (m_WeaponManager)
  2473. {
  2474. m_WeaponManager.Update(pDt);
  2475. }
  2476. if (m_EmoteManager && IsPlayerSelected())
  2477. {
  2478. m_EmoteManager.Update(pDt);
  2479. }
  2480. if (m_RGSManager)
  2481. {
  2482. m_RGSManager.Update();
  2483. }
  2484. if (m_StanceIndicator)
  2485. {
  2486. m_StanceIndicator.Update();
  2487. }
  2488. if (m_StaminaHandler)
  2489. {
  2490. m_StaminaHandler.Update(pDt, pCurrentCommandID);
  2491. }
  2492. if (m_InjuryHandler)
  2493. {
  2494. m_InjuryHandler.Update(pDt);
  2495. }
  2496. if (m_HCAnimHandler)
  2497. {
  2498. m_HCAnimHandler.Update(pDt, m_MovementState);
  2499. }
  2500. if (m_ShockHandler)
  2501. {
  2502. m_ShockHandler.Update(pDt);
  2503. }
  2504. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER || !GetGame().IsMultiplayer())
  2505. {
  2506. GetPlayerSoundManagerServer().Update();
  2507. ShockRefill(pDt);
  2508. FreezeCheck();
  2509. }
  2510. GetHumanInventory().Update(pDt);
  2511. if (m_IsDrowning)
  2512. {
  2513. ProcessDrowning(pDt);
  2514. }
  2515. UpdateDelete();
  2516. HandleDamageHit(pCurrentCommandID);
  2517. if (mngr && hic)
  2518. {
  2519. mngr.Update(pCurrentCommandID);
  2520. HumanCommandUnconscious hcu = GetCommand_Unconscious();
  2521. HumanCommandVehicle hcv = GetCommand_Vehicle();
  2522. if (!m_UnconsciousDebug)
  2523. {
  2524. //! When the player should be and is unconscious
  2525. if (m_ShouldBeUnconscious && m_IsUnconscious)
  2526. {
  2527. if (hcu)
  2528. {
  2529. //! Player can start floating while unconscious
  2530. m_Swimming.m_bWasSwimming |= hcu.IsInWater();
  2531. }
  2532. if (m_Swimming.m_bWasSwimming)
  2533. {
  2534. m_LastCommandBeforeUnconscious = DayZPlayerConstants.COMMANDID_SWIM;
  2535. }
  2536. OnUnconsciousUpdate(pDt, m_LastCommandBeforeUnconscious);
  2537. }
  2538. //! When the player will be unconscious, or is being blocked from being unconscious
  2539. else if (m_ShouldBeUnconscious)
  2540. {
  2541. //! If the player is getting in/out or switching seats, delay unconsciousness until after animation has finished
  2542. bool isTransitioning = hcv && (hcv.IsGettingIn() || hcv.IsGettingOut() || hcv.IsSwitchSeat());
  2543. if (pCurrentCommandID == DayZPlayerConstants.COMMANDID_UNCONSCIOUS)
  2544. {
  2545. OnUnconsciousUpdate(pDt, m_LastCommandBeforeUnconscious);
  2546. m_IsUnconscious = true;
  2547. OnUnconsciousStart();
  2548. }
  2549. //! Death gate - prevent unlikely occurence of death -> unconsciousness transition
  2550. //! Fall gate - prevent unconciousness animation from playing while falling, doesn't look good
  2551. //! Transition gate - prevent unconciousness while previous command is transitioning
  2552. else if (pCurrentCommandID != DayZPlayerConstants.COMMANDID_DEATH && pCurrentCommandID != DayZPlayerConstants.COMMANDID_FALL && !isTransitioning)
  2553. {
  2554. m_LastCommandBeforeUnconscious = pCurrentCommandID;
  2555. if (hcv)
  2556. {
  2557. m_TransportCache = hcv.GetTransport();
  2558. }
  2559. else
  2560. {
  2561. m_TransportCache = null;
  2562. }
  2563. //! TODO: rework vehicle command Knockout back to force player prone after they have exited the vehicle
  2564. m_JumpClimb.CheckAndFinishJump();
  2565. StartCommand_Unconscious(0);
  2566. SetFallYDiff(playerPosition[1]);
  2567. }
  2568. }
  2569. //! When the player is waking up
  2570. else if (m_IsUnconscious)
  2571. {
  2572. //! Make sure the player is actually unconscious
  2573. if (hcu && pCurrentCommandID == DayZPlayerConstants.COMMANDID_UNCONSCIOUS)
  2574. {
  2575. OnUnconsciousUpdate(pDt, m_LastCommandBeforeUnconscious);
  2576. //! protection for a player being broken when attempting to wake them up too early into unconsciousness
  2577. if (m_UnconsciousTime > 2)
  2578. {
  2579. int wakeUpStance = DayZPlayerConstants.STANCEIDX_PRONE;
  2580. //! Don't set the stance if we are swimming or in a vehicle, stance change animation could play
  2581. if (m_Swimming.m_bWasSwimming || m_LastCommandBeforeUnconscious == DayZPlayerConstants.COMMANDID_VEHICLE)
  2582. wakeUpStance = -1;
  2583. hcu.WakeUp(wakeUpStance);
  2584. m_IsUnconscious = false;
  2585. OnUnconsciousStop(pCurrentCommandID);
  2586. }
  2587. }
  2588. else
  2589. {
  2590. //! Maybe instead error out or notify of possible desync?
  2591. if (IsAlive())
  2592. {
  2593. m_IsUnconscious = false;
  2594. OnUnconsciousStop(pCurrentCommandID);
  2595. }
  2596. }
  2597. }
  2598. }
  2599. // quickbar use
  2600. int quickBarSlot = hic.IsQuickBarSlot();
  2601. if (quickBarSlot && IsAlive())
  2602. {
  2603. if (hic.IsQuickBarSingleUse())
  2604. {
  2605. OnQuickBarSingleUse(quickBarSlot);
  2606. //Print("PlayerBase.c IsQuickBarSingleUse - slot: " + quickBarSlot.ToString());
  2607. }
  2608. if (hic.IsQuickBarContinuousUseStart() && ((!GetGame().IsDedicatedServer()) && !GetGame().GetUIManager().GetMenu()))
  2609. {
  2610. OnQuickBarContinuousUseStart(quickBarSlot);
  2611. //Print("PlayerBase.c IsQuickBarContinuousUseStart - slot: " + quickBarSlot.ToString());
  2612. }
  2613. if (hic.IsQuickBarContinuousUseEnd() && ((!GetGame().IsDedicatedServer())))
  2614. {
  2615. OnQuickBarContinuousUseEnd(quickBarSlot);
  2616. //Print("PlayerBase.c IsQuickBarContinuousUseEnd - slot: " + quickBarSlot.ToString());
  2617. }
  2618. }
  2619. /*if ((pCurrentCommandID == DayZPlayerConstants.COMMANDID_ACTION || pCurrentCommandID == DayZPlayerConstants.COMMANDID_MOVE || pCurrentCommandID == DayZPlayerConstants.COMMANDID_LADDER || pCurrentCommandID == DayZPlayerConstants.COMMANDID_SWIM))
  2620. {
  2621. mngr.Update(); // checks for suitable action and sets it
  2622. }*/
  2623. }
  2624. if (m_StaminaHandler && hic)
  2625. {
  2626. //! SPRINT: enable/disable - based on stamina; disable also when raised
  2627. if (!CanConsumeStamina(EStaminaConsumers.SPRINT) || !CanSprint())
  2628. {
  2629. hic.LimitsDisableSprint(true);
  2630. }
  2631. else
  2632. {
  2633. hic.LimitsDisableSprint(false);
  2634. }
  2635. }
  2636. //map closing - feel free to move to different "update" if it does not belong here
  2637. if (IsMapOpen())
  2638. {
  2639. if (!GetGame().IsDedicatedServer())
  2640. {
  2641. if (!CfgGameplayHandler.GetUse3DMap() && !GetGame().GetUIManager().IsMenuOpen(MENU_MAP))
  2642. {
  2643. CloseMapEx(false);
  2644. }
  2645. else if (CfgGameplayHandler.GetUse3DMap())
  2646. {
  2647. if (IsMapCallbackCancelInput())
  2648. {
  2649. CloseMapEx(true);
  2650. }
  2651. else if (IsMapCallbackEndInput())
  2652. {
  2653. CloseMapEx(false);
  2654. }
  2655. }
  2656. }
  2657. }
  2658. #ifdef DIAG_DEVELOPER
  2659. if (m_Bot)
  2660. m_Bot.OnUpdate(pDt);
  2661. #endif
  2662. if (m_CheckMeleeItem && (!GetGame().IsDedicatedServer()))
  2663. {
  2664. CheckMeleeItemDamage(m_CheckMeleeItem);
  2665. SetCheckMeleeItem();
  2666. }
  2667. #ifdef DEVELOPER
  2668. TryGetInVehicleDebug();
  2669. #endif
  2670. OnCommandHandlerTick(pDt, pCurrentCommandID);
  2671. }
  2672. #ifdef DEVELOPER
  2673. void SetGetInVehicleDebug(EntityAI ent)
  2674. {
  2675. m_GetInVehicleTransportDebug = Transport.Cast(ent);
  2676. }
  2677. void TryGetInVehicleDebug()
  2678. {
  2679. if (m_GetInVehicleTransportDebug)
  2680. {
  2681. HumanCommandVehicle vehCommand = StartCommand_Vehicle(m_GetInVehicleTransportDebug, 0, 0);
  2682. if (vehCommand)
  2683. {
  2684. vehCommand.SetVehicleType(m_GetInVehicleTransportDebug.GetAnimInstance());
  2685. }
  2686. m_GetInVehicleTransportDebug = null;
  2687. }
  2688. }
  2689. #endif
  2690. //MAP handling
  2691. //! DEPRECATED; terminates map animation callback and re-enables controls
  2692. void CloseMap()
  2693. {
  2694. CloseMapEx(false);
  2695. }
  2696. void CloseMapEx(bool cancelled)
  2697. {
  2698. if (m_hac && !GetMapClosingSyncSent())
  2699. {
  2700. if (ScriptInputUserData.CanStoreInputUserData())
  2701. {
  2702. if (GetGame().IsMultiplayer() && GetGame().IsClient())
  2703. {
  2704. ActionManagerClient mngr_client;
  2705. CastTo(mngr_client, GetActionManager());
  2706. if (cancelled)
  2707. {
  2708. mngr_client.RequestInterruptAction();
  2709. }
  2710. else
  2711. {
  2712. mngr_client.RequestEndAction();
  2713. }
  2714. GetGame().GetMission().RemoveActiveInputExcludes({"map"});
  2715. GetGame().GetMission().RemoveActiveInputRestriction(EInputRestrictors.MAP);
  2716. }
  2717. else if (!GetGame().IsMultiplayer())
  2718. {
  2719. int command_ID = DayZPlayerConstants.CMD_ACTIONINT_END;
  2720. if (cancelled)
  2721. {
  2722. command_ID = DayZPlayerConstants.CMD_ACTIONINT_INTERRUPT;
  2723. }
  2724. m_hac.InternalCommand(command_ID);
  2725. }
  2726. SetMapClosingSyncSet(true);
  2727. }
  2728. }
  2729. if (!GetGame().IsDedicatedServer())
  2730. {
  2731. if (GetGame().GetUIManager().IsMenuOpen(MENU_MAP))
  2732. {
  2733. GetGame().GetUIManager().FindMenu(MENU_MAP).Close();
  2734. if (m_Hud)
  2735. {
  2736. m_Hud.ShowHudPlayer(true);
  2737. m_Hud.ShowQuickbarPlayer(true);
  2738. }
  2739. GetGame().GetMission().RemoveActiveInputExcludes({"map"});
  2740. GetGame().GetMission().RemoveActiveInputRestriction(EInputRestrictors.MAP);
  2741. }
  2742. }
  2743. }
  2744. void SetMapOpen(bool state)
  2745. {
  2746. m_MapOpen = state;
  2747. }
  2748. bool IsMapOpen()
  2749. {
  2750. return m_MapOpen;
  2751. }
  2752. void SetMapClosingSyncSet(bool state)
  2753. {
  2754. m_MapClosingSyncSent = state;
  2755. }
  2756. bool GetMapClosingSyncSent()
  2757. {
  2758. return m_MapClosingSyncSent;
  2759. }
  2760. bool IsMapCallbackCancelInput()
  2761. {
  2762. if (IsRaised() || (GetUApi().GetInputByID(UAUIMenu).LocalPress() || GetUApi().GetInputByID(UAGear).LocalPress()))
  2763. {
  2764. return true;
  2765. }
  2766. return false;
  2767. }
  2768. bool IsMapCallbackEndInput()
  2769. {
  2770. if (GetUApi().GetInputByID(UADefaultAction).LocalPress())
  2771. {
  2772. return true;
  2773. }
  2774. return false;
  2775. }
  2776. MapNavigationBehaviour GetMapNavigationBehaviour()
  2777. {
  2778. return m_MapNavigationBehaviour;
  2779. }
  2780. void MapNavigationItemInPossession(EntityAI item)
  2781. {
  2782. if (GetMapNavigationBehaviour())
  2783. {
  2784. GetMapNavigationBehaviour().OnItemInPlayerPossession(item);
  2785. }
  2786. }
  2787. void MapNavigationItemNotInPossession(EntityAI item)
  2788. {
  2789. if (GetMapNavigationBehaviour())
  2790. {
  2791. GetMapNavigationBehaviour().OnItemNotInPlayerPossession(item);
  2792. }
  2793. }
  2794. void SetCheckMeleeItem(ItemBase item = null)
  2795. {
  2796. m_CheckMeleeItem = item;
  2797. }
  2798. void SetShakesForced(int value)
  2799. {
  2800. m_ShakesForced = value;
  2801. }
  2802. void FreezeCheck()
  2803. {
  2804. int level;
  2805. if (m_ShakesForced > 0)
  2806. {
  2807. level = m_ShakesForced;
  2808. }
  2809. else
  2810. {
  2811. float heat_comfort = GetStatHeatComfort().Get();
  2812. if (heat_comfort <= PlayerConstants.THRESHOLD_HEAT_COMFORT_MINUS_WARNING)
  2813. {
  2814. float value = Math.InverseLerp(PlayerConstants.THRESHOLD_HEAT_COMFORT_MINUS_WARNING, PlayerConstants.THRESHOLD_HEAT_COMFORT_MINUS_CRITICAL,heat_comfort);
  2815. level = Math.Lerp(1,7,value);
  2816. level = Math.Clamp(value,1,7);
  2817. /*
  2818. value = Math.Clamp(value,0,1);
  2819. level = Math.Round(value * SHAKE_LEVEL_MAX);//translate from normalized value to levels
  2820. */
  2821. }
  2822. }
  2823. if (level != m_Shakes)
  2824. {
  2825. m_Shakes = level;
  2826. SetSynchDirty();
  2827. }
  2828. }
  2829. override bool IsLanded(int pCurrentCommandID)
  2830. {
  2831. if (super.IsLanded(pCurrentCommandID))
  2832. {
  2833. return true;
  2834. }
  2835. //! Handle fall damage for unconscious
  2836. if (pCurrentCommandID == DayZPlayerConstants.COMMANDID_UNCONSCIOUS)
  2837. {
  2838. bool wasFalling = m_IsUnconsciousFalling;
  2839. m_IsUnconsciousFalling = PhysicsIsFalling(false);
  2840. return wasFalling && !m_IsUnconsciousFalling;
  2841. }
  2842. //! No fall damage for players currently being damaged, animation is temporary
  2843. return false;
  2844. }
  2845. override bool OnLand(int pCurrentCommandID, FallDamageData fallDamageData)
  2846. {
  2847. if (super.OnLand(pCurrentCommandID, fallDamageData))
  2848. {
  2849. return true;
  2850. }
  2851. //! Nothing happens for unconscious
  2852. //! Nothing happens for being damaged
  2853. return false;
  2854. }
  2855. override bool IsAlreadyInFallingCommand(int pCurrentCommandID)
  2856. {
  2857. if (super.IsAlreadyInFallingCommand(pCurrentCommandID))
  2858. {
  2859. return true;
  2860. }
  2861. //! Don't switch to falling command if unconscious
  2862. //! Don't switch to falling command if being damaged
  2863. return pCurrentCommandID == DayZPlayerConstants.COMMANDID_UNCONSCIOUS || pCurrentCommandID == DayZPlayerConstants.COMMANDID_DAMAGE;
  2864. }
  2865. void OnUnconsciousStart()
  2866. {
  2867. CloseInventoryMenu();
  2868. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  2869. {
  2870. SetInventorySoftLock(true);
  2871. if (m_LastCommandBeforeUnconscious != DayZPlayerConstants.COMMANDID_VEHICLE)
  2872. {
  2873. EntityAI entity_in_hands = GetHumanInventory().GetEntityInHands();
  2874. if (entity_in_hands && CanDropEntity(entity_in_hands) && !IsRestrained() && !IsSurrendered())
  2875. {
  2876. DropItem(ItemBase.Cast(entity_in_hands));
  2877. }
  2878. }
  2879. GetGame().GetSoundScene().SetSoundVolume(0,2);
  2880. m_EffectWidgets.AddSuspendRequest(EffectWidgetSuspends.UNCON);
  2881. }
  2882. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER || (!GetGame().IsMultiplayer() && GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT))
  2883. {
  2884. SetSynchDirty();
  2885. if (m_LastCommandBeforeUnconscious == DayZPlayerConstants.COMMANDID_VEHICLE)
  2886. {
  2887. if (m_TransportCache)
  2888. m_TransportCache.MarkCrewMemberUnconscious(m_TransportCache.CrewMemberIndex(this));
  2889. }
  2890. // disable voice communication
  2891. GetGame().EnableVoN(this, false);
  2892. if (m_AdminLog)
  2893. {
  2894. m_AdminLog.UnconStart(this);
  2895. }
  2896. // When we fall uncon we force out of block
  2897. if (GetMeleeFightLogic())
  2898. {
  2899. GetMeleeFightLogic().SetBlock(false);
  2900. }
  2901. }
  2902. SetMasterAttenuation("UnconsciousAttenuation");
  2903. if (m_OnUnconsciousStart)
  2904. m_OnUnconsciousStart.Invoke(this);
  2905. }
  2906. void OnUnconsciousStop(int pCurrentCommandID)
  2907. {
  2908. m_UnconRefillModifier =1;
  2909. SetSynchDirty();
  2910. m_UnconsciousTime = 0;
  2911. m_UnconsciousVignetteTarget = 2;
  2912. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  2913. {
  2914. if (pCurrentCommandID != DayZPlayerConstants.COMMANDID_DEATH)
  2915. {
  2916. GetGame().GetSoundScene().SetSoundVolume(g_Game.m_volume_sound,1);
  2917. PPERequesterBank.GetRequester(PPERequester_UnconEffects).Stop();
  2918. GetGame().GetMission().GetHud().ShowHudUI(true);
  2919. GetGame().GetMission().GetHud().ShowQuickbarUI(true);
  2920. if (GetGame().GetUIManager().IsDialogVisible())
  2921. {
  2922. GetGame().GetUIManager().CloseDialog();
  2923. }
  2924. if (GetGame().GetUIManager().IsMenuOpen(MENU_RESPAWN_DIALOGUE))
  2925. {
  2926. GetGame().GetUIManager().FindMenu(MENU_RESPAWN_DIALOGUE).Close();
  2927. }
  2928. }
  2929. SetInventorySoftLock(false);
  2930. m_EffectWidgets.RemoveSuspendRequest(EffectWidgetSuspends.UNCON);
  2931. }
  2932. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  2933. {
  2934. // enable voice communication
  2935. if (IsAlive())
  2936. GetGame().EnableVoN(this, true);
  2937. if (m_AdminLog)
  2938. {
  2939. m_AdminLog.UnconStop(this);
  2940. }
  2941. }
  2942. SetMasterAttenuation("");
  2943. if (m_OnUnconsciousStop)
  2944. m_OnUnconsciousStop.Invoke(this);
  2945. }
  2946. void OnUnconsciousUpdate(float pDt, int last_command)
  2947. {
  2948. m_UnconsciousTime += pDt;
  2949. if (GetGame().IsServer())
  2950. {
  2951. int shock_simplified = SimplifyShock();
  2952. if (m_ShockSimplified != shock_simplified)
  2953. {
  2954. m_ShockSimplified = shock_simplified;
  2955. SetSynchDirty();
  2956. }
  2957. if (m_UnconsciousTime > PlayerConstants.UNCONSCIOUS_IN_WATER_TIME_LIMIT_TO_DEATH && last_command == DayZPlayerConstants.COMMANDID_SWIM)
  2958. {
  2959. SetHealth("","",-100);
  2960. }
  2961. }
  2962. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  2963. {
  2964. GetGame().GetMission().GetHud().ShowHudUI(false);
  2965. GetGame().GetMission().GetHud().ShowQuickbarUI(false);
  2966. if (GetPulseType() == EPulseType.REGULAR)
  2967. {
  2968. float shock_simple_normalized = GetSimplifiedShockNormalized();
  2969. float sin = Math.Sin(m_UnconsciousTime * 0.3);
  2970. float sin_normalized = (sin + 1) / 2;
  2971. if (sin_normalized < 0.05)
  2972. {
  2973. m_UnconsciousVignetteTarget = (1 - shock_simple_normalized / 3) * 2/*vignette max*/;
  2974. }
  2975. float vignette = Math.Lerp(2,m_UnconsciousVignetteTarget, sin_normalized);
  2976. m_UnconParam.param1 = vignette;
  2977. PPERequesterBank.GetRequester(PPERequester_UnconEffects).Start(m_UnconParam);
  2978. }
  2979. }
  2980. }
  2981. int SimplifyShock()
  2982. {
  2983. int shock = Math.Lerp(0, SIMPLIFIED_SHOCK_CAP, GetHealth("","Shock") / GetMaxHealth("","Shock"));
  2984. shock = Math.Clamp(shock, 0, SIMPLIFIED_SHOCK_CAP);
  2985. return shock;
  2986. }
  2987. float GetSimplifiedShockNormalized()
  2988. {
  2989. return (m_ShockSimplified / SIMPLIFIED_SHOCK_CAP);
  2990. }
  2991. override bool IsUnconscious()
  2992. {
  2993. return m_MovementState.m_CommandTypeId == DayZPlayerConstants.COMMANDID_UNCONSCIOUS || m_IsUnconscious;
  2994. }
  2995. override bool IsUnconsciousStateOnly()
  2996. {
  2997. return m_IsUnconscious;
  2998. }
  2999. override bool CanBeTargetedByAI(EntityAI ai)
  3000. {
  3001. #ifdef DIAG_DEVELOPER
  3002. if (!m_CanBeTargetedDebug)
  3003. {
  3004. return false;
  3005. }
  3006. #endif
  3007. return super.CanBeTargetedByAI(ai) && !IsUnconscious() && !IsInVehicle();
  3008. }
  3009. void GiveShock(float shock)
  3010. {
  3011. AddHealth("","Shock",shock);
  3012. }
  3013. void OnRestrainStart()
  3014. {
  3015. CloseInventoryMenu();
  3016. GetGame().GetMission().RemoveActiveInputExcludes({"inventory"},true);
  3017. GetGame().GetMission().RemoveActiveInputRestriction(EInputRestrictors.INVENTORY);
  3018. }
  3019. //! functionality moved to ShockMdfr::OnTick
  3020. void ShockRefill(float pDt);
  3021. //BrokenLegs
  3022. // -----------------------
  3023. eBrokenLegs GetBrokenLegs()
  3024. {
  3025. return Math.AbsInt(m_BrokenLegState);//negative value denotes first time activation
  3026. }
  3027. //Server side
  3028. void SetBrokenLegs(int stateId)
  3029. {
  3030. m_BrokenLegState = stateId;
  3031. DayZPlayerSyncJunctures.SendBrokenLegsEx(this, stateId);
  3032. eBrokenLegs state = GetBrokenLegs();//m_BrokenLegState can go bellow 0, cannot be used directly
  3033. if (state == eBrokenLegs.NO_BROKEN_LEGS)
  3034. {
  3035. m_InjuryHandler.m_ForceInjuryAnimMask = m_InjuryHandler.m_ForceInjuryAnimMask & ~eInjuryOverrides.BROKEN_LEGS;
  3036. m_InjuryHandler.m_ForceInjuryAnimMask = m_InjuryHandler.m_ForceInjuryAnimMask & ~eInjuryOverrides.BROKEN_LEGS_SPLINT;
  3037. }
  3038. else if (state == eBrokenLegs.BROKEN_LEGS)
  3039. {
  3040. SetLegHealth();
  3041. }
  3042. else if (state == eBrokenLegs.BROKEN_LEGS_SPLINT)
  3043. {
  3044. // handle splint here
  3045. }
  3046. SetSynchDirty();
  3047. }
  3048. //Update of state
  3049. void UpdateBrokenLegs(int stateId)
  3050. {
  3051. eBrokenLegs state = GetBrokenLegs();
  3052. //Raise broken legs flag and force to prone
  3053. if (state != eBrokenLegs.NO_BROKEN_LEGS)
  3054. {
  3055. if (state == eBrokenLegs.BROKEN_LEGS_SPLINT)
  3056. {
  3057. if (m_MovementState.m_iStanceIdx != DayZPlayerConstants.STANCEIDX_PRONE)
  3058. {
  3059. m_InjuryHandler.m_ForceInjuryAnimMask = m_InjuryHandler.m_ForceInjuryAnimMask & ~eInjuryOverrides.PRONE_ANIM_OVERRIDE;
  3060. m_InjuryHandler.m_ForceInjuryAnimMask = m_InjuryHandler.m_ForceInjuryAnimMask & ~eInjuryOverrides.BROKEN_LEGS;
  3061. m_InjuryHandler.m_ForceInjuryAnimMask = m_InjuryHandler.m_ForceInjuryAnimMask | eInjuryOverrides.BROKEN_LEGS_SPLINT;
  3062. }
  3063. m_InjuryHandler.CheckValue(false);
  3064. }
  3065. else if (state == eBrokenLegs.BROKEN_LEGS)
  3066. {
  3067. if (m_MovementState.m_iStanceIdx != DayZPlayerConstants.STANCEIDX_PRONE)
  3068. {
  3069. m_InjuryHandler.m_ForceInjuryAnimMask = m_InjuryHandler.m_ForceInjuryAnimMask & ~eInjuryOverrides.PRONE_ANIM_OVERRIDE;
  3070. m_InjuryHandler.m_ForceInjuryAnimMask = m_InjuryHandler.m_ForceInjuryAnimMask & ~eInjuryOverrides.BROKEN_LEGS_SPLINT;
  3071. m_InjuryHandler.m_ForceInjuryAnimMask = m_InjuryHandler.m_ForceInjuryAnimMask | eInjuryOverrides.BROKEN_LEGS;
  3072. }
  3073. BrokenLegWalkShock();
  3074. m_InjuryHandler.CheckValue(false);
  3075. }
  3076. }
  3077. else if (state == eBrokenLegs.NO_BROKEN_LEGS)
  3078. {
  3079. m_InjuryHandler.m_ForceInjuryAnimMask = m_InjuryHandler.m_ForceInjuryAnimMask & ~eInjuryOverrides.BROKEN_LEGS;
  3080. m_InjuryHandler.m_ForceInjuryAnimMask = m_InjuryHandler.m_ForceInjuryAnimMask & ~eInjuryOverrides.BROKEN_LEGS_SPLINT;
  3081. }
  3082. }
  3083. void BreakLegSound()
  3084. {
  3085. PlaySoundSet(m_BrokenLegSound, SOUND_BREAK_LEG, 0.1, 0.1);
  3086. }
  3087. void BrokenLegForceProne(bool forceOverride = false)
  3088. {
  3089. if (!IsInWater() && !IsSwimming() && !IsClimbingLadder() && !IsInVehicle() && !IsClimbing() && DayZPlayerUtils.PlayerCanChangeStance(this, DayZPlayerConstants.STANCEIDX_PRONE))
  3090. {
  3091. if (m_MovementState.m_iStanceIdx != DayZPlayerConstants.STANCEIDX_PRONE && m_MovementState.m_iStanceIdx != DayZPlayerConstants.STANCEIDX_RAISEDPRONE)
  3092. {
  3093. EntityAI attachment;
  3094. Class.CastTo(attachment, GetItemOnSlot("Splint_Right"));
  3095. if (attachment && attachment.GetType() == "Splint_Applied")
  3096. {
  3097. attachment.Delete();
  3098. }
  3099. m_ShockHandler.SetShock(PlayerConstants.BROKEN_LEGS_INITIAL_SHOCK);
  3100. m_ShockHandler.CheckValue(true);
  3101. if (m_ShockHandler.GetCurrentShock() >= 25) //Prevent conflict with unconsciousness by not forcing prone when going uncon (25 shock or less left)
  3102. {
  3103. //calcels user action
  3104. HumanCommandActionCallback cmd = GetCommand_Action();
  3105. if (cmd)
  3106. {
  3107. cmd.Cancel();
  3108. }
  3109. StopHandEvent();
  3110. //Get command move and verify not null
  3111. HumanCommandMove hcm = StartCommand_Move();//not sure why this is here
  3112. hcm = GetCommand_Move();
  3113. if (hcm)
  3114. {
  3115. hcm.ForceStance(DayZPlayerConstants.STANCEIDX_PRONE);
  3116. }
  3117. }
  3118. }
  3119. }
  3120. m_JumpClimb.CheckAndFinishJump();
  3121. }
  3122. //Used to inflict shock when player is walking (only inflicted on Update timer)
  3123. void BrokenLegWalkShock()
  3124. {
  3125. //No need to pursue here if player is prone as the following logic is not applied
  3126. if (m_MovementState.m_iStanceIdx != DayZPlayerConstants.STANCEIDX_PRONE && m_MovementState.m_iStanceIdx != DayZPlayerConstants.STANCEIDX_RAISEDPRONE)
  3127. {
  3128. float avgLegHealth = GetHealth("RightLeg","") + GetHealth("LeftLeg","") + GetHealth("RightFoot","") + GetHealth("LeftFoot","");
  3129. avgLegHealth *= 0.25; //divide by 4 to make the average leg health;
  3130. if (IsSwimming())
  3131. {
  3132. //swimming other than forward is not detectable in script other than through velocity check
  3133. vector v;
  3134. PhysicsGetVelocity(v);
  3135. if (v.LengthSq() > 0)
  3136. {
  3137. m_ShockHandler.SetShock(PlayerConstants.BROKEN_LEGS_SHOCK_SWIM);
  3138. }
  3139. }
  3140. else if (m_MovementState.m_iMovement != 0)
  3141. {
  3142. if (IsClimbingLadder())
  3143. {
  3144. MovingShock(avgLegHealth, PlayerConstants.BROKEN_LEGS_HIGH_SHOCK_WALK, PlayerConstants.BROKEN_LEGS_MID_SHOCK_WALK, PlayerConstants.BROKEN_LEGS_LOW_SHOCK_WALK);
  3145. }
  3146. else if (m_MovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_ERECT || m_MovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_RAISEDERECT)
  3147. {
  3148. if (m_MovementState.m_iMovement > 1)//only jog and faster
  3149. {
  3150. MovingShock(avgLegHealth, PlayerConstants.BROKEN_LEGS_HIGH_SHOCK_WALK, PlayerConstants.BROKEN_LEGS_MID_SHOCK_WALK, PlayerConstants.BROKEN_LEGS_LOW_SHOCK_WALK);
  3151. }
  3152. }
  3153. else if (m_MovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_CROUCH || m_MovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_RAISEDCROUCH)
  3154. {
  3155. //any speed other than idle
  3156. MovingShock(avgLegHealth, PlayerConstants.BROKEN_LEGS_HIGH_SHOCK_WALK * PlayerConstants.BROKEN_CROUCH_MODIFIER, PlayerConstants.BROKEN_LEGS_MID_SHOCK_WALK * PlayerConstants.BROKEN_CROUCH_MODIFIER, PlayerConstants.BROKEN_LEGS_LOW_SHOCK_WALK * PlayerConstants.BROKEN_CROUCH_MODIFIER);
  3157. }
  3158. }
  3159. else
  3160. {
  3161. //Here apply shock if player is standing or crouched and STANDING STILL
  3162. m_ShockHandler.SetShock(PlayerConstants.BROKEN_LEGS_STAND_SHOCK);
  3163. }
  3164. m_ShockHandler.CheckValue(true);
  3165. }
  3166. }
  3167. //Always use the same thresholds but allow passing of different shock values
  3168. void MovingShock(float legHealth, float highShock, float midShock, float lowShock)
  3169. {
  3170. if (legHealth <= PlayerConstants.BROKEN_LEGS_LOW_HEALTH_THRESHOLD)
  3171. {
  3172. //Inflict "high shock"
  3173. m_ShockHandler.SetShock(highShock);
  3174. }
  3175. else if (legHealth >= PlayerConstants.BROKEN_LEGS_HIGH_HEALTH_THRESHOLD)
  3176. {
  3177. //Inflict "low shock"
  3178. m_ShockHandler.SetShock(lowShock);
  3179. }
  3180. else
  3181. {
  3182. //If neither high nore low, inflict "mid shock"
  3183. m_ShockHandler.SetShock(midShock);
  3184. }
  3185. }
  3186. void DealShock(float dmg)
  3187. {
  3188. Param1<float> damage = new Param1<float>(0);
  3189. damage.param1 = dmg;
  3190. GetGame().RPCSingleParam(this, ERPCs.RPC_SHOCK, damage, true, GetIdentity());
  3191. }
  3192. //Prevent player from picking up heavy items when legs are broken
  3193. override bool CanPickupHeavyItem(notnull EntityAI item)
  3194. {
  3195. if (item.IsHeavyBehaviour() && (GetBrokenLegs() == eBrokenLegs.BROKEN_LEGS || GetBrokenLegs() == eBrokenLegs.BROKEN_LEGS_SPLINT))
  3196. return false;
  3197. return super.CanPickupHeavyItem(item);
  3198. }
  3199. //Set all leg zones' health to 0 in order to limit emergent behaviour and prevent confusion as to how broken legs really work
  3200. void SetLegHealth()
  3201. {
  3202. SetHealth("RightLeg", "", 0);
  3203. SetHealth("RightFoot", "", 0);
  3204. SetHealth("LeftLeg", "", 0);
  3205. SetHealth("LeftFoot", "", 0);
  3206. }
  3207. void DropHeavyItem()
  3208. {
  3209. ItemBase itemInHands = GetItemInHands();
  3210. if (itemInHands && itemInHands.IsHeavyBehaviour())
  3211. DropItem(itemInHands);
  3212. }
  3213. bool IsWearingSplint()
  3214. {
  3215. EntityAI attachment;
  3216. Class.CastTo(attachment, GetItemOnSlot("Splint_Right"));
  3217. if (attachment && attachment.GetType() == "Splint_Applied")
  3218. {
  3219. return true;
  3220. }
  3221. return false;
  3222. }
  3223. // -----------------------
  3224. override void OnCommandSwimStart()
  3225. {
  3226. ItemBase itemInHands = GetItemInHands();
  3227. if (itemInHands)
  3228. {
  3229. if (itemInHands.IsHeavyBehaviour())
  3230. {
  3231. TryHideItemInHands(false);
  3232. DropHeavyItem();
  3233. }
  3234. else
  3235. {
  3236. TryHideItemInHands(true);
  3237. }
  3238. itemInHands.OnItemInHandsPlayerSwimStart(this);
  3239. }
  3240. m_AnimCommandStarting = HumanMoveCommandID.CommandSwim;
  3241. if (GetInventory())
  3242. GetInventory().LockInventory(LOCK_FROM_SCRIPT);
  3243. CloseInventoryMenu();
  3244. GetDayZGame().GetBacklit().OnSwimmingStart();
  3245. AbortWeaponEvent();
  3246. GetWeaponManager().DelayedRefreshAnimationState(10);
  3247. RequestHandAnimationStateRefresh();
  3248. GetGame().GetMission().AddActiveInputExcludes({"swimming"});
  3249. }
  3250. override void OnCommandSwimFinish()
  3251. {
  3252. TryHideItemInHands(false, true);
  3253. if (GetInventory())
  3254. GetInventory().UnlockInventory(LOCK_FROM_SCRIPT);
  3255. GetDayZGame().GetBacklit().OnSwimmingStop();
  3256. GetWeaponManager().RefreshAnimationState();
  3257. GetGame().GetMission().RemoveActiveInputExcludes({"swimming"});
  3258. }
  3259. override void OnCommandLadderStart()
  3260. {
  3261. m_AnimCommandStarting = HumanMoveCommandID.CommandLadder;
  3262. TryHideItemInHands(true);
  3263. if (GetInventory())
  3264. GetInventory().LockInventory(LOCK_FROM_SCRIPT);
  3265. CloseInventoryMenu();
  3266. GetGame().GetMission().AddActiveInputExcludes({"ladderclimbing"});
  3267. }
  3268. override void OnCommandLadderFinish()
  3269. {
  3270. TryHideItemInHands(false, true);
  3271. if (GetInventory())
  3272. GetInventory().UnlockInventory(LOCK_FROM_SCRIPT);
  3273. GetGame().GetMission().RemoveActiveInputExcludes({"ladderclimbing"});
  3274. }
  3275. override void OnCommandFallStart()
  3276. {
  3277. m_AnimCommandStarting = HumanMoveCommandID.CommandFall;
  3278. if (GetInventory())
  3279. GetInventory().LockInventory(LOCK_FROM_SCRIPT);
  3280. CloseInventoryMenu();
  3281. AbortWeaponEvent();
  3282. GetWeaponManager().DelayedRefreshAnimationState(10);
  3283. RequestHandAnimationStateRefresh();
  3284. }
  3285. override void OnCommandFallFinish()
  3286. {
  3287. if (GetInventory())
  3288. GetInventory().UnlockInventory(LOCK_FROM_SCRIPT);
  3289. GetWeaponManager().RefreshAnimationState();
  3290. }
  3291. override void OnCommandClimbStart()
  3292. {
  3293. m_AnimCommandStarting = HumanMoveCommandID.CommandClimb;
  3294. if (GetInventory())
  3295. GetInventory().LockInventory(LOCK_FROM_SCRIPT);
  3296. CloseInventoryMenu();
  3297. AbortWeaponEvent();
  3298. GetWeaponManager().DelayedRefreshAnimationState(10);
  3299. RequestHandAnimationStateRefresh();
  3300. }
  3301. override void OnCommandClimbFinish()
  3302. {
  3303. if (GetInventory())
  3304. GetInventory().UnlockInventory(LOCK_FROM_SCRIPT);
  3305. GetWeaponManager().RefreshAnimationState();
  3306. }
  3307. override void OnCommandVehicleStart()
  3308. {
  3309. m_AnimCommandStarting = HumanMoveCommandID.CommandVehicle;
  3310. if (GetInventory())
  3311. GetInventory().LockInventory(LOCK_FROM_SCRIPT);
  3312. CloseInventoryMenu();
  3313. ItemBase itemInHand = GetItemInHands();
  3314. EntityAI itemOnHead = FindAttachmentBySlotName("Headgear");
  3315. if (itemInHand && itemInHand.GetCompEM())
  3316. itemInHand.GetCompEM().SwitchOff();
  3317. TryHideItemInHands(true);
  3318. if (itemOnHead && itemOnHead.GetCompEM())
  3319. itemOnHead.GetCompEM().SwitchOff();
  3320. GetGame().GetMission().AddActiveInputExcludes({"vehicledriving"});
  3321. }
  3322. override void OnCommandVehicleFinish()
  3323. {
  3324. if (GetInventory())
  3325. GetInventory().UnlockInventory(LOCK_FROM_SCRIPT);
  3326. TryHideItemInHands(false, true);
  3327. GetGame().GetMission().RemoveActiveInputExcludes({"vehicledriving"});
  3328. }
  3329. override void OnCommandMelee2Start()
  3330. {
  3331. m_AnimCommandStarting = HumanMoveCommandID.CommandMelee2;
  3332. m_IsFighting = true;
  3333. AbortWeaponEvent();
  3334. GetWeaponManager().DelayedRefreshAnimationState(10);
  3335. RequestHandAnimationStateRefresh();
  3336. }
  3337. override void OnCommandMelee2Finish()
  3338. {
  3339. RunFightBlendTimer();
  3340. GetWeaponManager().RefreshAnimationState();
  3341. }
  3342. override void OnCommandDeathStart()
  3343. {
  3344. m_AnimCommandStarting = HumanMoveCommandID.CommandDeath;
  3345. AbortWeaponEvent();
  3346. GetWeaponManager().DelayedRefreshAnimationState(10);
  3347. RequestHandAnimationStateRefresh();
  3348. super.OnCommandDeathStart();
  3349. }
  3350. override void OnJumpStart()
  3351. {
  3352. m_ActionManager.OnJumpStart();
  3353. AbortWeaponEvent();
  3354. GetWeaponManager().DelayedRefreshAnimationState(10);
  3355. RequestHandAnimationStateRefresh();
  3356. CloseMapEx(true);
  3357. }
  3358. override void OnJumpEnd(int pLandType = 0)
  3359. {
  3360. if (m_PresenceNotifier)
  3361. {
  3362. switch (pLandType)
  3363. {
  3364. case HumanCommandFall.LANDTYPE_NONE:
  3365. case HumanCommandFall.LANDTYPE_LIGHT:
  3366. m_PresenceNotifier.ProcessEvent(EPresenceNotifierNoiseEventType.LAND_LIGHT);
  3367. break;
  3368. case HumanCommandFall.LANDTYPE_MEDIUM:
  3369. case HumanCommandFall.LANDTYPE_HEAVY:
  3370. m_PresenceNotifier.ProcessEvent(EPresenceNotifierNoiseEventType.LAND_HEAVY);
  3371. break;
  3372. }
  3373. }
  3374. GetWeaponManager().RefreshAnimationState();
  3375. }
  3376. bool IsStance(int stance, int stanceMask)
  3377. {
  3378. return ((1 << stance) & stanceMask) != 0;
  3379. }
  3380. override void OnStanceChange(int previousStance, int newStance)
  3381. {
  3382. int prone = DayZPlayerConstants.STANCEMASK_PRONE | DayZPlayerConstants.STANCEMASK_RAISEDPRONE;
  3383. int notProne = DayZPlayerConstants.STANCEMASK_ERECT | DayZPlayerConstants.STANCEMASK_CROUCH | DayZPlayerConstants.STANCEMASK_RAISEDERECT | DayZPlayerConstants.STANCEMASK_RAISEDCROUCH;
  3384. if (IsStance(previousStance, DayZPlayerConstants.STANCEMASK_PRONE) && IsStance(newStance, DayZPlayerConstants.STANCEMASK_ERECT))
  3385. m_SprintedTimePerStanceMin = PlayerConstants.FULL_SPRINT_DELAY_FROM_PRONE;
  3386. if (IsStance(previousStance, DayZPlayerConstants.STANCEMASK_PRONE) && IsStance(previousStance, DayZPlayerConstants.STANCEMASK_CROUCH) || (IsStance(previousStance, DayZPlayerConstants.STANCEMASK_CROUCH) && IsStance(newStance, DayZPlayerConstants.STANCEMASK_ERECT)))
  3387. m_SprintedTimePerStanceMin = PlayerConstants.FULL_SPRINT_DELAY_FROM_CROUCH;
  3388. if ((IsStance(previousStance, prone) && IsStance(newStance, notProne)) || (IsStance(previousStance, notProne) && IsStance(newStance, prone)))
  3389. {
  3390. AbortWeaponEvent();
  3391. GetWeaponManager().RefreshAnimationState();
  3392. }
  3393. }
  3394. override bool CanChangeStance(int previousStance, int newStance)
  3395. {
  3396. // Check if the player is playing a throwing animation
  3397. if (GetThrowing().IsThrowingAnimationPlaying())
  3398. {
  3399. return false;
  3400. }
  3401. // don't allow base stance change, only raised hands change
  3402. if (IsRolling())
  3403. {
  3404. if (Math.AbsInt(previousStance - newStance) == 3)
  3405. return true;
  3406. return false;
  3407. }
  3408. // Check if the player is going to crouch or raised crouch
  3409. if (newStance == DayZPlayerConstants.STANCEIDX_CROUCH || newStance == DayZPlayerConstants.STANCEIDX_RAISEDCROUCH)
  3410. {
  3411. return GetCurrentWaterLevel() <= GetDayZPlayerType().CommandSwimSettingsW().m_fToErectLevel;
  3412. }
  3413. // Check if the player is going to prone
  3414. if (newStance == DayZPlayerConstants.STANCEIDX_PRONE || newStance == DayZPlayerConstants.STANCEIDX_RAISEDPRONE)
  3415. {
  3416. return GetCurrentWaterLevel() <= GetDayZPlayerType().CommandSwimSettingsW().m_fToCrouchLevel;
  3417. }
  3418. // The player can change stance if none of the conditions above are met
  3419. return true;
  3420. }
  3421. override void OnCommandMoveStart()
  3422. {
  3423. if (GetGame().IsServer())
  3424. {
  3425. //In case player changes stance through a different command, we refresh the anim overrides
  3426. int prone = DayZPlayerConstants.STANCEMASK_PRONE | DayZPlayerConstants.STANCEMASK_RAISEDPRONE;
  3427. if (!IsPlayerInStance(prone))
  3428. {
  3429. m_InjuryHandler.m_ForceInjuryAnimMask = m_InjuryHandler.m_ForceInjuryAnimMask & ~eInjuryOverrides.PRONE_ANIM_OVERRIDE;
  3430. ForceUpdateInjuredState();
  3431. }
  3432. }
  3433. }
  3434. override bool CanRoll()
  3435. {
  3436. if (!CanConsumeStamina(EStaminaConsumers.ROLL))
  3437. return false;
  3438. if (IsInFBEmoteState() || m_EmoteManager.m_MenuEmote)
  3439. {
  3440. return false;
  3441. }
  3442. return IsPlayerInStance(DayZPlayerConstants.STANCEMASK_PRONE | DayZPlayerConstants.STANCEMASK_RAISEDPRONE) && GetCommand_Move() && !GetCommand_Move().IsOnBack();
  3443. }
  3444. override void OnRollStart(bool isToTheRight)
  3445. {
  3446. DepleteStamina(EStaminaModifiers.ROLL);
  3447. if (GetBrokenLegs() == eBrokenLegs.BROKEN_LEGS)
  3448. m_ShockHandler.SetShock(PlayerConstants.BROKEN_LEGS_ROLL_SHOCK);
  3449. }
  3450. override void OnRollFinish()
  3451. {
  3452. }
  3453. void OnJumpOutVehicleFinish(float carSpeed)
  3454. {
  3455. string surfaceType;
  3456. int liquidType;
  3457. GetGame().SurfaceUnderObject(this, surfaceType, liquidType);
  3458. }
  3459. void OnVehicleSwitchSeat(int seatIndex)
  3460. {
  3461. }
  3462. override void OnVehicleSeatDriverEnter()
  3463. {
  3464. m_IsVehicleSeatDriver = true;
  3465. if (m_Hud)
  3466. m_Hud.ShowVehicleInfo();
  3467. #ifdef FEATURE_NETWORK_RECONCILIATION
  3468. PlayerIdentity identity = GetIdentity();
  3469. if (identity)
  3470. {
  3471. Pawn pawn = Pawn.Cast(GetParent());
  3472. //! Hand off control to the vehicle - null is valid
  3473. identity.Possess(pawn);
  3474. }
  3475. #endif
  3476. }
  3477. override void OnVehicleSeatDriverLeft()
  3478. {
  3479. #ifdef FEATURE_NETWORK_RECONCILIATION
  3480. PlayerIdentity identity = GetIdentity();
  3481. //! Don't possess the player if we are in the vehicle and unconscious, we are still the driver!
  3482. if (identity && !m_ShouldBeUnconscious)
  3483. {
  3484. //! And now we want to resume control of the player
  3485. identity.Possess(this);
  3486. }
  3487. #endif
  3488. m_IsVehicleSeatDriver = false;
  3489. if (m_Hud)
  3490. m_Hud.HideVehicleInfo();
  3491. }
  3492. override void OnThrowingModeChange(bool change_to_enabled)
  3493. {
  3494. if (change_to_enabled)
  3495. {
  3496. PlacingCancelLocal();
  3497. PlacingCancelServer();
  3498. }
  3499. }
  3500. override void EOnFrame(IEntity other, float timeSlice)
  3501. {
  3502. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  3503. {
  3504. #ifndef NO_GUI
  3505. m_Hud.Update(timeSlice);
  3506. if (IsControlledPlayer() && m_EffectWidgets && m_EffectWidgets.IsAnyEffectRunning())
  3507. {
  3508. m_EffectWidgets.Update(timeSlice);
  3509. }
  3510. #endif
  3511. if (m_UndergroundHandler)
  3512. m_UndergroundHandler.Tick(timeSlice);
  3513. if (m_UndergroundBunkerHandler)
  3514. m_UndergroundBunkerHandler.Tick(timeSlice);
  3515. }
  3516. if (m_InEffectAreaType != 0 && GetGame().IsServer())
  3517. OnUpdateEffectAreaServer(timeSlice);
  3518. }
  3519. override void EOnPostFrame(IEntity other, int extra)
  3520. {
  3521. float delta_time = (GetGame().GetTime() - m_LastPostFrameTickTime) / 1000;
  3522. m_LastPostFrameTickTime = GetGame().GetTime();
  3523. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  3524. {
  3525. if (GetDamageDealtEffect())
  3526. {
  3527. if (IsAlive())
  3528. GetDamageDealtEffect().Update(delta_time);
  3529. else
  3530. delete GetDamageDealtEffect();
  3531. }
  3532. if (m_EffectRadial)
  3533. {
  3534. if (IsAlive())
  3535. {
  3536. m_EffectRadial.Update(delta_time);
  3537. }
  3538. else
  3539. m_EffectRadial = null;
  3540. }
  3541. if (GetFlashbangEffect())
  3542. {
  3543. if (IsAlive())
  3544. {
  3545. GetFlashbangEffect().Update(delta_time);
  3546. }
  3547. else
  3548. {
  3549. GetFlashbangEffect().Stop();
  3550. delete GetFlashbangEffect();
  3551. }
  3552. }
  3553. if (GetShockEffect())
  3554. {
  3555. if (IsAlive())
  3556. GetShockEffect().Update(delta_time);
  3557. else
  3558. delete GetShockEffect();
  3559. }
  3560. m_InventoryActionHandler.OnUpdate();
  3561. }
  3562. #ifdef DIAG_DEVELOPER
  3563. DiagOnPostFrame(other, extra);
  3564. #endif
  3565. }
  3566. #ifdef DIAG_DEVELOPER
  3567. protected void DiagOnPostFrame(IEntity other, int extra)
  3568. {
  3569. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  3570. {
  3571. if (m_WeaponDebug)
  3572. {
  3573. m_WeaponDebug.OnPostFrameUpdate();
  3574. }
  3575. if (GetBleedingManagerRemote())
  3576. {
  3577. GetBleedingManagerRemote().OnUpdate();
  3578. }
  3579. if (m_MeleeCombat)
  3580. {
  3581. if (DiagMenu.GetBool(DiagMenuIDs.MELEE_DEBUG))
  3582. {
  3583. m_MeleeDebug = true;
  3584. m_MeleeCombat.Debug(GetItemInHands(), m_MeleeCombat.GetHitType());
  3585. }
  3586. else if (!DiagMenu.GetBool(DiagMenuIDs.MELEE_DEBUG) && m_MeleeDebug)
  3587. {
  3588. m_MeleeDebug = false;
  3589. m_MeleeCombat.Debug(GetItemInHands(), m_MeleeCombat.GetHitType());
  3590. }
  3591. }
  3592. if (DiagMenu.GetBool(DiagMenuIDs.SOUNDS_ITEM_IMPACT_SOUNDS))
  3593. InventoryItem.DrawImpacts();
  3594. if (GetPluginManager())
  3595. {
  3596. PluginDrawCheckerboard drawCheckerboard = PluginDrawCheckerboard.Cast(GetPluginManager().GetPluginByType(PluginDrawCheckerboard));
  3597. if (drawCheckerboard && !drawCheckerboard.IsActive())
  3598. {
  3599. drawCheckerboard.ShowWidgets(DiagMenu.GetBool(DiagMenuIDs.MISC_DRAW_CHECKERBOARD));
  3600. }
  3601. }
  3602. if (m_PresenceNotifier)
  3603. {
  3604. m_PresenceNotifier.EnableDebug(DiagMenu.GetBool(DiagMenuIDs.MISC_PRESENCE_NOTIFIER_DBG));
  3605. }
  3606. if (m_TargetTemperatureDiag)
  3607. {
  3608. m_TargetTemperatureDiag.ShowDebug(DiagMenu.GetBool(DiagMenuIDs.MISC_TARGET_TEMPERATURE));
  3609. }
  3610. if (DiagMenu.GetBool(DiagMenuIDs.TRIGGER_PLAYER_DEBUG))
  3611. {
  3612. vector minmax[2];
  3613. GetCollisionBox(minmax);
  3614. int color = COLOR_RED_A;
  3615. if (m_IsInsideTrigger)
  3616. color = COLOR_GREEN_A;
  3617. Shape dbgShape = Debug.DrawBoxEx(minmax[0], minmax[1], color, ShapeFlags.TRANSP|ShapeFlags.NOZWRITE|ShapeFlags.ONCE);
  3618. vector mat[4];
  3619. GetTransform(mat);
  3620. dbgShape.CreateMatrix(mat);
  3621. dbgShape.SetMatrix(mat);
  3622. }
  3623. }
  3624. if (m_Environment && m_Environment.m_Debug)
  3625. {
  3626. #ifdef SERVER
  3627. EnvDebugData envDebugData = m_Environment.GetEnvDebugData();
  3628. GetGame().RPCSingleParam(this, ERPCs.DIAG_MISC_ENVIRONMENT_DEBUG_DATA, envDebugData, false, GetIdentity());
  3629. #else
  3630. m_Environment.ShowEnvDebugPlayerInfo(DiagMenu.GetBool(DiagMenuIDs.MISC_ENVIRONMENT_DEBUG));
  3631. #endif
  3632. }
  3633. if (m_FallDamage && m_FallDamage.m_Debug)
  3634. {
  3635. #ifdef SERVER
  3636. FallDamageDebugData fallDamageDebugData = m_FallDamage.GetFallDamageDebugData();
  3637. GetGame().RPCSingleParam(this, ERPCs.DIAG_MISC_FALLDAMAGE_DEBUG_DATA, fallDamageDebugData, false, GetIdentity());
  3638. #else
  3639. m_FallDamage.ShowFallDamageDebugInfo(DiagMenu.GetBool(DiagMenuIDs.MISC_FALLDAMAGE_DEBUG));
  3640. #endif
  3641. }
  3642. }
  3643. override void OnEnterTrigger(ScriptedEntity trigger)
  3644. {
  3645. super.OnEnterTrigger(trigger);
  3646. ++m_IsInsideTrigger;
  3647. }
  3648. override void OnLeaveTrigger(ScriptedEntity trigger)
  3649. {
  3650. super.OnLeaveTrigger(trigger);
  3651. --m_IsInsideTrigger;
  3652. }
  3653. #endif
  3654. void StaminaHUDNotifier(bool show)
  3655. {
  3656. if (m_Hud)
  3657. m_Hud.SetStaminaBarVisibility(show);
  3658. }
  3659. override void DepleteStamina(EStaminaModifiers modifier, float dT = -1)
  3660. {
  3661. if (GetStaminaHandler())
  3662. GetStaminaHandler().DepleteStamina(modifier,dT);
  3663. }
  3664. override bool CanConsumeStamina(EStaminaConsumers consumer)
  3665. {
  3666. if (!GetStaminaHandler()) return false;
  3667. bool val = (GetStaminaHandler().HasEnoughStaminaFor(consumer) /*&& !IsOverloaded()*/ && !IsRestrained() && !IsInFBEmoteState());
  3668. if (!val)
  3669. StaminaHUDNotifier(false);
  3670. return val;
  3671. }
  3672. override bool CanStartConsumingStamina(EStaminaConsumers consumer)
  3673. {
  3674. if (!GetStaminaHandler()) return false;
  3675. bool val = (GetStaminaHandler().HasEnoughStaminaToStart(consumer) && !IsRestrained() && !IsInFBEmoteState());
  3676. if (!val)
  3677. StaminaHUDNotifier(false);
  3678. return val;
  3679. }
  3680. override bool CanClimb(int climbType, SHumanCommandClimbResult climbRes)
  3681. {
  3682. if (GetBrokenLegs() == eBrokenLegs.BROKEN_LEGS)
  3683. return false;
  3684. if (climbType == 1 && !CanConsumeStamina(EStaminaConsumers.VAULT))
  3685. return false;
  3686. //! vault from water allowed
  3687. if (IsSwimming())
  3688. return true;
  3689. if (climbType == 2 && (!CanConsumeStamina(EStaminaConsumers.CLIMB) || GetBrokenLegs() != eBrokenLegs.NO_BROKEN_LEGS))
  3690. return false;
  3691. if (climbType > 0 && m_InjuryHandler && m_InjuryHandler.GetInjuryAnimValue() >= InjuryAnimValues.LVL3)
  3692. return false;
  3693. return super.CanClimb(climbType,climbRes);
  3694. }
  3695. override bool CanJump()
  3696. {
  3697. if (GetBrokenLegs() != eBrokenLegs.NO_BROKEN_LEGS)
  3698. {
  3699. return false;
  3700. }
  3701. if (!CanConsumeStamina(EStaminaConsumers.JUMP))
  3702. return false;
  3703. //! disables jump when player is significantly injured
  3704. if (m_InjuryHandler && m_InjuryHandler.GetInjuryAnimValue() >= InjuryAnimValues.LVL3)
  3705. return false;
  3706. if (IsInFBEmoteState() || m_EmoteManager.m_MenuEmote)
  3707. {
  3708. return false;
  3709. }
  3710. return super.CanJump();
  3711. }
  3712. bool IsJumpInProgress()
  3713. {
  3714. return m_JumpClimb.m_bIsJumpInProgress;
  3715. }
  3716. bool IsTargetInActiveRefresherRange(EntityAI target)
  3717. {
  3718. array<vector> temp = new array<vector>;
  3719. temp = GetGame().GetMission().GetActiveRefresherLocations();
  3720. int count = temp.Count();
  3721. if (count > 0)
  3722. {
  3723. vector pos = target.GetPosition();
  3724. for (int i = 0; i < count; i++)
  3725. {
  3726. if (vector.Distance(pos,temp.Get(i)) < GameConstants.REFRESHER_RADIUS)
  3727. return true;
  3728. }
  3729. return false;
  3730. }
  3731. else
  3732. {
  3733. return false;
  3734. }
  3735. }
  3736. void RequestHandAnimationStateRefresh()
  3737. {
  3738. if ((GetGame().IsMultiplayer() && GetGame().IsServer()))
  3739. {
  3740. m_RefreshAnimStateIdx++;
  3741. if (m_RefreshAnimStateIdx > 3)
  3742. m_RefreshAnimStateIdx = 0;
  3743. SetSynchDirty();
  3744. }
  3745. }
  3746. void RefreshHandAnimationState(int delay = 0)
  3747. {
  3748. if (delay == 0)
  3749. {
  3750. GetItemAccessor().OnItemInHandsChanged(true);
  3751. GetItemAccessor().ResetWeaponInHands();
  3752. }
  3753. else
  3754. {
  3755. GetGame().GetCallQueue(CALL_CATEGORY_GUI).CallLater(RefreshHandAnimationState,delay,false,0);
  3756. }
  3757. }
  3758. // -------------------------------------------------------------------------
  3759. // USER ACTIONS
  3760. // -------------------------------------------------------------------------
  3761. bool IsFacingTarget(Object target)
  3762. {
  3763. vector pdir = GetDirection();
  3764. vector ptv = target.GetPosition() - GetPosition();
  3765. pdir.Normalize();
  3766. ptv.Normalize();
  3767. if (Math.AbsFloat(pdir[0]-ptv[0]) < 0.5 && Math.AbsFloat(pdir[2]-ptv[2]) < 0.5)
  3768. {
  3769. return true;
  3770. }
  3771. return false;
  3772. }
  3773. //---------------------------------------------------------
  3774. void OnQuickBarSingleUse(int slotClicked)
  3775. {
  3776. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  3777. return;
  3778. if (m_AreHandsLocked)
  3779. return; //Player is in the short window of time after interrupting placement of an item and before getting it back in hands
  3780. if (GetInventory().IsInventoryLocked() || IsEmotePlaying())
  3781. return;
  3782. if (GetThrowing().IsThrowingModeEnabled() || GetThrowing().IsThrowingAnimationPlaying())
  3783. return;
  3784. if (IsRaised() || GetCommand_Melee() || IsSwimming() || IsClimbingLadder() || IsClimbing() || IsRestrained() || IsRestrainPrelocked())
  3785. return;
  3786. if (GetDayZPlayerInventory().IsProcessing() || IsItemsToDelete())
  3787. return;
  3788. if (GetActionManager().GetRunningAction() != null)
  3789. return;
  3790. if (GetWeaponManager() && GetWeaponManager().IsRunning())
  3791. return;
  3792. if (!ScriptInputUserData.CanStoreInputUserData())
  3793. return;
  3794. //TODO MW change locking method
  3795. //if (GetDayZPlayerInventory().HasLockedHands())
  3796. // return;
  3797. EntityAI quickBarEntity = GetQuickBarEntity(slotClicked - 1);//GetEntityInQuickBar(slotClicked - 1);
  3798. if (!quickBarEntity)
  3799. return;
  3800. Magazine mag;
  3801. Weapon_Base wpn;
  3802. if (Class.CastTo(mag, quickBarEntity) && Class.CastTo(wpn, mag.GetHierarchyParent()))
  3803. return;
  3804. EntityAI inHandEntity = GetHumanInventory().GetEntityInHands();
  3805. if (!GetDayZPlayerInventory().IsIdle())
  3806. return; // player is already performing some animation
  3807. InventoryLocation handInventoryLocation = new InventoryLocation;
  3808. handInventoryLocation.SetHands(this,quickBarEntity);
  3809. if (this.GetInventory().HasInventoryReservation(quickBarEntity, handInventoryLocation))
  3810. return;
  3811. if (inHandEntity == quickBarEntity)
  3812. {
  3813. if (GetHumanInventory().CanRemoveEntityInHands())
  3814. {
  3815. if (LogManager.IsSyncLogEnable()) syncDebugPrint("[QB] Stash - PredictiveMoveItemFromHandsToInventory HND=" + Object.GetDebugName(inHandEntity));
  3816. PredictiveMoveItemFromHandsToInventory();
  3817. }
  3818. }
  3819. else
  3820. {
  3821. InventoryLocation invLocQBItem = new InventoryLocation;
  3822. quickBarEntity.GetInventory().GetCurrentInventoryLocation(invLocQBItem);
  3823. if (GetInventory().HasInventoryReservation(quickBarEntity,invLocQBItem))
  3824. return;
  3825. if (inHandEntity)
  3826. {
  3827. InventoryLocation Reserved_Item_il = new InventoryLocation;
  3828. InventoryLocation inHandEntityFSwapDst = new InventoryLocation;
  3829. inHandEntity.GetInventory().GetCurrentInventoryLocation(inHandEntityFSwapDst);
  3830. int index = GetHumanInventory().FindUserReservedLocationIndex(inHandEntity);
  3831. if (index >= 0)
  3832. GetHumanInventory().GetUserReservedLocation(index, Reserved_Item_il);
  3833. if (Reserved_Item_il)
  3834. inHandEntityFSwapDst.CopyLocationFrom(Reserved_Item_il, true);
  3835. if (index < 0 && GameInventory.CanSwapEntitiesEx(quickBarEntity, inHandEntity))
  3836. {
  3837. if (LogManager.IsSyncLogEnable()) syncDebugPrint("[QB] PredictiveSwapEntities QB=" + Object.GetDebugName(quickBarEntity) + " HND=" + Object.GetDebugName(inHandEntity));
  3838. PredictiveSwapEntities(quickBarEntity, inHandEntity);
  3839. }
  3840. else if (GameInventory.CanForceSwapEntitiesEx(quickBarEntity, handInventoryLocation, inHandEntity, inHandEntityFSwapDst))
  3841. {
  3842. if (LogManager.IsSyncLogEnable()) syncDebugPrint("[QB] Swap - PredictiveForceSwapEntities HND=" + Object.GetDebugName(inHandEntity) + " QB=" + Object.GetDebugName(quickBarEntity) + " fswap_dst=" + InventoryLocation.DumpToStringNullSafe(inHandEntityFSwapDst));
  3843. PredictiveForceSwapEntities(quickBarEntity, inHandEntity, inHandEntityFSwapDst);
  3844. }
  3845. }
  3846. else
  3847. {
  3848. if (GetInventory().HasInventoryReservation(quickBarEntity,handInventoryLocation))
  3849. return;
  3850. if (GetInventory().CanAddEntityIntoHands(quickBarEntity))
  3851. {
  3852. if (LogManager.IsSyncLogEnable()) syncDebugPrint("[QB] Stash - PredictiveTakeEntityToHands QB=" + Object.GetDebugName(quickBarEntity));
  3853. PredictiveTakeEntityToHands(quickBarEntity);
  3854. }
  3855. }
  3856. }
  3857. }
  3858. //---------------------------------------------------------
  3859. void OnQuickBarContinuousUseStart(int slotClicked)
  3860. {
  3861. if (GetInventory().IsInventoryLocked())
  3862. return;
  3863. if (IsSwimming() || IsClimbingLadder() || GetCommand_Melee() || IsClimbing() || IsRestrained() || IsRestrainPrelocked())
  3864. return;
  3865. ItemBase quickBarItem = ItemBase.Cast(GetQuickBarEntity(slotClicked - 1));
  3866. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  3867. {
  3868. ItemBase itemInHands = ItemBase.Cast(GetHumanInventory().GetEntityInHands());
  3869. if (itemInHands != quickBarItem)
  3870. {
  3871. ActionManagerClient amc = ActionManagerClient.Cast(GetActionManager());
  3872. if (amc.CanPerformActionFromQuickbar(itemInHands, quickBarItem))
  3873. {
  3874. amc.PerformActionFromQuickbar(itemInHands, quickBarItem);
  3875. }
  3876. else
  3877. {
  3878. if (IsRaised() || GetCommand_Melee())
  3879. return;
  3880. amc.ForceTarget(quickBarItem);
  3881. m_QuickBarFT = true;
  3882. }
  3883. }
  3884. }
  3885. m_QuickBarHold = true;
  3886. }
  3887. //---------------------------------------------------------
  3888. void OnQuickBarContinuousUseEnd(int slotClicked)
  3889. {
  3890. if (m_QuickBarHold)
  3891. {
  3892. if ( GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  3893. {
  3894. ActionManagerClient am = ActionManagerClient.Cast(GetActionManager());
  3895. if (m_ActionQBControl)
  3896. {
  3897. ActionBase action = am.GetRunningAction();
  3898. if (action)
  3899. {
  3900. if (!action.GetInput().IsActive())
  3901. {
  3902. am.EndActionInput();
  3903. }
  3904. }
  3905. }
  3906. if (m_QuickBarFT)
  3907. {
  3908. am.ClearForceTarget();
  3909. m_QuickBarFT = false;
  3910. }
  3911. }
  3912. }
  3913. m_QuickBarHold = false;
  3914. }
  3915. void SetActionEndInput(ActionBase action)
  3916. {
  3917. m_ActionQBControl = !action.GetInput().IsActive();
  3918. }
  3919. bool IsQBControl()
  3920. {
  3921. return m_ActionQBControl;
  3922. }
  3923. void ResetActionEndInput()
  3924. {
  3925. m_ActionQBControl = false;
  3926. }
  3927. //---------------------------------------------------------
  3928. // RADIAL QUICKBAR AND RELOAD ACTIONS
  3929. //---------------------------------------------------------
  3930. //the same functionality as normal quick bar slot key press
  3931. void RadialQuickBarSingleUse(int slotClicked)
  3932. {
  3933. OnQuickBarSingleUse(slotClicked);
  3934. }
  3935. //removed the need for holding down quick bar slot key
  3936. void RadialQuickBarCombine(int slotClicked)
  3937. {
  3938. EntityAI quickBarEntity = GetQuickBarEntity(slotClicked - 1);
  3939. EntityAI entity_in_hands = GetHumanInventory().GetEntityInHands();
  3940. ReloadWeapon(entity_in_hands, quickBarEntity);
  3941. }
  3942. //removed the need for holding down quick bar slot key
  3943. void QuickReloadWeapon(EntityAI weapon)
  3944. {
  3945. EntityAI magazine = GetMagazineToReload(weapon);
  3946. ReloadWeapon(weapon, magazine);
  3947. }
  3948. //Reload weapon with given magazine
  3949. void ReloadWeapon(EntityAI weapon, EntityAI magazine)
  3950. {
  3951. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  3952. {
  3953. ActionManagerClient mngr_client;
  3954. CastTo(mngr_client, GetActionManager());
  3955. if (mngr_client && FirearmActionLoadMultiBulletRadial.Cast(mngr_client.GetRunningAction()))
  3956. {
  3957. mngr_client.Interrupt();
  3958. }
  3959. else if (GetHumanInventory().GetEntityInHands()!= magazine)
  3960. {
  3961. Weapon_Base wpn;
  3962. Magazine mag;
  3963. Class.CastTo(wpn, weapon);
  3964. Class.CastTo(mag, magazine);
  3965. if (GetWeaponManager().CanUnjam(wpn))
  3966. {
  3967. GetWeaponManager().Unjam();
  3968. }
  3969. else if (GetWeaponManager().CanAttachMagazine(wpn, mag))
  3970. {
  3971. GetWeaponManager().AttachMagazine(mag);
  3972. }
  3973. else if (GetWeaponManager().CanSwapMagazine(wpn, mag))
  3974. {
  3975. GetWeaponManager().SwapMagazine(mag);
  3976. }
  3977. else if (GetWeaponManager().CanLoadBullet(wpn, mag))
  3978. {
  3979. //GetWeaponManager().LoadMultiBullet(mag);
  3980. ActionTarget atrg = new ActionTarget(mag, this, -1, vector.Zero, -1.0);
  3981. if (mngr_client && !mngr_client.GetRunningAction() && mngr_client.GetAction(FirearmActionLoadMultiBulletRadial).Can(this, atrg, wpn))
  3982. mngr_client.PerformActionStart(mngr_client.GetAction(FirearmActionLoadMultiBulletRadial), atrg, wpn);
  3983. }
  3984. }
  3985. }
  3986. }
  3987. //returns compatible magazine from player inventory with highest ammo count
  3988. EntityAI GetMagazineToReload(EntityAI weapon)
  3989. {
  3990. Weapon_Base weapon_base = Weapon_Base.Cast(weapon);
  3991. WeaponManager weapon_manager = GetWeaponManager();
  3992. EntityAI magazine_to_reload;
  3993. EntityAI ammo_magazine; //magazine
  3994. int last_ammo_magazine_count;
  3995. int ammo_magazine_count;
  3996. EntityAI ammo_pile; //ammo pile
  3997. int last_ammo_pile_count;
  3998. int ammo_pile_count;
  3999. //Get all magazines in (player) inventory
  4000. for (int att_i = 0; att_i < GetInventory().AttachmentCount(); ++att_i)
  4001. {
  4002. EntityAI attachment = GetInventory().GetAttachmentFromIndex(att_i);
  4003. ref CargoBase attachment_cargo = attachment.GetInventory().GetCargo();
  4004. if (attachment_cargo)
  4005. {
  4006. for (int cgo_i = 0; cgo_i < attachment_cargo.GetItemCount(); ++cgo_i)
  4007. {
  4008. EntityAI cargo_item = attachment_cargo.GetItem(cgo_i);
  4009. //check for proper magazine
  4010. if (cargo_item.IsMagazine())
  4011. {
  4012. Magazine magazine = Magazine.Cast(cargo_item);
  4013. ammo_pile_count = magazine.GetAmmoCount();
  4014. //magazines (get magazine with max ammo count)
  4015. if (weapon_manager.CanAttachMagazine(weapon_base, magazine) || weapon_manager.CanSwapMagazine(weapon_base, magazine))
  4016. {
  4017. if (ammo_pile_count > 0)
  4018. {
  4019. if (last_ammo_magazine_count == 0)
  4020. {
  4021. ammo_magazine = magazine;
  4022. last_ammo_magazine_count = ammo_pile_count;
  4023. }
  4024. else
  4025. {
  4026. if (last_ammo_magazine_count < ammo_pile_count)
  4027. {
  4028. ammo_magazine = magazine;
  4029. last_ammo_magazine_count = ammo_pile_count;
  4030. }
  4031. }
  4032. }
  4033. }
  4034. //bullets (get ammo pile with min ammo count)
  4035. else if (weapon_manager.CanLoadBullet(weapon_base, magazine))
  4036. {
  4037. if (ammo_pile_count > 0)
  4038. {
  4039. if (last_ammo_pile_count == 0)
  4040. {
  4041. ammo_pile = magazine;
  4042. last_ammo_pile_count = ammo_pile_count;
  4043. }
  4044. else
  4045. {
  4046. if (last_ammo_pile_count > ammo_pile_count)
  4047. {
  4048. ammo_pile = magazine;
  4049. last_ammo_pile_count = ammo_pile_count;
  4050. }
  4051. }
  4052. }
  4053. }
  4054. }
  4055. }
  4056. }
  4057. }
  4058. //prioritize magazine
  4059. if (ammo_magazine)
  4060. {
  4061. return ammo_magazine;
  4062. }
  4063. return ammo_pile;
  4064. }
  4065. //---------------------------------------------------------
  4066. //---------------------------------------------------------
  4067. void OnSpawnedFromConsole()
  4068. {
  4069. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER || !GetGame().IsMultiplayer())
  4070. {
  4071. GetGame().GetMission().AddDummyPlayerToScheduler(this);
  4072. OnSelectPlayer();
  4073. }
  4074. #ifdef DIAG_DEVELOPER
  4075. if (!m_Bot)
  4076. {
  4077. m_Bot = new Bot(this);
  4078. m_Bot.Start();
  4079. }
  4080. #endif
  4081. }
  4082. //---------------------------------------------------------
  4083. //Obsolete
  4084. bool GetLiquidTendencyDrain()
  4085. {
  4086. return m_LiquidTendencyDrain;
  4087. }
  4088. //---------------------------------------------------------
  4089. //Obsolete
  4090. void SetLiquidTendencyDrain(bool state)
  4091. {
  4092. m_LiquidTendencyDrain = state;
  4093. }
  4094. //---------------------------------------------------------
  4095. //! DEPRECATED
  4096. bool GetFlagTendencyRaise()
  4097. {
  4098. return m_FlagRaisingTendency;
  4099. }
  4100. //---------------------------------------------------------
  4101. //! DEPRECATED
  4102. void SetFlagTendencyRaise(bool state)
  4103. {
  4104. m_FlagRaisingTendency = state;
  4105. }
  4106. override SoundOnVehicle PlaySound(string sound_name, float range, bool create_local = false)
  4107. {
  4108. return BetaSound.SaySound(this, sound_name, range, false);
  4109. }
  4110. float GetPlayerLoad()
  4111. {
  4112. return GetWeightEx();
  4113. }
  4114. bool IsOverloaded()
  4115. {
  4116. return GetWeightEx() >= OVERLOAD_LIMIT;
  4117. }
  4118. void SetPlayerLoad(float load)//Deprecated
  4119. {
  4120. m_CargoLoad = load;
  4121. //Print("m_CargoLoad: " + m_CargoLoad);
  4122. //Log(ToString(this) + "'s load weight is " + ftoa(m_CargoLoad) + " g.", LogTemplates.TEMPLATE_PLAYER_WEIGHT);
  4123. }
  4124. //Deprecated, will be overrid by other method calls (in order to ensure stamina calculation is properly set)
  4125. void AddPlayerLoad(float addedload)//Deprecated
  4126. {
  4127. float newload = GetPlayerLoad() + addedload;
  4128. SetPlayerLoad(newload);
  4129. // Do not need -> Log is in SetPlayerLoad
  4130. //PrintString(ToString(this) + "'s load weight is " + ToString(m_CargoLoad) + " g.");
  4131. }
  4132. bool IsItemInInventory(EntityAI entity)
  4133. {
  4134. return GetInventory().HasEntityInInventory(entity);
  4135. }
  4136. override bool NeedInventoryJunctureFromServer(notnull EntityAI item, EntityAI currParent, EntityAI newParent)
  4137. {
  4138. if (GetGame().IsMultiplayer())
  4139. {
  4140. DayZPlayerInstanceType t = GetInstanceType();
  4141. switch (t)
  4142. {
  4143. case DayZPlayerInstanceType.INSTANCETYPE_AI_SINGLEPLAYER:
  4144. return false;
  4145. case DayZPlayerInstanceType.INSTANCETYPE_CLIENT:
  4146. case DayZPlayerInstanceType.INSTANCETYPE_SERVER:
  4147. case DayZPlayerInstanceType.INSTANCETYPE_AI_SERVER:
  4148. case DayZPlayerInstanceType.INSTANCETYPE_AI_REMOTE:
  4149. case DayZPlayerInstanceType.INSTANCETYPE_REMOTE:
  4150. return true; // Might help mitigate "megabugged" (desync)
  4151. if (LogManager.IsSyncLogEnable()) syncDebugPrint("[syncinv] " + GetDebugName(this) + " STS=" + GetSimulationTimeStamp() + " NeedInventoryJunctureFromServer item=" + Object.GetDebugName(item) + " currPar=" + currParent + " newPar=" + newParent);
  4152. bool i_owned = GetHumanInventory().HasEntityInInventory(item);
  4153. bool cp_owned = false;
  4154. if (currParent)
  4155. cp_owned = GetHumanInventory().HasEntityInInventory(currParent);
  4156. bool np_owned = false;
  4157. if (newParent)
  4158. np_owned = GetHumanInventory().HasEntityInInventory(newParent);
  4159. bool all_owned = i_owned && cp_owned && (np_owned || (newParent == null));
  4160. if (LogManager.IsSyncLogEnable()) syncDebugPrint("[syncinv] " + GetDebugName(this) + " STS=" + GetSimulationTimeStamp() + " NeedInventoryJunctureFromServer=" + !all_owned + " i_pwn=" + i_owned + " cp_pwn=" + cp_owned + " np_pwn=" + np_owned);
  4161. return !all_owned;
  4162. default:
  4163. Error("[syncinv] unsupported instance type t=" + t);
  4164. break;
  4165. }
  4166. }
  4167. return false;
  4168. }
  4169. override protected float GetWeightSpecialized(bool forceRecalc = false)
  4170. {
  4171. float totalWeight = super.GetWeightSpecialized(forceRecalc);
  4172. ItemBase itemHands = GetItemInHands();
  4173. if (itemHands) // adds weight of item carried in hands
  4174. {
  4175. totalWeight += itemHands.GetWeightEx(forceRecalc);
  4176. }
  4177. #ifdef DEVELOPER
  4178. if (WeightDebug.m_VerbosityFlags & WeightDebugType.RECALC_FORCED)
  4179. {
  4180. float itemInHandsWeight = totalWeight - super.GetWeightSpecialized(forceRecalc);
  4181. WeightDebugData dta = WeightDebug.GetWeightDebug(this);
  4182. dta.SetCalcDetails("TMan: " + (super.GetWeightSpecialized(forceRecalc)+ itemInHandsWeight) +"(contents weight[includes item in hands])");
  4183. }
  4184. #endif
  4185. return totalWeight;
  4186. }
  4187. void CalculateVisibilityForAI()
  4188. {
  4189. const int VISIBILITY_SLOTS_COUNT = 10;
  4190. int attcount = GetInventory().AttachmentCount();
  4191. float sumVisibility = 0;
  4192. float countVisibility = 0;
  4193. float visibilityMean = 0;
  4194. if (attcount > 0)
  4195. {
  4196. for (int att = 0; att < attcount; att++)
  4197. {
  4198. EntityAI attachment = GetInventory().GetAttachmentFromIndex(att);
  4199. if (attachment.IsClothing())
  4200. {
  4201. ClothingBase clothing;
  4202. Class.CastTo(clothing, attachment);
  4203. sumVisibility += clothing.GetItemVisibility();
  4204. countVisibility++;
  4205. }
  4206. }
  4207. visibilityMean = (sumVisibility + (VISIBILITY_SLOTS_COUNT - countVisibility)) / VISIBILITY_SLOTS_COUNT;
  4208. SetVisibilityCoef(visibilityMean);
  4209. }
  4210. else
  4211. {
  4212. visibilityMean = 1;
  4213. SetVisibilityCoef(visibilityMean);
  4214. }
  4215. }
  4216. void SetVisibilityCoef(float pVisibility)
  4217. {
  4218. m_VisibilityCoef = pVisibility;
  4219. }
  4220. float GetVisibilityCoef()
  4221. {
  4222. return m_VisibilityCoef;
  4223. }
  4224. int GetShakeLevel()
  4225. {
  4226. return m_Shakes;
  4227. }
  4228. EStatLevels GetStatLevelHealth()
  4229. {
  4230. float health = GetHealth("","");
  4231. return GetStatLevel(health, PlayerConstants.SL_HEALTH_CRITICAL, PlayerConstants.SL_HEALTH_LOW, PlayerConstants.SL_HEALTH_NORMAL, PlayerConstants.SL_HEALTH_HIGH);
  4232. }
  4233. EStatLevels GetStatLevelToxicity()
  4234. {
  4235. float toxicity = GetStatToxicity().Get();
  4236. return GetStatLevel(toxicity, PlayerConstants.SL_HEALTH_CRITICAL, PlayerConstants.SL_HEALTH_LOW, PlayerConstants.SL_HEALTH_NORMAL, PlayerConstants.SL_HEALTH_HIGH);
  4237. }
  4238. EStatLevels GetStatLevelBlood()
  4239. {
  4240. float blood = GetHealth("","Blood");
  4241. return GetStatLevel(blood, PlayerConstants.SL_BLOOD_CRITICAL, PlayerConstants.SL_BLOOD_LOW, PlayerConstants.SL_BLOOD_NORMAL, PlayerConstants.SL_BLOOD_HIGH);
  4242. }
  4243. EStatLevels GetStatLevelEnergy()
  4244. {
  4245. float energy = GetStatEnergy().Get();
  4246. return GetStatLevel(energy, PlayerConstants.SL_ENERGY_CRITICAL, PlayerConstants.SL_ENERGY_LOW, PlayerConstants.SL_ENERGY_NORMAL, PlayerConstants.SL_ENERGY_HIGH);
  4247. }
  4248. EStatLevels GetStatLevelWater()
  4249. {
  4250. float water = GetStatWater().Get();
  4251. return GetStatLevel(water, PlayerConstants.SL_WATER_CRITICAL, PlayerConstants.SL_WATER_LOW, PlayerConstants.SL_WATER_NORMAL, PlayerConstants.SL_WATER_HIGH);
  4252. }
  4253. EStatLevels GetImmunityLevel()
  4254. {
  4255. float immunity = GetImmunity();
  4256. if (m_ImmunityBoosted)
  4257. return EStatLevels.GREAT;
  4258. return GetStatLevel(immunity, PlayerConstants.IMMUNITY_THRESHOLD_LEVEL_CRITICAL, PlayerConstants.IMMUNITY_THRESHOLD_LEVEL_LOW, PlayerConstants.IMMUNITY_THRESHOLD_LEVEL_NORMAL, PlayerConstants.IMMUNITY_THRESHOLD_LEVEL_HIGH);
  4259. }
  4260. //-------------------------------------
  4261. float GetBordersImmunity()
  4262. {
  4263. float immunity = GetImmunity();
  4264. float immmunity_max = 1;
  4265. return GetStatLevelBorders(immunity, PlayerConstants.IMMUNITY_THRESHOLD_LEVEL_CRITICAL, PlayerConstants.IMMUNITY_THRESHOLD_LEVEL_LOW, PlayerConstants.IMMUNITY_THRESHOLD_LEVEL_NORMAL, PlayerConstants.IMMUNITY_THRESHOLD_LEVEL_HIGH, immmunity_max);
  4266. }
  4267. float GetStatBordersHealth()
  4268. {
  4269. float health = GetHealth("","");
  4270. float health_max = GetMaxHealth("","");
  4271. return GetStatLevelBorders(health, PlayerConstants.SL_HEALTH_CRITICAL, PlayerConstants.SL_HEALTH_LOW, PlayerConstants.SL_HEALTH_NORMAL, PlayerConstants.SL_HEALTH_HIGH, health_max);
  4272. }
  4273. float GetStatBordersToxicity()
  4274. {
  4275. float toxicity = GetStatToxicity().Get();
  4276. float toxicity_max = GetStatToxicity().GetMax();
  4277. return GetStatLevelBorders(toxicity, PlayerConstants.SL_HEALTH_CRITICAL, PlayerConstants.SL_HEALTH_LOW, PlayerConstants.SL_HEALTH_NORMAL, PlayerConstants.SL_HEALTH_HIGH, toxicity_max);
  4278. }
  4279. float GetStatBordersBlood()
  4280. {
  4281. float blood = GetHealth("","Blood");
  4282. float blood_max = GetMaxHealth("","Blood");
  4283. return GetStatLevelBorders(blood, PlayerConstants.SL_BLOOD_CRITICAL, PlayerConstants.SL_BLOOD_LOW, PlayerConstants.SL_BLOOD_NORMAL, PlayerConstants.SL_BLOOD_HIGH, blood_max);
  4284. }
  4285. float GetStatBordersEnergy()
  4286. {
  4287. float energy = GetStatEnergy().Get();
  4288. float energy_max = GetStatEnergy().GetMax();
  4289. return GetStatLevelBorders(energy, PlayerConstants.SL_ENERGY_CRITICAL, PlayerConstants.SL_ENERGY_LOW, PlayerConstants.SL_ENERGY_NORMAL, PlayerConstants.SL_ENERGY_HIGH, energy_max);
  4290. }
  4291. float GetStatBordersWater()
  4292. {
  4293. float water = GetStatWater().Get();
  4294. float water_max = GetStatWater().GetMax();
  4295. return GetStatLevelBorders(water, PlayerConstants.SL_WATER_CRITICAL, PlayerConstants.SL_WATER_LOW, PlayerConstants.SL_WATER_NORMAL, PlayerConstants.SL_WATER_HIGH, water_max);
  4296. }
  4297. //------------------------------------
  4298. float GetStatLevelBorders(float stat_value, float critical, float low, float normal, float high, float max)
  4299. {
  4300. if (stat_value <= critical)
  4301. {
  4302. return Math.InverseLerp(0, critical, stat_value);
  4303. }
  4304. if (stat_value <= low)
  4305. {
  4306. return Math.InverseLerp(critical, low, stat_value);
  4307. }
  4308. if (stat_value <= normal)
  4309. {
  4310. return Math.InverseLerp(low, normal, stat_value);
  4311. }
  4312. if (stat_value <= high)
  4313. {
  4314. return Math.InverseLerp(normal, high, stat_value);
  4315. }
  4316. return Math.InverseLerp(high, max, stat_value);
  4317. }
  4318. EStatLevels GetStatLevel(float stat_value, float critical, float low, float normal, float high)
  4319. {
  4320. if (stat_value <= critical)
  4321. {
  4322. return EStatLevels.CRITICAL;
  4323. }
  4324. if (stat_value <= low)
  4325. {
  4326. return EStatLevels.LOW;
  4327. }
  4328. if (stat_value <= normal)
  4329. {
  4330. return EStatLevels.MEDIUM;
  4331. }
  4332. if (stat_value <= high)
  4333. {
  4334. return EStatLevels.HIGH;
  4335. }
  4336. return EStatLevels.GREAT;
  4337. }
  4338. void SetImmunityBoosted(bool boosted)
  4339. {
  4340. m_ImmunityBoosted = boosted;
  4341. }
  4342. //!returns player's immunity strength between 0..1
  4343. float GetImmunity()
  4344. {
  4345. float immunity;
  4346. if (GetPlayerStats())
  4347. {
  4348. float max_health = GetMaxHealth("GlobalHealth", "Health") + 0.01;//addition to prevent divisioin by zero in case of some messup
  4349. float max_blood = GetMaxHealth("GlobalHealth", "Blood") + 0.01;//addition to prevent divisioin by zero in case of some messup
  4350. float energy_normalized = GetStatEnergy().Get() / PlayerConstants.SL_ENERGY_MAX;
  4351. float water_normalized = GetStatWater().Get() / PlayerConstants.SL_WATER_MAX;
  4352. float health_normalized = GetHealth("GlobalHealth", "Health") / max_health;
  4353. float blood_normalized = GetHealth("GlobalHealth", "Blood") / max_blood;
  4354. immunity = energy_normalized + water_normalized + health_normalized + blood_normalized;
  4355. immunity = immunity / 4;//avg
  4356. immunity = Math.Clamp(immunity,0,1);
  4357. }
  4358. return immunity;
  4359. }
  4360. bool IsSprinting()
  4361. {
  4362. return m_MovementState.m_iMovement == DayZPlayerConstants.MOVEMENT_SPRINT);
  4363. }
  4364. bool CanSprint()
  4365. {
  4366. ItemBase item = GetItemInHands();
  4367. if (IsRaised() || (item && item.IsHeavyBehaviour()))
  4368. return false;
  4369. if (item && GetThrowing() && GetThrowing().IsThrowingModeEnabled())
  4370. return false;
  4371. if (GetBrokenLegs() != eBrokenLegs.NO_BROKEN_LEGS)
  4372. return false;
  4373. return true;
  4374. }
  4375. bool IsInProne()
  4376. {
  4377. return m_MovementState.IsInProne();
  4378. }
  4379. bool IsInRasedProne()
  4380. {
  4381. return m_MovementState.IsInRaisedProne();
  4382. }
  4383. bool IsLeaning()
  4384. {
  4385. return m_MovementState.IsLeaning();
  4386. }
  4387. bool IsRolling()
  4388. {
  4389. return GetCommand_Move() && GetCommand_Move().IsInRoll());
  4390. }
  4391. bool IsClimbing()
  4392. {
  4393. return m_MovementState.m_CommandTypeId == DayZPlayerConstants.COMMANDID_CLIMB;
  4394. }
  4395. bool IsFalling()
  4396. {
  4397. return m_MovementState.m_CommandTypeId == DayZPlayerConstants.COMMANDID_FALL;
  4398. }
  4399. override bool IsFighting()
  4400. {
  4401. return m_IsFighting;
  4402. }
  4403. bool IsEmotePlaying()
  4404. {
  4405. return m_EmoteManager && m_EmoteManager.IsEmotePlaying();
  4406. }
  4407. override bool IsIgnoredByConstruction()
  4408. {
  4409. return IsRuined();
  4410. }
  4411. /*!
  4412. Returns whether the specified movement command(s) are starting the next frame.
  4413. Use caution when using this for anything player animation-related, some commands may require the movement state to be truly active (wait until next update)
  4414. */
  4415. bool AnimCommandCheck(HumanMoveCommandID mask)
  4416. {
  4417. return m_AnimCommandStarting & mask;
  4418. }
  4419. void RunFightBlendTimer()
  4420. {
  4421. if (!m_FightEndBlendTimer)
  4422. m_FightEndBlendTimer = new Timer();
  4423. if (!m_FightEndBlendTimer.IsRunning())
  4424. {
  4425. m_FightEndBlendTimer.Run(PlayerConstants.MELEE2_MOVEMENT_BLEND_DELAY,this,"EndFighting");
  4426. }
  4427. }
  4428. void EndFighting()
  4429. {
  4430. m_IsFighting = false;
  4431. }
  4432. bool CheckMeleeItemDamage(ItemBase item)
  4433. {
  4434. //on-hit drop of melee weapons
  4435. //bayonets & buttstocks
  4436. if (item && item.GetHierarchyParent() && item.GetHierarchyParent().IsWeapon() && item.IsRuined()/*&& item.FindAttachmentBySlotName()*/)
  4437. {
  4438. PlayAttachmentDropSound();
  4439. return DropItem(item);
  4440. }
  4441. //handheld items themselves
  4442. if (item && item == GetItemInHands() && item.IsRuined())
  4443. {
  4444. return PredictiveDropEntity(item);
  4445. }
  4446. return false;
  4447. }
  4448. void PlayAttachmentDropSound()
  4449. {
  4450. //TODO
  4451. }
  4452. // -------------------------------------------------------------------------
  4453. override void RPC(int rpc_type, array<ref Param> params, bool guaranteed, PlayerIdentity recipient = NULL)
  4454. {
  4455. super.RPC(rpc_type, params, guaranteed, recipient);
  4456. }
  4457. // -------------------------------------------------------------------------
  4458. override void OnRPC(PlayerIdentity sender, int rpc_type, ParamsReadContext ctx)
  4459. {
  4460. super.OnRPC(sender, rpc_type, ctx);
  4461. switch (rpc_type)
  4462. {
  4463. #ifndef SERVER
  4464. case ERPCs.RPC_PLAYER_STAT:
  4465. if (GetPlayerStats())
  4466. GetPlayerStats().OnRPC(ctx);
  4467. break;
  4468. case ERPCs.RPC_SYNC_DISPLAY_STATUS:
  4469. if (GetVirtualHud())
  4470. {
  4471. GetVirtualHud().OnRPC(ctx);
  4472. }
  4473. break;
  4474. case ERPCs.RPC_PLAYER_SYMPTOM_ON:
  4475. if (GetSymptomManager())
  4476. {
  4477. GetSymptomManager().OnRPC(ERPCs.RPC_PLAYER_SYMPTOM_ON, ctx);
  4478. }
  4479. break;
  4480. case ERPCs.RPC_PLAYER_SYMPTOM_OFF:
  4481. if (GetSymptomManager())
  4482. {
  4483. GetSymptomManager().OnRPC(ERPCs.RPC_PLAYER_SYMPTOM_OFF, ctx);
  4484. }
  4485. break;
  4486. case ERPCs.RPC_DAMAGE_VALUE_SYNC:
  4487. if (m_TrasferValues)
  4488. m_TrasferValues.OnRPC(ctx);
  4489. break;
  4490. case ERPCs.RPC_USER_ACTION_MESSAGE:
  4491. if (!GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  4492. {
  4493. break;
  4494. }
  4495. if (ctx.Read(m_UAParamMessage))
  4496. {
  4497. string actiontext = m_UAParamMessage.param1;
  4498. MessageAction(actiontext);
  4499. }
  4500. break;
  4501. case ERPCs.RPC_SOFT_SKILLS_SPECIALTY_SYNC:
  4502. ref Param1<float> p_synch = new Param1<float>(0);
  4503. ctx.Read(p_synch);
  4504. float specialty_level = p_synch.param1;
  4505. GetSoftSkillsManager().SetSpecialtyLevel(specialty_level);
  4506. break;
  4507. case ERPCs.RPC_SOFT_SKILLS_STATS_SYNC:
  4508. ref Param5<float, float, float, float, bool> p_debug_synch = new Param5<float, float ,float, float, bool>(0, 0, 0, 0, false);
  4509. ctx.Read(p_debug_synch);
  4510. float general_bonus_before = p_debug_synch.param1;
  4511. float general_bonus_after = p_debug_synch.param2;
  4512. float last_UA_value = p_debug_synch.param3;
  4513. float cooldown_value = p_debug_synch.param4;
  4514. float cooldown_active = p_debug_synch.param5;
  4515. GetSoftSkillsManager().SetGeneralBonusBefore(general_bonus_before);
  4516. GetSoftSkillsManager().SetGeneralBonusAfter(general_bonus_after);
  4517. GetSoftSkillsManager().SetLastUAValue(last_UA_value);
  4518. GetSoftSkillsManager().SetCoolDownValue(cooldown_value);
  4519. GetSoftSkillsManager().SetCoolDown(cooldown_active);
  4520. break;
  4521. case ERPCs.RPC_WARNING_ITEMDROP:
  4522. {
  4523. if (GetGame().IsClient() && GetGame().GetUIManager() && !GetGame().GetUIManager().FindMenu(MENU_WARNING_ITEMDROP))
  4524. {
  4525. GetGame().GetCallQueue(CALL_CATEGORY_GAMEPLAY).Call(GetGame().GetUIManager().EnterScriptedMenu,MENU_WARNING_ITEMDROP,null);
  4526. GetGame().GetMission().AddActiveInputExcludes({"menu"});
  4527. }
  4528. break;
  4529. }
  4530. case ERPCs.RPC_WARNING_TELEPORT:
  4531. {
  4532. if (GetGame().IsClient() && GetGame().GetUIManager() && !GetGame().GetUIManager().FindMenu(MENU_WARNING_TELEPORT))
  4533. {
  4534. GetGame().GetCallQueue(CALL_CATEGORY_GAMEPLAY).Call(GetGame().GetUIManager().EnterScriptedMenu,MENU_WARNING_TELEPORT,null);
  4535. GetGame().GetMission().AddActiveInputExcludes({"menu"});
  4536. }
  4537. break;
  4538. }
  4539. case ERPCs.RPC_INIT_SET_QUICKBAR:
  4540. ref Param1<int> count = new Param1<int>(0);
  4541. if (ctx.Read(count));
  4542. {
  4543. for (int i = 0; i < count.param1 ; i++)
  4544. {
  4545. m_QuickBarBase.OnSetEntityRPC(ctx);
  4546. }
  4547. }
  4548. break;
  4549. case ERPCs.RPC_SYNC_THERMOMETER:
  4550. {
  4551. float value;
  4552. if (ctx.Read(value))
  4553. m_Hud.SetTemperature(value.ToString() + "#degrees_celsius");
  4554. break;
  4555. }
  4556. case ERPCs.RPC_CHECK_PULSE:
  4557. ctx.Read(CachedObjectsParams.PARAM1_INT);
  4558. EPulseType pulse;
  4559. if ((CachedObjectsParams.PARAM1_INT.param1 & ActionCheckPulse.TARGET_IRREGULAR_PULSE_BIT) == 0)
  4560. {
  4561. pulse = EPulseType.REGULAR;
  4562. }
  4563. else
  4564. {
  4565. pulse = EPulseType.IRREGULAR;
  4566. }
  4567. int blood_level = ~ActionCheckPulse.TARGET_IRREGULAR_PULSE_BIT & CachedObjectsParams.PARAM1_INT.param1;
  4568. if (m_CheckPulseLastTarget)
  4569. {
  4570. m_CheckPulseLastTarget.SetLastUAMessage(ActionCheckPulse.GetPulseMessage(pulse, blood_level));
  4571. }
  4572. break;
  4573. //! uses contants outside of ERPCs !!!!
  4574. //woodcutting
  4575. case PlantType.TREE_HARD:
  4576. SoundHardTreeFallingPlay();
  4577. break;
  4578. case PlantType.TREE_SOFT:
  4579. SoundSoftTreeFallingPlay();
  4580. break;
  4581. case PlantType.BUSH_HARD:
  4582. SoundHardBushFallingPlay();
  4583. break;
  4584. case PlantType.BUSH_SOFT:
  4585. SoundSoftBushFallingPlay();
  4586. break;
  4587. case ERPCs.RPC_DEBUG_MONITOR_FLT:
  4588. if (m_DebugMonitorValues)
  4589. {
  4590. m_DebugMonitorValues.OnRPCFloat(ctx);
  4591. }
  4592. break;
  4593. case ERPCs.RPC_DEBUG_MONITOR_STR:
  4594. if (m_DebugMonitorValues)
  4595. {
  4596. m_DebugMonitorValues.OnRPCString(ctx);
  4597. }
  4598. break;
  4599. #endif
  4600. /*
  4601. case ERPCs.RPC_CRAFTING_INVENTORY_INSTANT:
  4602. ref Param3<int, ItemBase, ItemBase> craftParam = new Param3<int, ItemBase, ItemBase>(-1, NULL, NULL);
  4603. if (ctx.Read(craftParam))
  4604. {
  4605. m_ModuleRecipesManager.PerformRecipeServer(craftParam.param1, craftParam.param2, craftParam.param3, this);
  4606. }
  4607. break;
  4608. */
  4609. #ifdef DIAG_DEVELOPER
  4610. case ERPCs.DEV_RPC_AGENT_RESET:
  4611. {
  4612. bool val;
  4613. if (ctx.Read(val))
  4614. m_AgentPool.RemoveAllAgents();
  4615. break;
  4616. }
  4617. case ERPCs.DEV_PLAYER_DEBUG_REQUEST:
  4618. {
  4619. PluginRemotePlayerDebugServer plugin_remote_server = PluginRemotePlayerDebugServer.Cast(GetPlugin(PluginRemotePlayerDebugServer));
  4620. plugin_remote_server.OnRPC(ctx, this);
  4621. break;
  4622. }
  4623. case ERPCs.DEV_PLAYER_DEBUG_DATA:
  4624. {
  4625. PluginRemotePlayerDebugClient plugin_remote_client = PluginRemotePlayerDebugClient.Cast(GetPlugin(PluginRemotePlayerDebugClient));
  4626. PluginDeveloper plugin_dev = PluginDeveloper.Cast(GetPlugin(PluginDeveloper));
  4627. if (plugin_dev.m_ScriptConsole)
  4628. plugin_dev.m_ScriptConsole.OnRPCEx(rpc_type, ctx);
  4629. else
  4630. plugin_remote_client.OnRPC(ctx);
  4631. break;
  4632. }
  4633. case ERPCs.DEV_AGENT_GROW:
  4634. {
  4635. m_AgentPool.RemoteGrowRequestDebug(ctx);
  4636. break;
  4637. }
  4638. case ERPCs.RPC_ITEM_DIAG_CLOSE:
  4639. {
  4640. PluginItemDiagnostic mid = PluginItemDiagnostic.Cast(GetPlugin(PluginItemDiagnostic));
  4641. mid.StopWatchRequest(this);
  4642. break;
  4643. }
  4644. //! Universal Temperature Sources debug
  4645. case ERPCs.DEV_REQUEST_UTS_DEBUG:
  4646. {
  4647. PluginUniversalTemperatureSourceServer plugin_uts_server = PluginUniversalTemperatureSourceServer.Cast(GetPlugin(PluginUniversalTemperatureSourceServer));
  4648. plugin_uts_server.OnRPC(ctx, this);
  4649. break;
  4650. }
  4651. case ERPCs.DEV_UTS_DEBUG_DATA:
  4652. {
  4653. PluginUniversalTemperatureSourceClient plugin_uts_client = PluginUniversalTemperatureSourceClient.Cast(GetPlugin(PluginUniversalTemperatureSourceClient));
  4654. plugin_uts_client.OnRPC(ctx);
  4655. break;
  4656. }
  4657. //! ---
  4658. #endif
  4659. #ifdef DEVELOPER
  4660. case ERPCs.DEV_RPC_SERVER_SCRIPT:
  4661. {
  4662. //PluginItemDiagnostic plugin = PluginItemDiagnostic.Cast(GetPlugin(PluginItemDiagnostic));
  4663. //SetDebugDeveloper_item(plugin.GetWatchedItem(this));//!! needs to be inside DEVELOPER ifdef
  4664. if (ctx.Read(CachedObjectsParams.PARAM1_STRING))
  4665. {
  4666. _player = this;
  4667. string code = CachedObjectsParams.PARAM1_STRING.param1;
  4668. bool success = GetGame().ExecuteEnforceScript("void scConsMain() \n{\n" + code + "\n}\n", "scConsMain");
  4669. CachedObjectsParams.PARAM1_BOOL.param1 = success;
  4670. RPCSingleParam(ERPCs.DEV_RPC_SERVER_SCRIPT_RESULT, CachedObjectsParams.PARAM1_BOOL,true, GetIdentity());
  4671. }
  4672. break;
  4673. }
  4674. case ERPCs.DEV_RPC_SERVER_SCRIPT_RESULT:
  4675. {
  4676. PluginDeveloper dev = PluginDeveloper.Cast(GetPlugin(PluginDeveloper));
  4677. if (dev.m_ScriptConsole)
  4678. dev.m_ScriptConsole.OnRPCEx(rpc_type, ctx);
  4679. break;
  4680. }
  4681. case ERPCs.DEV_SET_DEV_ITEM:
  4682. {
  4683. Param1<EntityAI> ent = new Param1<EntityAI>(null);
  4684. if (ctx.Read(ent) && ent.param1)
  4685. {
  4686. PluginItemDiagnostic mid2 = PluginItemDiagnostic.Cast(GetPlugin(PluginItemDiagnostic));
  4687. mid2.RegisterDebugItem(ent.param1, this);
  4688. }
  4689. //SetDebugDeveloper_item(this);
  4690. break;
  4691. }
  4692. case ERPCs.RPC_ITEM_DIAG:
  4693. {
  4694. Param1<EntityAI> p1 = new Param1<EntityAI>(null);
  4695. if (ctx.Read(p1))
  4696. {
  4697. PluginItemDiagnostic plgn = PluginItemDiagnostic.Cast(GetPlugin(PluginItemDiagnostic));
  4698. plgn.OnRPC(p1.param1, ctx);
  4699. }
  4700. break;
  4701. }
  4702. #endif
  4703. }
  4704. #ifdef DIAG_DEVELOPER
  4705. PluginDeveloper module_rc = PluginDeveloper.Cast(GetPlugin(PluginDeveloper));
  4706. if (module_rc)
  4707. module_rc.OnRPC(this, rpc_type, ctx);
  4708. PluginDeveloperSync module_rcs = PluginDeveloperSync.Cast(GetPlugin(PluginDeveloperSync));
  4709. if (module_rcs)
  4710. module_rcs.OnRPC(this, rpc_type, ctx);
  4711. #ifdef SERVER
  4712. PluginDiagMenu plugin_diag_menu = PluginDiagMenu.Cast(GetPlugin(PluginDiagMenuServer));
  4713. #else
  4714. PluginDiagMenu plugin_diag_menu = PluginDiagMenu.Cast(GetPlugin(PluginDiagMenuClient));
  4715. #endif
  4716. if (plugin_diag_menu)
  4717. plugin_diag_menu.OnRPC(this, rpc_type, ctx);
  4718. #endif
  4719. }
  4720. override void OnGameplayDataHandlerSync()
  4721. {
  4722. super.OnGameplayDataHandlerSync();
  4723. UpdateLighting();
  4724. GetGame().GetMission().SetRespawnModeClient(CfgGameplayHandler.GetDisableRespawnDialog());
  4725. SetHitPPEEnabled(CfgGameplayHandler.GetHitIndicationPPEEnabled());
  4726. }
  4727. void UpdateLighting()
  4728. {
  4729. Mission mission = GetGame().GetMission();
  4730. if (mission)
  4731. {
  4732. WorldLighting wLighting = mission.GetWorldLighting();
  4733. if (wLighting)
  4734. wLighting.SetGlobalLighting(CfgGameplayHandler.GetLightingConfig());
  4735. }
  4736. }
  4737. void SetContaminatedEffectEx(bool enable, int ppeIdx = -1, int aroundId = ParticleList.CONTAMINATED_AREA_GAS_AROUND, int tinyId = ParticleList.CONTAMINATED_AREA_GAS_TINY, string soundset = "", bool partDynaUpdate = false, int newBirthRate = 0)
  4738. {
  4739. if (enable) // enable
  4740. {
  4741. // We assume that if this is set to true the PPE is already active
  4742. if (m_ContaminatedAreaEffectEnabled == enable)
  4743. return;
  4744. if (aroundId !=0)
  4745. {
  4746. if (!m_ContaminatedAroundPlayer)
  4747. {
  4748. m_ContaminatedAroundPlayer = ParticleManager.GetInstance().PlayInWorld(aroundId, GetPosition());
  4749. }
  4750. // First entry in an area with dynamic tweaks to particles
  4751. if (partDynaUpdate)
  4752. {
  4753. m_ContaminatedAroundPlayer.SetParameter(0, EmitorParam.BIRTH_RATE, newBirthRate);
  4754. }
  4755. }
  4756. if (!m_ContaminatedAroundPlayerTiny && tinyId !=0)
  4757. {
  4758. m_ContaminatedAroundPlayerTiny = ParticleManager.GetInstance().PlayInWorld(tinyId, GetPosition());
  4759. }
  4760. if (ppeIdx != -1)
  4761. {
  4762. PPERequesterBase ppeRequester;
  4763. if (Class.CastTo(ppeRequester, PPERequesterBank.GetRequester(ppeIdx)))
  4764. ppeRequester.Start();
  4765. }
  4766. // We start playing the ambient sound
  4767. if (!m_AmbientContamination && soundset != "")
  4768. PlaySoundSetLoop(m_AmbientContamination, soundset, 0.1, 0.1);
  4769. }
  4770. else // disable
  4771. {
  4772. if (m_ContaminatedAroundPlayer)
  4773. {
  4774. m_ContaminatedAroundPlayer.Stop();
  4775. m_ContaminatedAroundPlayer = null;
  4776. }
  4777. if (m_ContaminatedAroundPlayerTiny)
  4778. {
  4779. m_ContaminatedAroundPlayerTiny.Stop();
  4780. m_ContaminatedAroundPlayerTiny = null;
  4781. }
  4782. if (ppeIdx != -1)
  4783. PPERequesterBank.GetRequester(ppeIdx).Stop(new Param1<bool>(true)); //fade out
  4784. // We stop the ambient sound
  4785. if (m_AmbientContamination)
  4786. StopSoundSet(m_AmbientContamination);
  4787. // We make sure to reset the state
  4788. }
  4789. m_ContaminatedAreaEffectEnabled = enable;
  4790. }
  4791. void SetContaminatedEffect(bool enable, int ppeIdx = -1, int aroundId = ParticleList.CONTAMINATED_AREA_GAS_AROUND, int tinyId = ParticleList.CONTAMINATED_AREA_GAS_TINY, bool partDynaUpdate = false, int newBirthRate = 0)
  4792. {
  4793. SetContaminatedEffectEx(enable, ppeIdx, aroundId, tinyId, "", partDynaUpdate, newBirthRate);
  4794. }
  4795. // -------------------------------------------------------------------------
  4796. void UpdateCorpseState()
  4797. {
  4798. UpdateCorpseStateVisual();
  4799. if (m_CorpseState > 0 && !GetIsFrozen())
  4800. SetDecayEffects(Math.AbsInt(m_CorpseState));
  4801. else
  4802. SetDecayEffects();//no params means remove the effects
  4803. m_CorpseStateLocal = m_CorpseState;
  4804. }
  4805. // -------------------------------------------------------------------------
  4806. override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
  4807. {
  4808. super.EEHealthLevelChanged(oldLevel, newLevel, zone);
  4809. if (!GetGame().IsDedicatedServer())
  4810. {
  4811. if (newLevel == GameConstants.STATE_RUINED)
  4812. {
  4813. ClearLastUAMessage();
  4814. }
  4815. if (m_CorpseState != 0)
  4816. {
  4817. GetGame().GetCallQueue(CALL_CATEGORY_GUI).CallLater(UpdateCorpseState, 0, false);
  4818. }
  4819. }
  4820. }
  4821. // -------------------------------------------------------------------------
  4822. override void OnVariablesSynchronized()
  4823. {
  4824. super.OnVariablesSynchronized();
  4825. if (m_ModuleLifespan)
  4826. {
  4827. m_ModuleLifespan.SynchLifespanVisual(this, m_LifeSpanState, m_HasBloodyHandsVisible, m_HasBloodTypeVisible, m_BloodType);
  4828. if (m_LifespanLevelLocal != m_LifeSpanState) //client solution, lifespan level changed
  4829. {
  4830. m_LifespanLevelLocal = m_LifeSpanState;
  4831. UpdateHairSelectionVisibility();
  4832. }
  4833. }
  4834. CheckSoundEvent();
  4835. if (GetBleedingManagerRemote() && IsPlayerLoaded())
  4836. {
  4837. GetBleedingManagerRemote().OnVariablesSynchronized(GetBleedingBits());
  4838. }
  4839. if (m_CorpseStateLocal != m_CorpseState && (IsPlayerLoaded() || IsControlledPlayer()))
  4840. {
  4841. UpdateCorpseState();
  4842. }
  4843. if (m_RefreshAnimStateIdx != m_LocalRefreshAnimStateIdx)
  4844. {
  4845. RefreshHandAnimationState(396); //mean animation blend time
  4846. m_LocalRefreshAnimStateIdx = m_RefreshAnimStateIdx;
  4847. }
  4848. if (m_InsideEffectArea != m_InsideEffectAreaPrev)
  4849. {
  4850. if (m_InsideEffectArea)
  4851. {
  4852. OnPlayerIsNowInsideEffectAreaBeginClient();
  4853. }
  4854. else
  4855. {
  4856. OnPlayerIsNowInsideEffectAreaEndClient();
  4857. }
  4858. m_InsideEffectAreaPrev = m_InsideEffectArea;
  4859. }
  4860. //-------MODIFIERS START--------
  4861. if (m_SyncedModifiers != m_SyncedModifiersPrev)
  4862. {
  4863. int diff = (m_SyncedModifiers & ~m_SyncedModifiersPrev) | (~m_SyncedModifiers & m_SyncedModifiersPrev);//XOR gets us a mask for modifiers that changed by either deactivating, or activating
  4864. if (eModifierSyncIDs.MODIFIER_SYNC_DROWNING & diff)//has this modifier's status as active/inactive changed ?
  4865. {
  4866. if (eModifierSyncIDs.MODIFIER_SYNC_DROWNING & m_SyncedModifiers)//is this modifier currently active ? if so, it means it's been just activated
  4867. {
  4868. SetDrowning(true);
  4869. }
  4870. else
  4871. {
  4872. SetDrowning(false);
  4873. }
  4874. }
  4875. m_SyncedModifiersPrev = m_SyncedModifiers;
  4876. }
  4877. //-------MODIFIERS END--------
  4878. HandleBrokenLegsSync();
  4879. //! Remotely Activated Item Behaviour refresh on item is in hands
  4880. ItemBase itemHands = GetItemInHands();
  4881. if (itemHands)
  4882. {
  4883. RemotelyActivatedItemBehaviour raib = itemHands.GetRemotelyActivatedItemBehaviour();
  4884. if (raib)
  4885. raib.OnVariableSynchronized();
  4886. }
  4887. //restrain events
  4888. if (m_IsRestrainedLocal != m_IsRestrained)
  4889. {
  4890. m_IsRestrainedLocal = m_IsRestrained;
  4891. OnRestrainChangeClient();
  4892. }
  4893. if (m_IsRestrainStartedLocal != m_IsRestrainStarted)
  4894. {
  4895. m_IsRestrainStartedLocal = m_IsRestrainStarted;
  4896. OnRestrainStartedChangeClient();
  4897. }
  4898. }
  4899. //! Checks whether modifier (which has syncing enabled) is currently active, works on both Client and Server
  4900. bool IsSyncedModifierActive(eModifierSyncIDs modifier)
  4901. {
  4902. return (m_SyncedModifiers & m_SyncedModifiersPrev);
  4903. }
  4904. void HandleBrokenLegsSync()
  4905. {
  4906. if (m_BrokenLegState != m_LocalBrokenState)
  4907. {
  4908. m_LocalBrokenState = m_BrokenLegState;
  4909. if (GetBrokenLegs() == eBrokenLegs.BROKEN_LEGS)
  4910. {
  4911. if (m_BrokenLegState < 0)
  4912. BreakLegSound();
  4913. }
  4914. }
  4915. }
  4916. void FixAllInventoryItems()
  4917. {
  4918. array<EntityAI> items = new array<EntityAI>();
  4919. GetInventory().EnumerateInventory(InventoryTraversalType.INORDER, items);
  4920. foreach (EntityAI item : items)
  4921. {
  4922. item.SetHealthMax("", "");
  4923. item.SetWet(item.GetWetInit());
  4924. item.SetTemperatureDirect(GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE);
  4925. item.SetFrozen(false);
  4926. }
  4927. }
  4928. void OnInventoryMenuOpen();
  4929. void OnInventoryMenuClose();
  4930. //--------------------------------------------------------------------------
  4931. void OnSelectPlayer()
  4932. {
  4933. //Print("PlayerBase | OnSelectPlayer()");
  4934. m_PlayerSelected = true;
  4935. m_QuickBarBase.updateSlotsCount();
  4936. m_WeaponManager.SortMagazineAfterLoad();
  4937. PlayerIdentity identity = GetIdentity();
  4938. #ifdef FEATURE_NETWORK_RECONCILIATION
  4939. if (identity)
  4940. {
  4941. //! TODO(kumarjac): vhc: Check if it causes further issues with SelectPlayer while a player is leaving freecam
  4942. identity.Possess(this);
  4943. }
  4944. #endif
  4945. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER || !GetGame().IsMultiplayer())
  4946. {
  4947. if (identity)
  4948. {
  4949. m_CachedPlayerID = identity.GetId();
  4950. m_CachedPlayerName = identity.GetName();
  4951. }
  4952. //! add callbacks for ai target system
  4953. SetAITargetCallbacks(new AITargetCallbacksPlayer(this));
  4954. array<ref Param> params = new array<ref Param>;
  4955. if (m_aQuickBarLoad)
  4956. {
  4957. int count = m_aQuickBarLoad.Count();
  4958. Param1<int> paramCount = new Param1<int>(count);
  4959. params.Insert(paramCount);
  4960. for (int i = 0; i < count; i++)
  4961. {
  4962. m_QuickBarBase.OnSetEntityNoSync(m_aQuickBarLoad.Get(i).param1,m_aQuickBarLoad.Get(i).param2);
  4963. params.Insert(m_aQuickBarLoad.Get(i));
  4964. }
  4965. if (count > 0 && GetGame().IsMultiplayer())
  4966. {
  4967. GetGame().RPC(this, ERPCs.RPC_INIT_SET_QUICKBAR, params, true, identity);
  4968. }
  4969. m_aQuickBarLoad = NULL;
  4970. }
  4971. GetSoftSkillsManager().InitSpecialty(GetStatSpecialty().Get());
  4972. GetModifiersManager().SetModifiers(true);
  4973. SetSynchDirty();
  4974. if (GetGame().IsMultiplayer())
  4975. {
  4976. //Drop item warning
  4977. if (m_ProcessUIWarning)
  4978. {
  4979. GetGame().RPCSingleParam(this, ERPCs.RPC_WARNING_ITEMDROP, null, true, identity);
  4980. m_ProcessUIWarning = false;
  4981. }
  4982. GetGame().GetMission().SyncRespawnModeInfo(identity);
  4983. }
  4984. }
  4985. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  4986. {
  4987. m_ActionManager = new ActionManagerServer(this);
  4988. m_ConstructionActionData = new ConstructionActionData();
  4989. CheckForGag();
  4990. }
  4991. else if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  4992. {
  4993. m_ActionManager = new ActionManagerClient(this);
  4994. m_CraftingManager = new CraftingManager(this,m_ModuleRecipesManager);
  4995. m_ConstructionActionData = new ConstructionActionData();
  4996. }
  4997. else if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_AI_SINGLEPLAYER)
  4998. {
  4999. m_ActionManager = new ActionManagerServer(this);
  5000. }
  5001. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  5002. {
  5003. if (GetGame().GetMission())
  5004. {
  5005. GetGame().GetMission().ResetGUI();
  5006. // force update player
  5007. GetDayZGame().GetBacklit().UpdatePlayer(true);
  5008. }
  5009. m_DeathCheckTimer = new Timer();
  5010. m_DeathCheckTimer.Run(0.1, this, "CheckDeath", null, true);
  5011. PPEManagerStatic.GetPPEManager().StopAllEffects(PPERequesterCategory.ALL);
  5012. CheckForBurlap();
  5013. int characterCount = GetGame().GetMenuData().GetCharactersCount() - 1;
  5014. int idx = GetGame().GetMenuData().GetLastPlayedCharacter();
  5015. if (idx == GameConstants.DEFAULT_CHARACTER_MENU_ID || idx > characterCount)
  5016. {
  5017. GetGame().GetCallQueue(CALL_CATEGORY_GUI).Call(SetNewCharName);
  5018. }
  5019. GetGame().GetMission().EnableAllInputs(true);
  5020. m_PresenceNotifier = PluginPresenceNotifier.Cast(GetPlugin(PluginPresenceNotifier));
  5021. m_PresenceNotifier.Init(this);
  5022. #ifdef DIAG_DEVELOPER
  5023. m_TargetTemperatureDiag = PluginTargetTemperature.Cast(GetPlugin(PluginTargetTemperature));
  5024. m_TargetTemperatureDiag.Init(this);
  5025. #endif
  5026. OnGameplayDataHandlerSync();//only here for legacy reasons
  5027. }
  5028. #ifdef BOT
  5029. m_Bot = new Bot(this);
  5030. m_Bot.Start(true, new MyBotTrigger(this));
  5031. #endif
  5032. }
  5033. override void SimulateDeath(bool state)
  5034. {
  5035. super.SimulateDeath(state);
  5036. m_UndergroundHandler = null;
  5037. m_UndergroundBunkerHandler = null;
  5038. if (m_EffectWidgets)
  5039. {
  5040. m_EffectWidgets.StopAllEffects();
  5041. m_EffectWidgets.ClearSuspendRequests();
  5042. }
  5043. }
  5044. void SetNewCharName()
  5045. {
  5046. g_Game.GetMenuData().SaveCharacter(false, true);
  5047. g_Game.GetMenuData().SetCharacterName(g_Game.GetMenuData().GetLastPlayedCharacter(), g_Game.GetMenuDefaultCharacterData(false).GetCharacterName());
  5048. g_Game.GetMenuData().SaveCharactersLocal();
  5049. }
  5050. void CheckForBurlap()
  5051. {
  5052. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  5053. {
  5054. BurlapSackCover attachment;
  5055. Class.CastTo(attachment, GetInventory().FindAttachment(InventorySlots.HEADGEAR));
  5056. PPERequester_BurlapSackEffects req;
  5057. if (Class.CastTo(req,PPERequesterBank.GetRequester(PPERequesterBank.REQ_BURLAPSACK)))
  5058. {
  5059. if (attachment)
  5060. {
  5061. req.Start();
  5062. }
  5063. else if (req.IsRequesterRunning())
  5064. {
  5065. PPERequesterBank.GetRequester(PPERequester_BurlapSackEffects).Stop();
  5066. }
  5067. }
  5068. }
  5069. }
  5070. void CheckForGag()
  5071. {
  5072. #ifdef SERVER
  5073. Clothing item;
  5074. Class.CastTo(item, GetInventory().FindAttachment(InventorySlots.MASK));
  5075. if (!item)
  5076. {
  5077. Class.CastTo(item, GetInventory().FindAttachment(InventorySlots.HEADGEAR));
  5078. }
  5079. if (item && item.IsObstructingVoice())
  5080. {
  5081. item.MutePlayer(this,true);
  5082. }
  5083. else //should probably check for relevant types before removing mumbling and obstruction specifically..
  5084. {
  5085. GetGame().SetVoiceEffect(this, VoiceEffectMumbling, false);
  5086. GetGame().SetVoiceEffect(this, VoiceEffectObstruction, false);
  5087. }
  5088. #endif
  5089. }
  5090. void UpdateMaskBreathWidget(notnull MaskBase mask, bool is_start = false)
  5091. {
  5092. if (is_start)
  5093. m_EffectWidgets.ResetMaskUpdateCount();
  5094. float resistance = 0;
  5095. if (mask.HasIntegratedFilter() || mask.IsExternalFilterAttached())
  5096. resistance = 1 - mask.GetFilterQuantity01();
  5097. m_EffectWidgets.OnVoiceEvent(resistance);
  5098. m_EffectWidgets.IncreaseMaskUpdateCount();
  5099. }
  5100. // -------------------------------------------------------------------------
  5101. void OnVoiceEvent(PlayerSoundEventBase voice_event)
  5102. {
  5103. if (m_EffectWidgets)
  5104. {
  5105. MaskBase mask = MaskBase.Cast(GetInventory().FindAttachment(InventorySlots.MASK));
  5106. if (mask)
  5107. {
  5108. UpdateMaskBreathWidget(mask, true);
  5109. //m_EffectWidgets.SetBreathIntensityStamina(GetStaminaHandler().GetStaminaCap(),GetStaminaHandler().GetStamina());
  5110. }
  5111. }
  5112. }
  5113. // -------------------------------------------------------------------------
  5114. //! called every cmd handler tick during a playback of PlayerSoundEvent, m_ProcessPlaybackEvent needs to be enabled on the PlayerSoundEvent
  5115. void OnVoiceEventPlayback(PlayerSoundEventBase voice_event, AbstractWave callback, float playback_time)
  5116. {
  5117. if (m_EffectWidgets)
  5118. {
  5119. MaskBase mask = MaskBase.Cast(GetInventory().FindAttachment(InventorySlots.MASK));
  5120. if (mask)
  5121. {
  5122. if (m_EffectWidgets.m_MaskWidgetUpdateCount < 2 && callback.GetLength() > 2 && playback_time > 0.5 )
  5123. UpdateMaskBreathWidget(mask);
  5124. }
  5125. }
  5126. }
  5127. // -------------------------------------------------------------------------
  5128. override bool OnInputUserDataProcess(int userDataType, ParamsReadContext ctx)
  5129. {
  5130. if (super.OnInputUserDataProcess(userDataType, ctx))
  5131. return true;
  5132. if (m_QuickBarBase.OnInputUserDataProcess(userDataType, ctx))
  5133. return true;
  5134. if (m_WeaponManager.OnInputUserDataProcess(userDataType, ctx))
  5135. return true;
  5136. if (HandleRemoteItemManipulation(userDataType, ctx))
  5137. return true;
  5138. if (userDataType == INPUT_UDT_INVENTORY && GetHumanInventory().OnInputUserDataProcess(ctx))
  5139. return true;
  5140. if (TogglePlacingServer(userDataType, ctx))
  5141. return true;
  5142. if (ResetADSPlayerSync(userDataType, ctx))
  5143. return true;
  5144. string uid;
  5145. bool mute;
  5146. if (userDataType == INPUT_UDT_USER_MUTE_XBOX)
  5147. {
  5148. if (ctx.Read(uid) && ctx.Read(mute))
  5149. {
  5150. GetGame().MutePlayer(uid, GetIdentity().GetPlainId(), mute);
  5151. // commented because plainID should not be present in logs
  5152. //Print("Player: " + GetIdentity().GetId() + " set mute for " + uid + " to " + mute);
  5153. }
  5154. }
  5155. if (m_EmoteManager && userDataType == INPUT_UDT_GESTURE)
  5156. return m_EmoteManager.OnInputUserDataProcess(userDataType, ctx);
  5157. if (userDataType == INPUT_UDT_WEAPON_LIFT_EVENT)
  5158. return ReadLiftWeaponRequest(userDataType, ctx);
  5159. if (m_ActionManager)
  5160. return m_ActionManager.OnInputUserDataProcess(userDataType, ctx);
  5161. return false;
  5162. }
  5163. float GetHealthRegenSpeed()
  5164. {
  5165. float blood = GetHealth("GlobalHealth", "Blood");
  5166. float blood_scale_normalized = Math.InverseLerp(PlayerConstants.BLOOD_THRESHOLD_FATAL, GetMaxHealth("", "Blood"), blood);
  5167. blood_scale_normalized = Math.Clamp(blood_scale_normalized,0,1);
  5168. return Math.Lerp(PlayerConstants.HEALTH_REGEN_MIN, PlayerConstants.HEALTH_REGEN_MAX, blood_scale_normalized);
  5169. }
  5170. bool HandleRemoteItemManipulation(int userDataType, ParamsReadContext ctx)
  5171. {
  5172. if (userDataType == INPUT_UDT_ITEM_MANIPULATION)
  5173. {
  5174. int type = -1;
  5175. ItemBase item1 = null;
  5176. ItemBase item2 = null;
  5177. bool use_stack_max = false;
  5178. int slot_id = -1;
  5179. if (!ctx.Read(type))
  5180. return false;
  5181. if (type == 4)
  5182. {
  5183. if (!ctx.Read(item1))
  5184. return false;
  5185. InventoryLocation dst = new InventoryLocation;
  5186. if (dst.ReadFromContext(ctx))
  5187. {
  5188. //Print(InventoryLocation.DumpToStringNullSafe(dst));
  5189. bool dummy;
  5190. if (ctx.Read(dummy))
  5191. item1.SplitItemToInventoryLocation(dst);
  5192. else
  5193. item1.SplitIntoStackMaxToInventoryLocation(dst);
  5194. return true;
  5195. }
  5196. return false;
  5197. }
  5198. if (!ctx.Read(item1))
  5199. return false;
  5200. if (!ctx.Read(item2))
  5201. return false;
  5202. if (!ctx.Read(use_stack_max))
  5203. return false;
  5204. if (!ctx.Read(slot_id))
  5205. return false;
  5206. if (type == -1 && item1 && item2)//combine
  5207. {
  5208. item1.CombineItems(item2, use_stack_max);
  5209. }
  5210. else if (type == 1 && item1)
  5211. {
  5212. if (use_stack_max)
  5213. item1.SplitIntoStackMax(item2, slot_id, this);
  5214. else
  5215. item1.SplitItem(this);
  5216. }
  5217. else if (type == 2 && item1)
  5218. {
  5219. int row, col;
  5220. if (!ctx.Read(row))
  5221. return false;
  5222. if (!ctx.Read(col))
  5223. return false;
  5224. item1.SplitIntoStackMaxCargo(item2, slot_id, row, col);
  5225. }
  5226. else if (type == 3 && item1)
  5227. {
  5228. item1.SplitIntoStackMaxHands(this);
  5229. }
  5230. return true;
  5231. }
  5232. return false;
  5233. }
  5234. // -------------------------------------------------------------------------
  5235. ItemBase GetItemInHands()
  5236. {
  5237. if (GetHumanInventory())
  5238. {
  5239. return ItemBase.Cast(GetHumanInventory().GetEntityInHands());
  5240. }
  5241. return null;
  5242. }
  5243. //--------------------------------------------------------------------------
  5244. override EntityAI SpawnEntityOnGroundPos(string object_name, vector pos)
  5245. {
  5246. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER || !GetGame().IsMultiplayer())
  5247. {
  5248. bool is_AI = GetGame().IsKindOf(object_name, "DZ_LightAI");
  5249. if (is_AI)
  5250. {
  5251. return SpawnAI(object_name, pos);
  5252. }
  5253. else
  5254. {
  5255. InventoryLocation inv_loc = new InventoryLocation;
  5256. vector mtx[4];
  5257. Math3D.MatrixIdentity4(mtx);
  5258. mtx[3] = pos;
  5259. inv_loc.SetGround(null, mtx);
  5260. int flags = ECE_PLACE_ON_SURFACE;
  5261. #ifdef DEVELOPER
  5262. if (g_Game.IsKindOf(object_name, "Boat"))
  5263. flags = ECE_KEEPHEIGHT;
  5264. #endif
  5265. return EntityAI.Cast(GetGame().CreateObjectEx(object_name, inv_loc.GetPos(), flags));
  5266. }
  5267. }
  5268. return null;
  5269. }
  5270. EntityAI SpawnEntityOnGroundOnCursorDir(string object_name, float distance)
  5271. {
  5272. vector position = GetPosition() + (GetDirection() * distance);
  5273. return SpawnEntityOnGroundPos(object_name, position);
  5274. }
  5275. EntityAI SpawnAI(string object_name, vector pos)
  5276. {
  5277. bool is_ai = GetGame().IsKindOf(object_name, "DZ_LightAI");
  5278. if (is_ai)
  5279. {
  5280. return EntityAI.Cast(GetGame().CreateObjectEx(object_name, pos, ECE_PLACE_ON_SURFACE|ECE_INITAI|ECE_EQUIP_ATTACHMENTS));
  5281. }
  5282. return NULL;
  5283. }
  5284. //--------------------------------------------------------------------------
  5285. bool DropItem(ItemBase item)
  5286. {
  5287. bool can_be_dropped = CanDropEntity(item);
  5288. if (can_be_dropped)
  5289. {
  5290. can_be_dropped = PredictiveDropEntity(item);
  5291. }
  5292. vector pos_spawn = GetPosition() + GetDirection();
  5293. pos_spawn[0] = pos_spawn[0] + Math.RandomFloat(-0.2, 0.2);
  5294. pos_spawn[2] = pos_spawn[2] + Math.RandomFloat(-0.2, 0.2);
  5295. item.SetPosition(pos_spawn);
  5296. item.PlaceOnSurface();
  5297. return can_be_dropped;
  5298. }
  5299. // -------------------------------------------------------------------------
  5300. /**
  5301. /brief Creates \p ItemBase in players inventory. If player dont have enough slots for new item, item will be created on the ground under player.
  5302. \param item_name \p string Class name of ItemBase in configs
  5303. \returns \p ItemBase Created item
  5304. @code
  5305. ItemBase item = g_Game.GetPlayer().CreateInInventory("Consumable_GardenLime", "cargo_weapon");
  5306. @endcode
  5307. */
  5308. EntityAI CreateInInventory(string item_name, string cargo_type = "", bool full_quantity = false)
  5309. {
  5310. InventoryLocation inv_loc = new InventoryLocation;
  5311. if (GetInventory().FindFirstFreeLocationForNewEntity(item_name, FindInventoryLocationType.ANY, inv_loc))
  5312. {
  5313. return SpawnItemOnLocation(item_name, inv_loc, full_quantity);
  5314. }
  5315. return NULL;
  5316. }
  5317. ItemBase CreateCopyOfItemInInventory (ItemBase src)
  5318. {
  5319. InventoryLocation loc = new InventoryLocation;
  5320. string t = src.GetType();
  5321. if (GetInventory().FindFirstFreeLocationForNewEntity(t, FindInventoryLocationType.CARGO, loc))
  5322. {
  5323. bool locked = GetGame().HasInventoryJunctureDestination(this, loc);
  5324. if (locked)
  5325. {
  5326. Print("Warning: Split: CreateCopyOfItemInInventory - Cannot create entity at locked inventory at loc=" + InventoryLocation.DumpToStringNullSafe(loc));
  5327. return null;
  5328. }
  5329. ItemBase dst = ItemBase.Cast(GetInventory().LocationCreateLocalEntity(loc, t, ECE_IN_INVENTORY, RF_DEFAULT));
  5330. if (dst)
  5331. {
  5332. MiscGameplayFunctions.TransferItemProperties(src, dst);
  5333. GetGame().RemoteObjectTreeCreate(dst);
  5334. Print("CreateCopyOfItemInInventory - created " + dst.GetName() + " at loc=" + InventoryLocation.DumpToStringNullSafe(loc));
  5335. }
  5336. return dst;
  5337. }
  5338. return NULL;
  5339. }
  5340. ItemBase CreateCopyOfItemInInventoryOrGround(ItemBase src)
  5341. {
  5342. return CreateCopyOfItemInInventoryOrGroundEx(src, false);
  5343. }
  5344. ItemBase CreateCopyOfItemInInventoryOrGroundEx(ItemBase src, bool markItemAsSplitResult = false)
  5345. {
  5346. ItemBase dst = CreateCopyOfItemInInventory(src);
  5347. if (!dst)
  5348. {
  5349. dst = ItemBase.Cast(SpawnEntityOnGroundPos(src.GetType(), this.GetPosition()));
  5350. dst.PlaceOnSurface();
  5351. dst.SetResultOfSplit(markItemAsSplitResult);
  5352. MiscGameplayFunctions.TransferItemProperties(src, dst);
  5353. }
  5354. return dst;
  5355. }
  5356. // -------------------------------------------------------------------------
  5357. /**
  5358. colorStatusChannel
  5359. colorAction
  5360. colorFriendly
  5361. colorImportant
  5362. */
  5363. void Message(string text, string style)
  5364. {
  5365. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  5366. {
  5367. GetGame().ChatMP(this, text, style);
  5368. }
  5369. else
  5370. {
  5371. GetGame().Chat(text, style);
  5372. }
  5373. }
  5374. // -------------------------------------------------------------------------
  5375. void MessageStatus(string text)
  5376. {
  5377. Message(text, "colorStatusChannel");
  5378. }
  5379. // -------------------------------------------------------------------------
  5380. void MessageAction(string text)
  5381. {
  5382. Message(text, "colorAction");
  5383. }
  5384. // -------------------------------------------------------------------------
  5385. void MessageFriendly(string text)
  5386. {
  5387. Message(text, "colorFriendly");
  5388. }
  5389. // -------------------------------------------------------------------------
  5390. void MessageImportant(string text)
  5391. {
  5392. Message(text, "colorImportant");
  5393. }
  5394. void CloseInventoryMenu()
  5395. {
  5396. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  5397. {
  5398. #ifndef NO_GUI
  5399. UIScriptedMenu menu = GetGame().GetUIManager().GetMenu();
  5400. if (menu && (menu.GetID() == MENU_INVENTORY || menu.GetID() == MENU_INSPECT))
  5401. {
  5402. GetGame().GetUIManager().CloseAll();
  5403. GetGame().GetMission().RemoveActiveInputExcludes({"inventory"},false);
  5404. GetGame().GetMission().RemoveActiveInputRestriction(EInputRestrictors.INVENTORY);
  5405. }
  5406. #endif
  5407. }
  5408. }
  5409. // -------------------------------------------------------------------------
  5410. /**
  5411. /brief Delete all items in inventory
  5412. \returns \p void
  5413. @code
  5414. PlayerBase player = GetGame().GetPlayer();
  5415. player.ClearInventory();
  5416. @endcode
  5417. */
  5418. override void ClearInventory()
  5419. {
  5420. if ((GetGame().IsServer() || !GetGame().IsMultiplayer()) && GetInventory())
  5421. {
  5422. GameInventory inv = PlayerBase.Cast(this).GetInventory();
  5423. array<EntityAI> items = new array<EntityAI>;
  5424. inv.EnumerateInventory(InventoryTraversalType.INORDER, items);
  5425. for (int i = 0; i < items.Count(); i++)
  5426. {
  5427. ItemBase item = ItemBase.Cast(items.Get(i));
  5428. if (item)
  5429. {
  5430. GetGame().ObjectDelete(item);
  5431. }
  5432. }
  5433. ItemBase item_in_hands = ItemBase.Cast(GetHumanInventory().GetEntityInHands());
  5434. if (item_in_hands)
  5435. {
  5436. LocalDestroyEntityInHands();
  5437. }
  5438. }
  5439. }
  5440. //! Drops all clothes/wearables this character is carrying on themselves.
  5441. void DropAllItems()
  5442. {
  5443. array<EntityAI> itemsArray = new array<EntityAI>;
  5444. ItemBase item;
  5445. GetInventory().EnumerateInventory(InventoryTraversalType.LEVELORDER, itemsArray);
  5446. int count = itemsArray.Count();
  5447. for (int i = 0; i < itemsArray.Count(); i++)
  5448. {
  5449. Class.CastTo(item, itemsArray.Get(i));
  5450. if (item && !item.IsInherited(SurvivorBase))
  5451. {
  5452. ServerDropEntity(item);
  5453. }
  5454. }
  5455. }
  5456. string GetPlayerClass()
  5457. {
  5458. string type;
  5459. GetGame().ObjectGetType(this, type);
  5460. return type;
  5461. }
  5462. // --------------------------------------------------
  5463. // Lifespan
  5464. //---------------------------------------------------
  5465. void ShavePlayer()
  5466. {
  5467. SetLastShavedSeconds(StatGet(AnalyticsManagerServer.STAT_PLAYTIME));
  5468. m_ModuleLifespan.UpdateLifespan(this, true);
  5469. }
  5470. bool CanShave()
  5471. {
  5472. if (!HasCoveredFaceForShave() && GetLifeSpanState())
  5473. {
  5474. return true;
  5475. }
  5476. else
  5477. {
  5478. return false;
  5479. }
  5480. }
  5481. override void OnParticleEvent(string pEventType, string pUserString, int pUserInt)
  5482. {
  5483. super.OnParticleEvent(pEventType ,pUserString, pUserInt);
  5484. if (!GetGame().IsDedicatedServer())
  5485. {
  5486. if (pUserInt == 123456) // 123456 is ID for vomiting effect. The current implementation is WIP.
  5487. {
  5488. PlayerBase player = PlayerBase.Cast(this);
  5489. int boneIdx = player.GetBoneIndexByName("Head");
  5490. if (boneIdx != -1)
  5491. {
  5492. EffectParticle eff;
  5493. if (m_SyncedModifiers & eModifierSyncIDs.MODIFIER_SYNC_CONTAMINATION2)
  5494. {
  5495. eff = new EffVomitBlood();
  5496. }
  5497. else
  5498. {
  5499. eff = new EffVomit();
  5500. }
  5501. eff.SetDecalOwner(player);
  5502. eff.SetAutodestroy(true);
  5503. SEffectManager.PlayInWorld(eff, vector.Zero);
  5504. Particle p = eff.GetParticle();
  5505. player.AddChild(p, boneIdx);
  5506. }
  5507. }
  5508. }
  5509. }
  5510. bool CanSpawnBreathVaporEffect()
  5511. {
  5512. if (!ToDelete() && IsAlive() && !IsSwimming() && !m_IsDrowning)
  5513. {
  5514. return true;
  5515. }
  5516. return false;
  5517. }
  5518. void ProcessADDModifier()
  5519. {
  5520. if (m_AddModifier != -1)
  5521. {
  5522. HumanCommandAdditives ad = GetCommandModifier_Additives();
  5523. if (ad)
  5524. ad.StartModifier(m_AddModifier);
  5525. m_AddModifier = -1;
  5526. }
  5527. }
  5528. void SpawnBreathVaporEffect()
  5529. {
  5530. //Print("SpawnBreathVaporEffect:"+GetGame().GetTime());
  5531. int boneIdx = GetBoneIndexByName("Head");
  5532. if (boneIdx != -1)
  5533. {
  5534. Particle p;
  5535. switch (m_BreathVapour)
  5536. {
  5537. case 1:
  5538. p = ParticleManager.GetInstance().PlayInWorld(ParticleList.BREATH_VAPOUR_LIGHT, "-0.03 0.15 0");
  5539. break;
  5540. case 2:
  5541. p = ParticleManager.GetInstance().PlayInWorld(ParticleList.BREATH_VAPOUR_MEDIUM, "-0.03 0.15 0");
  5542. break;
  5543. case 3:
  5544. p = ParticleManager.GetInstance().PlayInWorld(ParticleList.BREATH_VAPOUR_HEAVY, "-0.03 0.15 0");
  5545. break;
  5546. default:
  5547. break;
  5548. }
  5549. if (p)
  5550. AddChild(p, boneIdx);
  5551. }
  5552. }
  5553. // returns 'true' if the player is submerged under water deep enough so that we consider him/her to be eligible for drowning, do note some other conditions may apply for actual drowning to be turned on
  5554. bool GetDrowningWaterLevelCheck()
  5555. {
  5556. int index = GetBoneIndexByName("head");
  5557. vector pos = GetBonePositionWS(index);
  5558. float depth = g_Game.GetWaterDepth(pos);
  5559. if (IsSwimming())
  5560. {
  5561. return depth > PlayerConstants.DROWNING_SWIMMING_THRESHOLD;
  5562. }
  5563. else if (IsUnconscious())
  5564. {
  5565. return depth > PlayerConstants.DROWNING_UNCONSCIOUS_THRESHOLD;
  5566. }
  5567. return depth > PlayerConstants.DROWNING_DEFAULT_THRESHOLD;
  5568. }
  5569. void SetLifeSpanStateVisible(int show_state)
  5570. {
  5571. bool state_changed;
  5572. if (show_state != m_LifeSpanState)
  5573. state_changed = true;
  5574. m_LifeSpanState = show_state;
  5575. SetSynchDirty();
  5576. if (state_changed) //server only, client solution in OnVariablesSynchronized()
  5577. {
  5578. //SendLifespanSyncEvent(m_LifeSpanState);
  5579. UpdateHairSelectionVisibility();
  5580. }
  5581. }
  5582. int GetLifeSpanState()
  5583. {
  5584. return m_LifeSpanState;
  5585. }
  5586. int GetLastShavedSeconds()
  5587. {
  5588. return m_LastShavedSeconds;
  5589. }
  5590. void SetLastShavedSeconds(int last_shaved_seconds)
  5591. {
  5592. m_LastShavedSeconds = last_shaved_seconds;
  5593. }
  5594. bool HasCoveredFaceForShave()
  5595. {
  5596. return IsExclusionFlagPresent(GetFaceCoverageShaveValues());
  5597. }
  5598. //! returns a set of face covering values
  5599. static set<int> GetFaceCoverageShaveValues()
  5600. {
  5601. set<int> ret = new set<int>;
  5602. ret.Insert(EAttExclusions.SHAVING_MASK_ATT_0);
  5603. ret.Insert(EAttExclusions.SHAVING_HEADGEAR_ATT_0);
  5604. //ret.Insert(EAttExclusions.SHAVING_EYEWEAR_ATT_0);
  5605. return ret;
  5606. }
  5607. eBloodyHandsTypes HasBloodyHandsEx()
  5608. {
  5609. return m_HasBloodyHandsVisible;
  5610. }
  5611. bool HasBloodyHands()
  5612. {
  5613. return m_HasBloodyHandsVisible;
  5614. }
  5615. void SetBloodyHands(bool show)
  5616. {
  5617. SetBloodyHandsBase(show);
  5618. }
  5619. void SetBloodyHandsEx(eBloodyHandsTypes type)
  5620. {
  5621. SetBloodyHandsBase(type);
  5622. }
  5623. private void SetBloodyHandsBase(int type)
  5624. {
  5625. m_HasBloodyHandsVisible = type;
  5626. SetSynchDirty();
  5627. #ifdef DIAG_DEVELOPER
  5628. #ifndef SERVER
  5629. if (IsControlledPlayer())
  5630. {
  5631. bool enable = type;
  5632. DiagMenu.SetValue(DiagMenuIDs.LIFESPAN_BLOODY_HANDS, enable);
  5633. }
  5634. #endif
  5635. #endif
  5636. }
  5637. void SetBloodyHandsPenalty()
  5638. {
  5639. InsertAgent(eAgents.SALMONELLA, 1);
  5640. }
  5641. bool HasBloodTypeVisible()
  5642. {
  5643. return m_HasBloodTypeVisible;
  5644. }
  5645. void SetBloodTypeVisible(bool show)
  5646. {
  5647. m_HasBloodTypeVisible = show;
  5648. SetSynchDirty();
  5649. }
  5650. int GetBloodType()
  5651. {
  5652. return m_BloodType;
  5653. }
  5654. void SetBloodType(int blood_type)
  5655. {
  5656. m_BloodType = blood_type;
  5657. SetSynchDirty();
  5658. }
  5659. // --------------------------------------------------
  5660. // Soft Skills
  5661. //---------------------------------------------------
  5662. SoftSkillsManager GetSoftSkillsManager()
  5663. {
  5664. return m_SoftSkillsManager;
  5665. }
  5666. void CheckDeath()
  5667. {
  5668. if (IsPlayerSelected() && !IsAlive())
  5669. {
  5670. SimulateDeath(true);
  5671. m_DeathCheckTimer.Stop();
  5672. }
  5673. }
  5674. // -------------------------------------------------------------------------
  5675. // --------------------------------------------------
  5676. // AI Presence
  5677. //---------------------------------------------------
  5678. //! Return actual noise presence of player
  5679. int GetNoisePresenceInAI()
  5680. {
  5681. if (m_PresenceNotifier)
  5682. {
  5683. return m_PresenceNotifier.GetNoisePresence();
  5684. }
  5685. return 0;
  5686. }
  5687. // is a bit on in the persistent flags
  5688. bool IsPersistentFlag(PersistentFlag bit)
  5689. {
  5690. return (m_PersistentFlags & bit);
  5691. }
  5692. // turn on/off a bit in the persistent flag
  5693. void SetPersistentFlag(PersistentFlag bit, bool enable)
  5694. {
  5695. if (enable)//turn on bit
  5696. m_PersistentFlags = (m_PersistentFlags | bit);
  5697. else//turn off bit
  5698. m_PersistentFlags = ((~bit) & m_PersistentFlags);
  5699. }
  5700. // -------------------------------------------------------------------------
  5701. int GetStoreLoadVersion()
  5702. {
  5703. return m_StoreLoadVersion;
  5704. }
  5705. override void OnStoreSave(ParamsWriteContext ctx)
  5706. {
  5707. //Print("OnStoreSave");
  5708. if (GetGame().SaveVersion() < 102)
  5709. {
  5710. ctx.Write(ACT_STORE_SAVE_VERSION);//to be removed after we push 102+
  5711. }
  5712. super.OnStoreSave(ctx);
  5713. GetHumanInventory().OnStoreSave(ctx); // FSM of hands
  5714. OnStoreSaveLifespan(ctx);
  5715. if (GetDayZGame().IsServer() && GetDayZGame().IsMultiplayer())
  5716. {
  5717. GetPlayerStats().SaveStats(ctx);// save stats
  5718. m_ModifiersManager.OnStoreSave(ctx);// save modifiers
  5719. m_AgentPool.OnStoreSave(ctx);//save agents
  5720. GetSymptomManager().OnStoreSave(ctx);//save states
  5721. if (GetBleedingManagerServer())
  5722. {
  5723. GetBleedingManagerServer().OnStoreSave(ctx);//save bleeding sources
  5724. }
  5725. m_PlayerStomach.OnStoreSave(ctx);
  5726. ctx.Write(GetBrokenLegs());
  5727. //ctx.Write(m_LocalBrokenState);
  5728. SaveAreaPersistenceFlag(ctx);
  5729. HumanCommandLadder ladder = GetCommand_Ladder();
  5730. if (ladder)
  5731. {
  5732. ctx.Write(true);
  5733. ctx.Write(ladder.GetLogoutPosition());
  5734. }
  5735. else
  5736. {
  5737. ctx.Write(false);
  5738. }
  5739. ArrowManagerPlayer arrowManager = ArrowManagerPlayer.Cast(GetArrowManager());
  5740. arrowManager.Save(ctx);
  5741. }
  5742. }
  5743. void SaveAreaPersistenceFlag(ParamsWriteContext ctx)
  5744. {
  5745. if (GetModifiersManager())
  5746. SetPersistentFlag(PersistentFlag.AREA_PRESENCE, GetModifiersManager().IsModifierActive(eModifiers.MDF_AREAEXPOSURE));//set the flag for player's presence in contaminated area
  5747. ctx.Write(m_PersistentFlags);
  5748. }
  5749. override bool OnStoreLoad(ParamsReadContext ctx, int version)
  5750. {
  5751. //Print("---- PlayerBase OnStoreLoad START ----, version: "+version);
  5752. m_aQuickBarLoad = new array<ref Param2<EntityAI,int>>;
  5753. // todo :: this should be after base call !!!!
  5754. if (version < 102)//write removed in v. 102
  5755. {
  5756. if (!ctx.Read(m_StoreLoadVersion))
  5757. return false;
  5758. }
  5759. if (!super.OnStoreLoad(ctx, version))
  5760. return false;
  5761. // FSM of hands
  5762. if (!GetHumanInventory().OnStoreLoad(ctx, version))
  5763. return false;
  5764. if (!OnStoreLoadLifespan(ctx, version))
  5765. return false;
  5766. if (GetDayZGame().IsServer() && GetDayZGame().IsMultiplayer())
  5767. {
  5768. if (!GetPlayerStats().LoadStats(ctx, version)) // load stats
  5769. {
  5770. Print("---- failed to load PlayerStats ----");
  5771. return false;
  5772. }
  5773. if (version < m_ModifiersManager.GetStorageVersion())//load modifiers !! WILL CANCEL REST OF STREAM IF UNSUPPORTED VERSION !!
  5774. {
  5775. Print("---- failed to load ModifiersManager, unsupported version ----");
  5776. return false;
  5777. }
  5778. else
  5779. {
  5780. if (!m_ModifiersManager.OnStoreLoad(ctx, version))
  5781. {
  5782. Print("---- failed to load ModifiersManager, read fail ----");
  5783. return false;
  5784. }
  5785. }
  5786. if (version < m_AgentPool.GetStorageVersion())//load agents !! WILL CANCEL REST OF STREAM IF UNSUPPORTED VERSION !!
  5787. {
  5788. Print("---- failed to load AgentPool, unsupported version ----");
  5789. return false;
  5790. }
  5791. else
  5792. {
  5793. if (!m_AgentPool.OnStoreLoad(ctx, version))
  5794. {
  5795. Print("---- failed to load AgentPool, read fail ----");
  5796. return false;
  5797. }
  5798. }
  5799. if (version < GetSymptomManager().GetStorageVersion())//load symptoms !! WILL CANCEL REST OF STREAM IF UNSUPPORTED VERSION !!
  5800. {
  5801. Print("---- failed to load SymptomManager, unsupported version ----");
  5802. return false;
  5803. }
  5804. else
  5805. {
  5806. if (!GetSymptomManager().OnStoreLoad(ctx, version))
  5807. {
  5808. Print("---- failed to load SymptomManager, read fail ----");
  5809. return false;
  5810. }
  5811. }
  5812. if (version < GetBleedingManagerServer().GetStorageVersion())//load bleeding manager !! WILL CANCEL REST OF STREAM IF UNSUPPORTED VERSION !!
  5813. {
  5814. Print("---- failed to load BleedingManagerServer, unsupported version ----");
  5815. return false;
  5816. }
  5817. else
  5818. {
  5819. if (!GetBleedingManagerServer().OnStoreLoad(ctx, version))
  5820. {
  5821. Print("---- failed to load BleedingManagerServer, read fail ----");
  5822. return false;
  5823. }
  5824. }
  5825. if (version < m_PlayerStomach.GetStorageVersion())//load PlayerStomach !! WILL CANCEL REST OF STREAM IF UNSUPPORTED VERSION !!
  5826. {
  5827. Print("---- failed to load PlayerStomach, unsupported version ----");
  5828. return false;
  5829. }
  5830. else
  5831. {
  5832. if (!m_PlayerStomach.OnStoreLoad(ctx, version))
  5833. {
  5834. Print("---- failed to load PlayerStomach, read fail ----");
  5835. return false;
  5836. }
  5837. }
  5838. //Check for broken leg value
  5839. if (version >= 116)
  5840. {
  5841. if (!ctx.Read(m_BrokenLegState))
  5842. {
  5843. return false;
  5844. }
  5845. if (version <= 126)// WHILE >= 116
  5846. {
  5847. if (!ctx.Read(m_LocalBrokenState))
  5848. {
  5849. return false;
  5850. }
  5851. }
  5852. }
  5853. //Load persistent flags value
  5854. if (version >= 125 && (!ctx.Read(m_PersistentFlags)))
  5855. {
  5856. Print("---- failed to load Persistent Flags, read fail ----");
  5857. return false;
  5858. }
  5859. if (version >= 131)
  5860. {
  5861. bool onLadder;
  5862. if (!ctx.Read(onLadder))
  5863. {
  5864. return false;
  5865. }
  5866. if (onLadder)
  5867. {
  5868. vector position;
  5869. if (!ctx.Read(position))
  5870. {
  5871. return false;
  5872. }
  5873. Hive hive = GetHive();
  5874. if (!hive || !hive.CharacterIsLoginPositionChanged(this))
  5875. {
  5876. SetPosition(position);
  5877. }
  5878. }
  5879. }
  5880. if (version >= 134)
  5881. {
  5882. ArrowManagerPlayer arrowManager = ArrowManagerPlayer.Cast(GetArrowManager());
  5883. arrowManager.Load(ctx);
  5884. }
  5885. }
  5886. Print("---- PlayerBase OnStoreLoad SUCCESS ----");
  5887. return true;
  5888. }
  5889. override void AfterStoreLoad()
  5890. {
  5891. GetHumanInventory().OnAfterStoreLoad();
  5892. if (m_EmoteManager)
  5893. m_EmoteManager.AfterStoreLoad();
  5894. if (GetPlayerStats())
  5895. GetPlayerStats().OnAfterStoreLoad();
  5896. PlayerRestrictedAreaInstance pra;
  5897. vector currentPos = GetPosition();
  5898. if (g_Game.GetGameState() != DayZGameState.MAIN_MENU && CfgPlayerRestrictedAreaHandler.IsInitialized() && CfgPlayerRestrictedAreaHandler.IsPointInPlayerRestrictedArea(currentPos,pra))
  5899. {
  5900. //vector safePos = pra.GetClosestSafePos3D(currentPos);
  5901. vector safePos = pra.GetRandomSafePos3D(currentPos);
  5902. if (MiscGameplayFunctions.TeleportPlayerToSafeLocation3D(this,safePos) && m_AdminLog)
  5903. m_AdminLog.PlayerTeleportedLog(this,currentPos,safePos,"Spawning in Player Restricted Area: " + pra.areaName);
  5904. }
  5905. }
  5906. void OnStoreSaveLifespan(ParamsWriteContext ctx)
  5907. {
  5908. ctx.Write(m_LifeSpanState);
  5909. ctx.Write(m_LastShavedSeconds);
  5910. ctx.Write(m_HasBloodyHandsVisible);
  5911. ctx.Write(m_HasBloodTypeVisible);
  5912. ctx.Write(m_BloodType);
  5913. }
  5914. bool OnStoreLoadLifespan(ParamsReadContext ctx, int version)
  5915. {
  5916. int lifespan_state = 0;
  5917. if (!ctx.Read(lifespan_state))
  5918. return false;
  5919. m_LifeSpanState = lifespan_state;
  5920. int last_shaved = 0;
  5921. if (!ctx.Read(last_shaved))
  5922. return false;
  5923. m_LastShavedSeconds = last_shaved;
  5924. if (version < 122)
  5925. {
  5926. bool bloody_hands_old;
  5927. if (!ctx.Read(bloody_hands_old))
  5928. return false;
  5929. m_HasBloodyHandsVisible = bloody_hands_old;
  5930. }
  5931. else
  5932. {
  5933. int bloody_hands = 0;
  5934. if (!ctx.Read(bloody_hands))
  5935. return false;
  5936. m_HasBloodyHandsVisible = bloody_hands;
  5937. }
  5938. bool blood_visible = false;
  5939. if (!ctx.Read(blood_visible))
  5940. return false;
  5941. m_HasBloodTypeVisible = blood_visible;
  5942. int blood_type = 0;
  5943. if (!ctx.Read(blood_type))
  5944. return false;
  5945. m_BloodType = blood_type;
  5946. return true;
  5947. }
  5948. vector m_PlayerOldPos;
  5949. void UpdatePlayerMeasures()
  5950. {
  5951. int hour, minute, second;
  5952. GetHourMinuteSecond(hour, minute, second);
  5953. float distance;
  5954. distance = StatGet(AnalyticsManagerServer.STAT_DISTANCE);
  5955. if (m_AnalyticsTimer)
  5956. {
  5957. StatsEventMeasuresData data = new StatsEventMeasuresData();
  5958. data.m_CharacterId = g_Game.GetDatabaseID();
  5959. data.m_TimeInterval = m_AnalyticsTimer.GetRemaining();
  5960. data.m_DaytimeHour = hour;
  5961. data.m_PositionStart = m_PlayerOldPos;
  5962. data.m_PositionEnd = GetPosition();
  5963. data.m_DistanceOnFoot = distance;
  5964. Analytics.PlayerMeasures(data);
  5965. }
  5966. m_PlayerOldPos = GetPosition();
  5967. }
  5968. void OnConnect()
  5969. {
  5970. Debug.Log("Player connected:"+this.ToString(),"Connect");
  5971. // analytics
  5972. GetGame().GetAnalyticsServer().OnPlayerConnect(this);
  5973. m_PlayerOldPos = GetPosition();
  5974. if (m_AnalyticsTimer)
  5975. m_AnalyticsTimer.Run(60, this, "UpdatePlayerMeasures", null, true);
  5976. //construction action data
  5977. ResetConstructionActionData();
  5978. }
  5979. void OnReconnect()
  5980. {
  5981. Debug.Log("Player reconnected:"+this.ToString(),"Reconnect");
  5982. //construction action data
  5983. ResetConstructionActionData();
  5984. }
  5985. void OnDisconnect()
  5986. {
  5987. Debug.Log("Player disconnected:"+this.ToString(),"Connect");
  5988. // analytics
  5989. // force update of the stats
  5990. // if player disconnect too soon, UpdatePlayersStats() is not called
  5991. GetGame().GetAnalyticsServer().OnPlayerDisconnect(this);
  5992. StatsEventDisconnectedData data = new StatsEventDisconnectedData();
  5993. data.m_CharacterId = g_Game.GetDatabaseID();
  5994. data.m_Reason = "Disconnected";
  5995. Analytics.PlayerDisconnected(data);
  5996. if (m_AnalyticsTimer)
  5997. m_AnalyticsTimer.Stop();
  5998. UpdatePlayerMeasures();
  5999. SetPlayerDisconnected(true);
  6000. }
  6001. void SetModifiers(bool enable)
  6002. {
  6003. GetModifiersManager().SetModifiers(enable);
  6004. }
  6005. bool Consume(ItemBase source, float amount, EConsumeType consume_type)
  6006. {
  6007. PluginTransmissionAgents plugin = PluginTransmissionAgents.Cast(GetPlugin(PluginTransmissionAgents));
  6008. int agents;
  6009. int pollution = GetGame().GetMission().GetWorldData().GetPollution();
  6010. float temperature = 0;
  6011. if (consume_type == EConsumeType.ENVIRO_POND || consume_type == EConsumeType.ENVIRO_WELL)
  6012. {
  6013. if (consume_type == EConsumeType.ENVIRO_POND)
  6014. {
  6015. if (pollution & EPollution.HEAVYMETAL)
  6016. {
  6017. agents = agents | eAgents.HEAVYMETAL;
  6018. }
  6019. agents = agents | eAgents.CHOLERA;
  6020. //plugin.TransmitAgents(NULL, this, AGT_WATER_POND, amount);
  6021. }
  6022. temperature = GetGame().GetMission().GetWorldData().GetLiquidTypeEnviroTemperature(consume_type);
  6023. m_PlayerStomach.AddToStomach(Liquid.GetLiquidClassname(LIQUID_WATER), amount, 0 , agents, temperature);
  6024. return true;
  6025. }
  6026. if (consume_type == EConsumeType.ENVIRO_SNOW)
  6027. {
  6028. if (pollution & EPollution.HEAVYMETAL)
  6029. {
  6030. agents = agents | eAgents.HEAVYMETAL;
  6031. }
  6032. temperature = GetGame().GetMission().GetWorldData().GetLiquidTypeEnviroTemperature(consume_type);
  6033. m_PlayerStomach.AddToStomach(Liquid.GetLiquidClassname(LIQUID_WATER), amount, 0 , agents, temperature);
  6034. }
  6035. Edible_Base edible_item = Edible_Base.Cast(source);
  6036. if (!edible_item || edible_item.GetIsFrozen())
  6037. {
  6038. return false;
  6039. }
  6040. agents = edible_item.FilterAgents(edible_item.GetAgents());
  6041. temperature = edible_item.GetTemperature();
  6042. if (consume_type == EConsumeType.ITEM_SINGLE_TIME || consume_type == EConsumeType.ITEM_CONTINUOUS)
  6043. {
  6044. if (consume_type == EConsumeType.ITEM_SINGLE_TIME)
  6045. {
  6046. plugin.TransmitAgents(edible_item, this, AGT_UACTION_CONSUME, amount);
  6047. }
  6048. /*
  6049. else
  6050. {
  6051. plugin.TransmitAgents(edible_item, this, AGT_UACTION_TO_PLAYER, amount);
  6052. }
  6053. */
  6054. if (edible_item.IsLiquidContainer())
  6055. {
  6056. int liquid_type = edible_item.GetLiquidType();
  6057. string liquidClassName = Liquid.GetLiquidClassname(liquid_type);
  6058. if (liquidClassName.Length() == 0)
  6059. Error("Error! Trying to add unknown liquid to stomach with item=" + Object.GetDebugName(edible_item) + " consume_type=" + consume_type + " liquid_type=" + liquid_type);
  6060. m_PlayerStomach.AddToStomach(liquidClassName, amount, 0, agents, temperature);
  6061. }
  6062. else
  6063. {
  6064. int food_stage_type;
  6065. if (edible_item.GetFoodStage())
  6066. {
  6067. food_stage_type = edible_item.GetFoodStage().GetFoodStageType();
  6068. }
  6069. m_PlayerStomach.AddToStomach(source.GetType(), amount, food_stage_type, agents, temperature);
  6070. }
  6071. edible_item.Consume(amount, this);
  6072. return true;
  6073. }
  6074. /*
  6075. if (consume_type == EConsumeType.ITEM_CONTINUOUS)
  6076. {
  6077. if (edible_item)
  6078. {
  6079. plugin.TransmitAgents(edible_item, this, AGT_UACTION_TO_PLAYER, amount);
  6080. edible_item.Consume(amount, this);
  6081. //ProcessNutritions(edible_item.GetNutritionalProfile(),amount);
  6082. m_PlayerStomach.AddToStomach(source.GetType(), amount, edible_item.GetNutritionalProfile());
  6083. return true;
  6084. }
  6085. }
  6086. */
  6087. return false;
  6088. }
  6089. void ShowUnconsciousScreen(bool show)
  6090. {
  6091. #ifndef NO_GUI
  6092. if (show)
  6093. {
  6094. GetGame().GetUIManager().ScreenFadeIn(0, "You are Unconscious", FadeColors.BLACK, FadeColors.WHITE);
  6095. PrintString("Fade in");
  6096. }
  6097. else
  6098. {
  6099. GetGame().GetUIManager().ScreenFadeOut(0);
  6100. PrintString("Fade out");
  6101. }
  6102. #endif
  6103. }
  6104. override void RequestSoundEventEx(EPlayerSoundEventID id, bool from_server_and_client = false, int param = 0)
  6105. {
  6106. if (from_server_and_client && GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  6107. {
  6108. PlaySoundEventEx(id, false, false, param);
  6109. return;
  6110. }
  6111. SendSoundEventEx(id, param);
  6112. }
  6113. override void RequestSoundEvent(EPlayerSoundEventID id, bool from_server_and_client = false)
  6114. {
  6115. RequestSoundEventEx(id, from_server_and_client);
  6116. }
  6117. override protected void SendSoundEvent(EPlayerSoundEventID id)
  6118. {
  6119. SendSoundEventEx(id);
  6120. }
  6121. override protected void SendSoundEventEx(EPlayerSoundEventID id, int param = 0)
  6122. {
  6123. if (!GetGame().IsServer())
  6124. {
  6125. return;
  6126. }
  6127. m_SoundEvent = id;
  6128. m_SoundEventParam = param;
  6129. SetSynchDirty();
  6130. if (!GetGame().IsMultiplayer())
  6131. {
  6132. CheckSoundEvent();
  6133. }
  6134. //PrintString(GetGame().GetTime().ToString() + " Set SoundEvent, id:" + id.ToString());
  6135. }
  6136. void CheckZeroSoundEvent()
  6137. {
  6138. if (m_SoundEvent != 0 && m_SoundEventSent)
  6139. {
  6140. m_SoundEvent = 0;
  6141. m_SoundEventParam = 0;
  6142. m_SoundEventSent = false;
  6143. SetSynchDirty();
  6144. }
  6145. }
  6146. void CheckSendSoundEvent()
  6147. {
  6148. if (m_SoundEvent!= 0 && !m_SoundEventSent)
  6149. {
  6150. m_SoundEventSent = true;
  6151. }
  6152. }
  6153. override bool PlaySoundEventType(ESoundEventType soundType, int soundEventID, int param = 0)
  6154. {
  6155. if (m_ReplaceSoundEventHandler)
  6156. return m_ReplaceSoundEventHandler.PlayReplaceSound(soundEventID, soundType, param);
  6157. return false;
  6158. }
  6159. override bool PlaySoundEvent(EPlayerSoundEventID id, bool from_anim_system = false, bool is_from_server = false)
  6160. {
  6161. return PlaySoundEventEx(id, from_anim_system, is_from_server);
  6162. }
  6163. override bool PlaySoundEventEx(EPlayerSoundEventID id, bool from_anim_system = false, bool is_from_server = false, int param = 0)
  6164. {
  6165. if (!m_PlayerSoundEventHandler)
  6166. return false;
  6167. return m_PlayerSoundEventHandler.PlayRequestEx(id, is_from_server, param);
  6168. }
  6169. PlayerSoundEventHandler GetPlayerSoundEventHandler()
  6170. {
  6171. return m_PlayerSoundEventHandler;
  6172. }
  6173. void OnBleedingBegin();
  6174. void OnBleedingEnd();
  6175. void OnBleedingSourceAdded()
  6176. {
  6177. m_BleedingSourceCount++;
  6178. if (IsControlledPlayer())
  6179. {
  6180. if (!GetGame().IsDedicatedServer())
  6181. {
  6182. DisplayElementBadge dis_elm = DisplayElementBadge.Cast(GetVirtualHud().GetElement(eDisplayElements.DELM_BADGE_BLEEDING));
  6183. if (dis_elm)
  6184. {
  6185. dis_elm.SetValue(GetBleedingSourceCount());
  6186. }
  6187. //Print("----------bleeding_SoundSet----------");
  6188. SEffectManager.PlaySoundOnObject("bleeding_SoundSet", this);
  6189. }
  6190. }
  6191. }
  6192. void OnBleedingSourceRemoved()
  6193. {
  6194. m_BleedingSourceCount--;
  6195. if (GetGame().IsServer())
  6196. {
  6197. ArrowManagerBase arrowManager = GetArrowManager();
  6198. if (GetBleedingSourceCount() > 0)
  6199. {
  6200. arrowManager.DropFirstArrow();
  6201. }
  6202. else
  6203. {
  6204. arrowManager.DropAllArrows();
  6205. }
  6206. }
  6207. if (IsControlledPlayer())
  6208. {
  6209. if (!GetGame().IsDedicatedServer())
  6210. {
  6211. //Print("GetBleedingSourceCount() "+GetBleedingSourceCount());
  6212. DisplayElementBadge dis_elm = DisplayElementBadge.Cast(GetVirtualHud().GetElement(eDisplayElements.DELM_BADGE_BLEEDING));
  6213. if (dis_elm)
  6214. {
  6215. dis_elm.SetValue(GetBleedingSourceCount());
  6216. }
  6217. }
  6218. }
  6219. }
  6220. void OnBleedingSourceRemovedEx(ItemBase item)
  6221. {
  6222. OnBleedingSourceRemoved();
  6223. }
  6224. int GetBleedingSourceCount()
  6225. {
  6226. return m_BleedingSourceCount;
  6227. }
  6228. // for debug purposes, should reset some systems like Modifiers, Stats, Damage etc.....
  6229. void ResetPlayer(bool set_max)
  6230. {
  6231. #ifdef DIAG_DEVELOPER
  6232. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  6233. {
  6234. GetStomach().ClearContents();
  6235. DamageSystem.ResetAllZones(this);
  6236. GetModifiersManager().ResetAll();
  6237. // bleeding sources
  6238. if (m_BleedingManagerServer)
  6239. m_BleedingManagerServer.RemoveAllSources();
  6240. // Stats
  6241. if (GetPlayerStats())
  6242. {
  6243. int bloodType = GetStatBloodType().Get();
  6244. GetPlayerStats().ResetAllStats();
  6245. GetStatBloodType().Set(bloodType);
  6246. }
  6247. // Agents
  6248. if (m_AgentPool)
  6249. m_AgentPool.RemoveAllAgents();
  6250. if (m_StaminaHandler)
  6251. m_StaminaHandler.SetStamina(GameConstants.STAMINA_MAX);
  6252. // uncon
  6253. if (IsUnconscious())
  6254. DayZPlayerSyncJunctures.SendPlayerUnconsciousness(this, false);
  6255. // set max
  6256. if (set_max)
  6257. {
  6258. GetStatWater().Set(GetStatWater().GetMax());
  6259. GetStatEnergy().Set(GetStatEnergy().GetMax());
  6260. }
  6261. // fix up inventory
  6262. FixAllInventoryItems();
  6263. //remove bloody hands
  6264. PluginLifespan moduleLifespan = PluginLifespan.Cast(GetPlugin(PluginLifespan));
  6265. moduleLifespan.UpdateBloodyHandsVisibilityEx(this, eBloodyHandsTypes.CLEAN);
  6266. if (GetArrowManager())
  6267. GetArrowManager().ClearArrows();
  6268. }
  6269. // client + single + server
  6270. HumanCommandVehicle vehCmd = GetCommand_Vehicle();
  6271. if (vehCmd)
  6272. {
  6273. Transport transport = vehCmd.GetTransport();
  6274. if (transport)
  6275. transport.FixEntity();
  6276. }
  6277. #endif
  6278. }
  6279. void CheckSoundEvent()
  6280. {
  6281. if (m_SoundEvent != 0)
  6282. {
  6283. PlaySoundEventEx(m_SoundEvent, false, true,m_SoundEventParam);
  6284. m_SoundEvent = 0;
  6285. m_SoundEventParam = 0;
  6286. }
  6287. // cancelling marked interrupted sounds
  6288. if (m_PerformedAnimActionID == -1)
  6289. {
  6290. if (m_PerformedActionSounds.Count() == 0)
  6291. return;
  6292. foreach (AbstractWave sound : m_PerformedActionSounds)
  6293. {
  6294. if (sound)
  6295. sound.Stop();
  6296. }
  6297. m_PerformedActionSounds.Clear();
  6298. }
  6299. }
  6300. void TestSend()
  6301. {
  6302. if (GetGame().IsClient()) return;
  6303. RequestSoundEvent(1234);
  6304. //Math.RandomInt(1,4096)
  6305. }
  6306. void SetStaminaState(eStaminaState state)
  6307. {
  6308. if (state != m_StaminaState)
  6309. {
  6310. m_StaminaState = state;
  6311. //PrintString("m_StaminaState:"+m_StaminaState.ToString());
  6312. SetSynchDirty();
  6313. }
  6314. }
  6315. int GetStaminaState()
  6316. {
  6317. return m_StaminaState;
  6318. }
  6319. void UpdateQuickBarExtraSlots()
  6320. {
  6321. m_QuickBarBase.updateSlotsCount();
  6322. }
  6323. bool Save()
  6324. {
  6325. // saved player must be alive and not captive
  6326. if (GetPlayerState() == EPlayerStates.ALIVE && !IsRestrained())
  6327. {
  6328. GetHive().CharacterSave(this);
  6329. Debug.Log("Player "+this.ToString()+ " saved as alive");
  6330. return true;
  6331. }
  6332. return false;
  6333. }
  6334. // agent transfer
  6335. //! chance between [0..1] , distance in meters
  6336. void SpreadAgentsEx(float distance = 3,float chance = 0.25)
  6337. {
  6338. if (Math.RandomFloat01() > chance)
  6339. return;
  6340. GetGame().GetPlayers(m_ServerPlayers);
  6341. float dist_check = distance * distance;//make it sq
  6342. PluginTransmissionAgents plugin = PluginTransmissionAgents.Cast(GetPlugin(PluginTransmissionAgents));
  6343. foreach (Man target: m_ServerPlayers)
  6344. {
  6345. if (vector.DistanceSq(GetWorldPosition(), target.GetWorldPosition()) < dist_check && target != this)
  6346. {
  6347. plugin.TransmitAgents(this, target, AGT_AIRBOURNE_BIOLOGICAL, 1);
  6348. }
  6349. }
  6350. }
  6351. void SpreadAgents()//legacy method
  6352. {
  6353. SpreadAgentsEx(3,1);
  6354. }
  6355. //--------------------------------------------------------------------------------------------
  6356. override int GetAgents()
  6357. {
  6358. return m_AgentPool.GetAgents();
  6359. }
  6360. //--------------------------------------------------------------------------------------------
  6361. override void RemoveAgent(int agent_id) //removes a single agent type from the player agent pool
  6362. {
  6363. m_AgentPool.RemoveAgent(agent_id);
  6364. }
  6365. //--------------------------------------------------------------------------------------------
  6366. override void RemoveAllAgents()
  6367. {
  6368. m_AgentPool.RemoveAllAgents();
  6369. }
  6370. //--------------------------------------------------------------------------------------------
  6371. override void InsertAgent(int agent, float count = 1) //adds a single agent type to the player agent pool
  6372. {
  6373. m_AgentPool.AddAgent(agent,count);
  6374. }
  6375. //--------------------------------------------------------------------------------------------
  6376. int GetSingleAgentCount(int agent_id)
  6377. {
  6378. return m_AgentPool.GetSingleAgentCount(agent_id);
  6379. }
  6380. //--------------------------------------------------------------------------------------------
  6381. float GetSingleAgentCountNormalized(int agent_id)
  6382. {
  6383. int max_count = PluginTransmissionAgents.GetAgentMaxCount(agent_id);
  6384. return m_AgentPool.GetSingleAgentCount(agent_id) / max_count;
  6385. }
  6386. float GetTotalAgentCount()
  6387. {
  6388. return m_AgentPool.GetTotalAgentCount();
  6389. }
  6390. void PrintAgents()
  6391. {
  6392. m_AgentPool.PrintAgents();
  6393. }
  6394. void ImmuneSystemTick(float value, float deltaT)
  6395. {
  6396. m_AgentPool.ImmuneSystemTick(value, deltaT);
  6397. }
  6398. void AntibioticsAttack(float value)
  6399. {
  6400. m_AgentPool.DrugsAttack(EMedicalDrugsType.ANTIBIOTICS, value);
  6401. }
  6402. void SetTemporaryResistanceToAgent(int agent, float time)
  6403. {
  6404. m_AgentPool.SetTemporaryResistance(agent, time);
  6405. }
  6406. //Get aim (player crosshair) position
  6407. vector GetAimPosition()
  6408. {
  6409. float min_distance = 0.5; //min distance, default = 5m
  6410. vector from = GetGame().GetCurrentCameraPosition();
  6411. vector to = from + (GetGame().GetCurrentCameraDirection() * min_distance);
  6412. vector contactPos;
  6413. vector contactDir;
  6414. int contactComponent;
  6415. DayZPhysics.RaycastRV(from, to, contactPos, contactDir, contactComponent, NULL, NULL, NULL, false, true);
  6416. return contactPos;
  6417. }
  6418. bool CanEatAndDrink()
  6419. {
  6420. ItemBase mask = ItemBase.Cast(GetInventory().FindAttachment(InventorySlots.MASK));
  6421. return (!mask || (mask && mask.AllowFoodConsumption()));
  6422. }
  6423. //get modifier manager
  6424. ModifiersManager GetModifiersManager()
  6425. {
  6426. return m_ModifiersManager;
  6427. }
  6428. PlayerStat<float> GetStatWater()
  6429. {
  6430. if (!m_StatWater && GetPlayerStats())
  6431. {
  6432. m_StatWater = PlayerStat<float>.Cast(GetPlayerStats().GetStatObject(EPlayerStats_current.WATER));
  6433. }
  6434. return m_StatWater;
  6435. }
  6436. PlayerStat<float> GetStatToxicity()
  6437. {
  6438. if (!m_StatToxicity && GetPlayerStats())
  6439. {
  6440. m_StatToxicity = PlayerStat<float>.Cast(GetPlayerStats().GetStatObject(EPlayerStats_current.TOXICITY));
  6441. }
  6442. return m_StatToxicity;
  6443. }
  6444. PlayerStat<float> GetStatEnergy()
  6445. {
  6446. if (!m_StatEnergy && GetPlayerStats())
  6447. {
  6448. m_StatEnergy = PlayerStat<float>.Cast(GetPlayerStats().GetStatObject(EPlayerStats_current.ENERGY));
  6449. }
  6450. return m_StatEnergy;
  6451. }
  6452. PlayerStat<float> GetStatHeatComfort()
  6453. {
  6454. if (!m_StatHeatComfort && GetPlayerStats())
  6455. {
  6456. m_StatHeatComfort = PlayerStat<float>.Cast(GetPlayerStats().GetStatObject(EPlayerStats_current.HEATCOMFORT));
  6457. }
  6458. return m_StatHeatComfort;
  6459. }
  6460. PlayerStat<float> GetStatTremor()
  6461. {
  6462. if (!m_StatTremor && GetPlayerStats())
  6463. {
  6464. m_StatTremor = PlayerStat<float>.Cast(GetPlayerStats().GetStatObject(EPlayerStats_current.TREMOR));
  6465. }
  6466. return m_StatTremor;
  6467. }
  6468. PlayerStat<int> GetStatWet()
  6469. {
  6470. if (!m_StatWet && GetPlayerStats())
  6471. {
  6472. m_StatWet = PlayerStat<int>.Cast(GetPlayerStats().GetStatObject(EPlayerStats_current.WET));
  6473. }
  6474. return m_StatWet;
  6475. }
  6476. PlayerStat<float> GetStatDiet()
  6477. {
  6478. if (!m_StatDiet && GetPlayerStats())
  6479. {
  6480. m_StatDiet = PlayerStat<float>.Cast(GetPlayerStats().GetStatObject(EPlayerStats_current.DIET));
  6481. }
  6482. return m_StatDiet;
  6483. }
  6484. PlayerStat<float> GetStatStamina()
  6485. {
  6486. if (!m_StatStamina && GetPlayerStats())
  6487. {
  6488. m_StatStamina = PlayerStat<float>.Cast(GetPlayerStats().GetStatObject(EPlayerStats_current.STAMINA));
  6489. }
  6490. return m_StatStamina;
  6491. }
  6492. PlayerStat<float> GetStatSpecialty()
  6493. {
  6494. if (!m_StatSpecialty && GetPlayerStats())
  6495. {
  6496. m_StatSpecialty = PlayerStat<float>.Cast(GetPlayerStats().GetStatObject(EPlayerStats_current.SPECIALTY));
  6497. }
  6498. return m_StatSpecialty;
  6499. }
  6500. PlayerStat<int> GetStatBloodType()
  6501. {
  6502. if (!m_StatBloodType && GetPlayerStats())
  6503. {
  6504. m_StatBloodType = PlayerStat<int>.Cast(GetPlayerStats().GetStatObject(EPlayerStats_current.BLOODTYPE));
  6505. }
  6506. return m_StatBloodType;
  6507. }
  6508. PlayerStat<float> GetStatHeatBuffer()
  6509. {
  6510. if (!m_StatHeatBuffer && GetPlayerStats())
  6511. {
  6512. m_StatHeatBuffer = PlayerStat<float>.Cast(GetPlayerStats().GetStatObject(EPlayerStats_current.HEATBUFFER));
  6513. }
  6514. return m_StatHeatBuffer;
  6515. }
  6516. void SetHeatBufferDynamicMax(float value)
  6517. {
  6518. m_HeatBufferDynamicMax = value;
  6519. SetSynchDirty();
  6520. }
  6521. float GetHeatBufferDynamicMax()
  6522. {
  6523. return m_HeatBufferDynamicMax;
  6524. }
  6525. void ToggleHeatBufferVisibility(bool show)
  6526. {
  6527. m_HasHeatBuffer = show;
  6528. SetSynchDirty();
  6529. }
  6530. void ToggleHeatBufferVisibility(int heatbufferStage)
  6531. {
  6532. m_HeatBufferStage = heatbufferStage;
  6533. SetSynchDirty();
  6534. }
  6535. //! UA Last Message
  6536. string GetLastUAMessage()
  6537. {
  6538. return m_UALastMessage;
  6539. }
  6540. void SetLastUAMessage(string pMsg)
  6541. {
  6542. m_UALastMessage = pMsg;
  6543. if (m_UALastMessageTimer.IsRunning())
  6544. {
  6545. m_UALastMessageTimer.Stop();
  6546. }
  6547. m_UALastMessageTimer.Run(PlayerConstants.LAST_UA_MSG_LIFETIME, this, "ClearLastUAMessage", null);
  6548. }
  6549. protected void ClearLastUAMessage()
  6550. {
  6551. if (m_UALastMessageTimer.IsRunning())
  6552. {
  6553. m_UALastMessageTimer.Stop();
  6554. }
  6555. m_UALastMessage = "";
  6556. }
  6557. //! -------------------------------------------------------------------------
  6558. //! Injured stat
  6559. //! update injured state immediately
  6560. void ForceUpdateInjuredState()
  6561. {
  6562. m_InjuryHandler.CheckValue(true);
  6563. }
  6564. override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
  6565. {
  6566. #ifdef DIAG_DEVELOPER
  6567. if (m_Bot && action_id > EActions.PLAYER_BOT_INTERNAL_START && action_id < EActions.PLAYER_BOT_END)
  6568. {
  6569. m_Bot.StartAction(action_id);
  6570. return true;
  6571. }
  6572. #endif
  6573. return super.OnAction(action_id, player, ctx);
  6574. }
  6575. // -------------------------------------------------------------------------
  6576. override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
  6577. {
  6578. int i;
  6579. PluginTransmissionAgents pluginTransmissionAgents = PluginTransmissionAgents.Cast(GetPlugin(PluginTransmissionAgents));
  6580. if (pluginTransmissionAgents)
  6581. {
  6582. map<int, string> agentList = pluginTransmissionAgents.GetSimpleAgentList();
  6583. if (agentList)
  6584. {
  6585. foreach (int tid, string tname : agentList)
  6586. {
  6587. string injectName = "Inject " + tname;
  6588. string removeName = "Remove " + tname;
  6589. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DEBUG_AGENTS_RANGE_INJECT_START + tid, injectName, Colors.WHITE));
  6590. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DEBUG_AGENTS_RANGE_REMOVE_START + tid, removeName, Colors.WHITE));
  6591. }
  6592. }
  6593. }
  6594. #ifdef DIAG_DEVELOPER
  6595. if (m_Bot || GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_AI_REMOTE)
  6596. {
  6597. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
  6598. typename e = EActions;
  6599. int cnt = e.GetVariableCount();
  6600. int val;
  6601. for (i = 0; i < cnt; i++)
  6602. {
  6603. if (!e.GetVariableValue(null, i, val))
  6604. continue;
  6605. if (val <= EActions.PLAYER_BOT_INTERNAL_START)
  6606. continue;
  6607. if (val == EActions.PLAYER_BOT_START)
  6608. {
  6609. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
  6610. continue;
  6611. }
  6612. if (val >= EActions.PLAYER_BOT_END)
  6613. break;
  6614. string name = e.GetVariableName(i);
  6615. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, val, name, FadeColors.LIGHT_GREY));
  6616. }
  6617. }
  6618. #endif
  6619. }
  6620. //-------------------------------------------------------------
  6621. //!
  6622. //! SyncJunctures
  6623. //!
  6624. override void OnSyncJuncture(int pJunctureID, ParamsReadContext pCtx)
  6625. {
  6626. super.OnSyncJuncture(pJunctureID, pCtx);
  6627. switch(pJunctureID)
  6628. {
  6629. case DayZPlayerSyncJunctures.SJ_INJURY:
  6630. eInjuryHandlerLevels level;
  6631. bool enable;
  6632. DayZPlayerSyncJunctures.ReadInjuryParams(pCtx, enable, level);
  6633. m_InjuryHandler.SetInjuryCommandParams(enable, level);
  6634. break;
  6635. case DayZPlayerSyncJunctures.SJ_PLAYER_STATES:
  6636. GetSymptomManager().SetAnimation(pCtx);
  6637. break;
  6638. case DayZPlayerSyncJunctures.SJ_QUICKBAR_SET_SHORTCUT:
  6639. OnQuickbarSetEntityRequest(pCtx);
  6640. break;
  6641. case DayZPlayerSyncJunctures.SJ_INVENTORY:
  6642. GetInventory().OnInventoryJunctureFromServer(pCtx);
  6643. break;
  6644. case DayZPlayerSyncJunctures.SJ_INVENTORY_REPAIR:
  6645. GetInventory().OnInventoryJunctureRepairFromServer(pCtx);
  6646. break;
  6647. case DayZPlayerSyncJunctures.SJ_INVENTORY_FAILURE:
  6648. GetInventory().OnInventoryJunctureFailureFromServer(pCtx);
  6649. break;
  6650. case DayZPlayerSyncJunctures.SJ_ACTION_INTERRUPT:
  6651. case DayZPlayerSyncJunctures.SJ_ACTION_ACK_ACCEPT:
  6652. case DayZPlayerSyncJunctures.SJ_ACTION_ACK_REJECT:
  6653. m_ActionManager.OnSyncJuncture(pJunctureID,pCtx);
  6654. break;
  6655. case DayZPlayerSyncJunctures.SJ_WEAPON_ACTION_ACK_ACCEPT:
  6656. case DayZPlayerSyncJunctures.SJ_WEAPON_ACTION_ACK_REJECT:
  6657. case DayZPlayerSyncJunctures.SJ_WEAPON_SET_JAMMING_CHANCE:
  6658. m_WeaponManager.OnSyncJuncture(pJunctureID,pCtx);
  6659. break;
  6660. case DayZPlayerSyncJunctures.SJ_UNCONSCIOUSNESS:
  6661. DayZPlayerSyncJunctures.ReadPlayerUnconsciousnessParams(pCtx, m_ShouldBeUnconscious);
  6662. break;
  6663. case DayZPlayerSyncJunctures.SJ_PLAYER_ADD_MODIFIER:
  6664. GetSymptomManager().SetAnimation(pCtx);
  6665. break;
  6666. case DayZPlayerSyncJunctures.SJ_KURU_REQUEST:
  6667. float amount;
  6668. if (DayZPlayerSyncJunctures.ReadKuruRequest(pCtx, amount))
  6669. {
  6670. if (GetAimingModel() && IsFireWeaponRaised())
  6671. {
  6672. GetAimingModel().RequestKuruShake(amount);
  6673. }
  6674. }
  6675. break;
  6676. case DayZPlayerSyncJunctures.SJ_GESTURE_REQUEST :
  6677. m_EmoteManager.OnSyncJuncture(pJunctureID, pCtx);
  6678. break;
  6679. case DayZPlayerSyncJunctures.SJ_WEAPON_LIFT: // Obsolete
  6680. SetLiftWeapon(pJunctureID, pCtx);
  6681. break;
  6682. case DayZPlayerSyncJunctures.SJ_ADS_RESET:
  6683. m_ResetADS = true;
  6684. break;
  6685. case DayZPlayerSyncJunctures.SJ_DELETE_ITEM:
  6686. SetToDelete(pCtx);
  6687. break;
  6688. case DayZPlayerSyncJunctures.SJ_BROKEN_LEGS:
  6689. m_BrokenLegsJunctureReceived = true;
  6690. DayZPlayerSyncJunctures.ReadBrokenLegsParamsEx(pCtx, m_BrokenLegState);
  6691. break;
  6692. case DayZPlayerSyncJunctures.SJ_SHOCK :
  6693. DayZPlayerSyncJunctures.ReadShockParams(pCtx, m_CurrentShock);
  6694. break;
  6695. case DayZPlayerSyncJunctures.SJ_STAMINA:
  6696. m_StaminaHandler.OnSyncJuncture(pJunctureID, pCtx);
  6697. break;
  6698. case DayZPlayerSyncJunctures.SJ_STAMINA_MISC:
  6699. m_StaminaHandler.OnSyncJuncture(pJunctureID, pCtx);
  6700. break;
  6701. #ifdef DEVELOPER
  6702. case DayZPlayerSyncJunctures.SJ_DEBUG_GET_IN_VEHICLE:
  6703. EntityAI vehicle;
  6704. DayZPlayerSyncJunctures.ReadGetInVehicleParams(pCtx, vehicle);
  6705. SetGetInVehicleDebug(vehicle);
  6706. break;
  6707. #endif
  6708. }
  6709. }
  6710. bool IsItemsToDelete()
  6711. {
  6712. return m_ItemsToDelete.Count() > 0;
  6713. }
  6714. void SetToDelete(ParamsReadContext pCtx)
  6715. {
  6716. EntityAI item;
  6717. pCtx.Read(item);
  6718. AddItemToDelete(item);
  6719. }
  6720. override void AddItemToDelete(EntityAI item)
  6721. {
  6722. if (item)
  6723. {
  6724. item.SetPrepareToDelete();
  6725. m_ItemsToDelete.Insert(item);
  6726. }
  6727. }
  6728. bool CanDeleteItems()
  6729. {
  6730. return !(GetThrowing().IsThrowingAnimationPlaying() || GetDayZPlayerInventory().IsProcessing() || (GetActionManager() && GetActionManager().GetRunningAction()));
  6731. }
  6732. override void JunctureDeleteItem(EntityAI item)
  6733. {
  6734. DayZPlayerSyncJunctures.SendDeleteItem(this, item);
  6735. }
  6736. void UpdateDelete()
  6737. {
  6738. int count = m_ItemsToDelete.Count();
  6739. if (count > 0)
  6740. {
  6741. if (CanDeleteItems())
  6742. {
  6743. EntityAI itemToDelete;
  6744. if (GetGame().IsClient() && GetGame().IsMultiplayer())
  6745. {
  6746. InventoryLocation il = new InventoryLocation();
  6747. for (int i = count - 1; i >= 0 ; i--)
  6748. {
  6749. itemToDelete = m_ItemsToDelete.Get(i);
  6750. if (itemToDelete != null)
  6751. {
  6752. itemToDelete.GetInventory().GetCurrentInventoryLocation(il);
  6753. }
  6754. if (itemToDelete == null || (GetItemInHands() == null && il.GetType() == InventoryLocationType.UNKNOWN))
  6755. {
  6756. m_ItemsToDelete.Remove(i);
  6757. }
  6758. }
  6759. }
  6760. else
  6761. {
  6762. for (int j = count - 1; j >= 0 ; j--)
  6763. {
  6764. itemToDelete = m_ItemsToDelete.Get(j);
  6765. if (itemToDelete == null)
  6766. {
  6767. m_ItemsToDelete.Remove(j);
  6768. }
  6769. else
  6770. {
  6771. itemToDelete.Delete();
  6772. m_ItemsToDelete.Remove(j);
  6773. }
  6774. }
  6775. }
  6776. }
  6777. }
  6778. }
  6779. override bool HeadingModel(float pDt, SDayZPlayerHeadingModel pModel)
  6780. {
  6781. if (GetActionManager()) // disable character turning while performing actions
  6782. {
  6783. ActionContinuousBase action = ActionContinuousBase.Cast(GetActionManager().GetRunningAction());
  6784. if (action && action.IsFullBody(this) && action.IsCameraLockOnPerform())
  6785. {
  6786. if (!m_IsHeadingRestricted)
  6787. {
  6788. m_IsHeadingRestricted = true;
  6789. m_HeadingRestrictData.InitData(pModel.m_fHeadingAngle, action.GetCameraLRAngle());
  6790. }
  6791. return DayZPlayerImplementHeading.RestrictHeading(pDt, pModel, m_fLastHeadingDiff, m_HeadingRestrictData);
  6792. }
  6793. else
  6794. m_IsHeadingRestricted = false;
  6795. }
  6796. //! during fullbody gestures - disables character turning
  6797. if (GetEmoteManager().IsControllsLocked())
  6798. {
  6799. HumanItemAccessor hia = GetItemAccessor();
  6800. HumanItemBehaviorCfg hibcfg = hia.GetItemInHandsBehaviourCfg();
  6801. if (hibcfg && hibcfg.m_StanceRotation[m_MovementState.m_iStanceIdx] == DayZPlayerConstants.ROTATION_DISABLE)
  6802. {
  6803. return DayZPlayerImplementHeading.NoHeading(pDt, pModel, m_fLastHeadingDiff);
  6804. }
  6805. else
  6806. {
  6807. m_fLastHeadingDiff = 0;
  6808. return DayZPlayerImplementHeading.ClampHeading(pDt, pModel, m_fLastHeadingDiff);
  6809. }
  6810. }
  6811. return super.HeadingModel(pDt, pModel);
  6812. }
  6813. override bool IsInventorySoftLocked()
  6814. {
  6815. return m_InventorySoftLockCount > 0;
  6816. }
  6817. //! 'soft lock' meaning inventory screen cannot be displayed, but mechanically, inventory operations are still possible
  6818. override void SetInventorySoftLock(bool status)
  6819. {
  6820. if (status)
  6821. m_InventorySoftLockCount++;
  6822. else
  6823. m_InventorySoftLockCount--;
  6824. if (m_InventorySoftLockCount < 0)
  6825. m_InventorySoftLockCount = 0;
  6826. m_InventorySoftLocked = IsInventorySoftLocked();
  6827. }
  6828. void SetLoadedQuickBarItemBind(EntityAI entity, int index)
  6829. {
  6830. if (m_aQuickBarLoad)
  6831. m_aQuickBarLoad.Insert(new Param2<EntityAI, int>(entity,index));
  6832. }
  6833. override bool IsLiftWeapon()
  6834. {
  6835. return m_LiftWeapon_player;
  6836. }
  6837. //Server
  6838. bool ReadLiftWeaponRequest(int userDataType, ParamsReadContext ctx)
  6839. {
  6840. bool state;
  6841. ctx.Read(state);
  6842. SetLiftWeapon(state);
  6843. return true;
  6844. }
  6845. void SetLiftWeapon(int pJunctureID, ParamsReadContext ctx) // Obsolete
  6846. {
  6847. bool state;
  6848. ctx.Read(state);
  6849. SetLiftWeapon(state);
  6850. //Print("SetLiftWeapon | STS: " + GetSimulationTimeStamp());
  6851. }
  6852. void SetLiftWeapon(bool state)
  6853. {
  6854. m_ProcessLiftWeaponState = state;
  6855. m_ProcessLiftWeapon = true;
  6856. }
  6857. //! Client-side only
  6858. void SendLiftWeaponSync(bool state)
  6859. {
  6860. HumanCommandWeapons hcw;
  6861. // Apply state immediately
  6862. m_LiftWeapon_player = state;
  6863. hcw = GetCommandModifier_Weapons();
  6864. if (hcw)
  6865. hcw.LiftWeapon(state);
  6866. GetWeaponManager().OnLiftWeapon();
  6867. // Notify server to apply same state
  6868. if (GetGame().IsMultiplayer() && GetGame().IsClient())
  6869. {
  6870. ScriptInputUserData ctx = new ScriptInputUserData;
  6871. if (!ctx.CanStoreInputUserData())
  6872. {
  6873. // ctx not available??
  6874. return;
  6875. }
  6876. ctx.Write(INPUT_UDT_WEAPON_LIFT_EVENT);
  6877. ctx.Write(state);
  6878. ctx.Send();
  6879. }
  6880. }
  6881. override void CheckLiftWeapon()
  6882. {
  6883. // lift weapon check
  6884. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  6885. {
  6886. Weapon_Base weap;
  6887. if (Weapon_Base.CastTo(weap, GetItemInHands()))
  6888. {
  6889. bool limited = weap.LiftWeaponCheck(this);
  6890. if (limited && !m_LiftWeapon_player)
  6891. SendLiftWeaponSync(true);
  6892. else if (!limited && m_LiftWeapon_player)
  6893. SendLiftWeaponSync(false);
  6894. }
  6895. else if (m_LiftWeapon_player)
  6896. {
  6897. SendLiftWeaponSync(false);
  6898. }
  6899. }
  6900. }
  6901. override void ProcessLiftWeapon()
  6902. {
  6903. if (m_ProcessLiftWeapon)
  6904. {
  6905. HumanCommandWeapons hcw = GetCommandModifier_Weapons();
  6906. if (hcw)
  6907. hcw.LiftWeapon(m_ProcessLiftWeaponState);
  6908. GetWeaponManager().OnLiftWeapon();
  6909. m_LiftWeapon_player = m_ProcessLiftWeaponState;
  6910. m_ProcessLiftWeapon = false;
  6911. //Debug.Log("SimulationStamp_server: " + this.GetSimulationTimeStamp());
  6912. }
  6913. }
  6914. //! state 'true' == hide
  6915. override void HideClothing(ItemOptics optic, bool state)
  6916. {
  6917. super.HideClothing(optic, state);
  6918. array<int> clothingArray = new array<int>;
  6919. Clothing clothes;
  6920. if (state && DayZPlayerCameraOptics.Cast(m_CurrentCamera))
  6921. {
  6922. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  6923. {
  6924. clothingArray.Insert(InventorySlots.BACK);
  6925. clothingArray.Insert(InventorySlots.SHOULDER);
  6926. clothingArray.Insert(InventorySlots.MELEE);
  6927. if (optic && optic.GetCurrentStepFOV() < GameConstants.DZPLAYER_CAMERA_FOV_IRONSIGHTS)
  6928. {
  6929. clothingArray.Insert(InventorySlots.BODY);
  6930. clothingArray.Insert(InventorySlots.VEST);
  6931. }
  6932. SetInvisibleRecursive(true,this,clothingArray);
  6933. }
  6934. }
  6935. //showing should be instant (called directly, not via CallLater)
  6936. else
  6937. {
  6938. if (GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  6939. {
  6940. clothingArray = {InventorySlots.BACK,InventorySlots.BODY,InventorySlots.VEST,InventorySlots.SHOULDER,InventorySlots.MELEE};
  6941. SetInvisibleRecursive(false,this,clothingArray);
  6942. }
  6943. }
  6944. }
  6945. void RequestUnconsciousness(bool enable)
  6946. {
  6947. DayZPlayerSyncJunctures.SendPlayerUnconsciousness(this, enable);
  6948. }
  6949. override void SetDeathDarknessLevel(float duration, float tick_time)
  6950. {
  6951. super.SetDeathDarknessLevel(duration, tick_time);
  6952. if (IsControlledPlayer())
  6953. {
  6954. float actual_tick = tick_time;
  6955. if (GetDamageDealtEffect())
  6956. m_DamageDealtEffect = null;
  6957. if (GetFlashbangEffect())
  6958. m_FlashbangEffect = null;
  6959. float progress;
  6960. if (duration > 0)
  6961. progress = 1 - ((duration - m_DeathDarkeningCurrentTime) / duration);
  6962. m_DeathDarkeningCurrentTime += actual_tick;
  6963. if (!IsAlive() && IsPlayerSelected())
  6964. {
  6965. m_DeathDarkeningParam.param1 = progress;
  6966. PPERequesterBank.GetRequester(PPERequester_DeathDarkening).Start(m_DeathDarkeningParam);
  6967. }
  6968. if (m_DeathDarkeningCurrentTime >= duration)
  6969. {
  6970. StopDeathDarkeningEffect();
  6971. }
  6972. }
  6973. else
  6974. {
  6975. StopDeathDarkeningEffect();
  6976. }
  6977. }
  6978. override bool IsInFBEmoteState()
  6979. {
  6980. if (!IsEmotePlaying())
  6981. return false;
  6982. if ((m_EmoteManager.m_Callback && m_EmoteManager.m_Callback.m_IsFullbody) || m_EmoteManager.m_IsSurrendered)
  6983. {
  6984. return true;
  6985. }
  6986. return false;
  6987. }
  6988. //! ends surrender, originally intended for surrender->restrained transitioning
  6989. void EndSurrenderRequest(SurrenderData data = null)
  6990. {
  6991. if (m_EmoteManager)
  6992. m_EmoteManager.EndSurrenderRequest(data);
  6993. }
  6994. bool IsSurrendered()
  6995. {
  6996. if (m_EmoteManager)
  6997. return m_EmoteManager.m_IsSurrendered;
  6998. return false;
  6999. }
  7000. bool IsPlayerLoaded()
  7001. {
  7002. return m_PlayerLoaded;
  7003. }
  7004. //disconnected, caused problems. Awaiting refactor
  7005. override void CheckAnimationOverrides()
  7006. {
  7007. //FB gesture slideposeangle override
  7008. if (IsInFBEmoteState() && IsControlledPlayer() && IsPlayerSelected())
  7009. {
  7010. OverrideSlidePoseAngle(Math.PI2);
  7011. }
  7012. else if (!IsInFBEmoteState() && IsControlledPlayer() && IsPlayerSelected())
  7013. {
  7014. OverrideSlidePoseAngle(m_OriginalSlidePoseAngle);
  7015. }
  7016. //+add more, if needed
  7017. }
  7018. /*void OnSurrenderEnd()
  7019. {
  7020. }*/
  7021. bool CanRedirectToWeaponManager (notnull EntityAI item, out bool isActionPossible)
  7022. {
  7023. isActionPossible = false;
  7024. Magazine mag = Magazine.Cast(item);
  7025. Weapon_Base wpn = Weapon_Base.Cast(item.GetHierarchyParent());
  7026. if (mag && wpn)
  7027. {
  7028. if (GetWeaponManager().CanDetachMagazine(wpn, mag))
  7029. {
  7030. //Print("[inv] PlayerBase.CanRedirectToWeaponManager OK, can detach mag=" + mag + " from wpn=" + wpn);
  7031. isActionPossible = true;
  7032. }
  7033. else
  7034. {
  7035. //Print("[inv] PlayerBase.CanRedirectToWeaponManager cannot detach mag=" + mag + " from wpn=" + wpn);
  7036. }
  7037. return true;
  7038. }
  7039. return false;
  7040. }
  7041. // Inventory actions with redirection to weapon manager
  7042. override bool PredictiveTakeEntityToTargetInventory (notnull EntityAI target, FindInventoryLocationType flags, notnull EntityAI item)
  7043. {
  7044. bool can_detach;
  7045. if (CanRedirectToWeaponManager(item,can_detach))
  7046. {
  7047. InventoryLocation il = new InventoryLocation();
  7048. if (can_detach && target.GetInventory().FindFreeLocationFor(item, flags, il))
  7049. {
  7050. return GetWeaponManager().DetachMagazine(il);
  7051. }
  7052. return false;
  7053. }
  7054. return super.PredictiveTakeEntityToTargetInventory(target, flags, item);
  7055. }
  7056. override bool PredictiveTakeEntityToInventory (FindInventoryLocationType flags, notnull EntityAI item)
  7057. {
  7058. bool can_detach;
  7059. if (CanRedirectToWeaponManager(item,can_detach))
  7060. {
  7061. InventoryLocation il = new InventoryLocation();
  7062. if (can_detach && GetInventory().FindFreeLocationFor(item, flags, il))
  7063. {
  7064. return GetWeaponManager().DetachMagazine(il);
  7065. }
  7066. return false;
  7067. }
  7068. return super.PredictiveTakeEntityToInventory(flags, item);
  7069. }
  7070. override bool PredictiveTakeEntityToTargetAttachment (notnull EntityAI target, notnull EntityAI item)
  7071. {
  7072. Weapon_Base parentWpn = Weapon_Base.Cast(target);
  7073. Magazine mag = Magazine.Cast(item);
  7074. if (parentWpn && mag)
  7075. {
  7076. if (GetWeaponManager().CanAttachMagazine(parentWpn, mag))
  7077. return GetWeaponManager().AttachMagazine(mag);
  7078. return false;
  7079. }
  7080. return super.PredictiveTakeEntityToTargetAttachment(target, item);
  7081. }
  7082. override bool PredictiveTakeEntityToTargetAttachmentEx (notnull EntityAI target, notnull EntityAI item, int slot)
  7083. {
  7084. Weapon_Base parentWpn = Weapon_Base.Cast(target);
  7085. Magazine mag = Magazine.Cast(item);
  7086. if (parentWpn && mag)
  7087. {
  7088. if (target.CanReceiveAttachment(item,slot) && GetWeaponManager().CanAttachMagazine(parentWpn, mag))
  7089. return GetWeaponManager().AttachMagazine(mag);
  7090. return false;
  7091. }
  7092. return super.PredictiveTakeEntityToTargetAttachmentEx(target, item,slot);
  7093. }
  7094. override bool PredictiveTakeEntityToTargetCargo (notnull EntityAI target, notnull EntityAI item)
  7095. {
  7096. bool can_detach;
  7097. if (CanRedirectToWeaponManager(item,can_detach))
  7098. {
  7099. InventoryLocation il = new InventoryLocation();
  7100. if (can_detach && target.GetInventory().FindFreeLocationFor(item, FindInventoryLocationType.CARGO, il))
  7101. {
  7102. return GetWeaponManager().DetachMagazine(il);
  7103. }
  7104. return false;
  7105. }
  7106. return super.PredictiveTakeEntityToTargetCargo(target,item);
  7107. }
  7108. override bool PredictiveTakeEntityToTargetCargoEx (notnull CargoBase cargo, notnull EntityAI item, int row, int col)
  7109. {
  7110. bool can_detach;
  7111. if (CanRedirectToWeaponManager(item, can_detach))
  7112. {
  7113. if (can_detach)
  7114. {
  7115. InventoryLocation dst = new InventoryLocation;
  7116. dst.SetCargoAuto(cargo, item, row, col, item.GetInventory().GetFlipCargo());
  7117. return GetWeaponManager().DetachMagazine(dst);
  7118. }
  7119. return false;
  7120. }
  7121. return super.PredictiveTakeEntityToTargetCargoEx (cargo, item, row, col);
  7122. }
  7123. override bool PredictiveDropEntity (notnull EntityAI item)
  7124. {
  7125. bool can_detach;
  7126. if (CanRedirectToWeaponManager(item,can_detach))
  7127. {
  7128. if (can_detach)
  7129. {
  7130. vector m4[4];
  7131. Math3D.MatrixIdentity4(m4);
  7132. //! We don't care if a valid transform couldn't be found, we just want to preferably use it instead of placing on the player
  7133. GameInventory.PrepareDropEntityPos(this, item, m4, false, GameConstants.INVENTORY_ENTITY_DROP_OVERLAP_DEPTH);
  7134. InventoryLocation il = new InventoryLocation;
  7135. il.SetGround(item, m4);
  7136. return GetWeaponManager().DetachMagazine(il);
  7137. }
  7138. return false;
  7139. }
  7140. return super.PredictiveDropEntity(item);
  7141. }
  7142. override bool PredictiveSwapEntities (notnull EntityAI item1, notnull EntityAI item2)
  7143. {
  7144. ForceStandUpForHeavyItemsSwap(item1, item2);
  7145. //Print("PlayerBase | PredictiveSwapEntities");
  7146. Magazine swapmag1 = Magazine.Cast(item1);
  7147. Magazine swapmag2 = Magazine.Cast(item2);
  7148. if (swapmag1 && swapmag2)
  7149. {
  7150. Weapon_Base parentWpn;
  7151. if (Class.CastTo(parentWpn, swapmag1.GetHierarchyParent()))
  7152. {
  7153. if (GetWeaponManager().CanSwapMagazine(parentWpn, swapmag2))
  7154. {
  7155. Print("[inv] PlayerBase.PredictiveSwapEntities: swapping mag1=" + swapmag1 + " to parent wpn=" + parentWpn + " of mag1=" + swapmag1);
  7156. return GetWeaponManager().SwapMagazine(swapmag2);
  7157. }
  7158. else
  7159. {
  7160. Print("[inv] PlayerBase.PredictiveSwapEntities: can not swap magazines");
  7161. return false;
  7162. }
  7163. }
  7164. if (Class.CastTo(parentWpn, swapmag2.GetHierarchyParent()))
  7165. {
  7166. if (GetWeaponManager().CanSwapMagazine(parentWpn, swapmag1))
  7167. {
  7168. Print("[inv] PlayerBase.PredictiveSwapEntities: swapping mag1=" + swapmag1 + " to parent wpn=" + parentWpn + " of mag2=" + swapmag2);
  7169. return GetWeaponManager().SwapMagazine(swapmag1);
  7170. }
  7171. else
  7172. {
  7173. Print("[inv] PlayerBase.PredictiveSwapEntities: can not swap magazines");
  7174. return false;
  7175. }
  7176. }
  7177. }
  7178. EntityAI item_hands;
  7179. EntityAI item_ground;
  7180. if (IsSwapBetweenHandsAndGroundLargeItem(item1,item2,item_hands,item_ground) && !m_ActionManager.GetRunningAction())
  7181. {
  7182. ActionManagerClient mngr_client;
  7183. CastTo(mngr_client,m_ActionManager);
  7184. ActionTarget atrg = new ActionTarget(item_ground,null,-1,vector.Zero,-1.0);
  7185. if (mngr_client.GetAction(ActionSwapItemToHands).Can(this,atrg,ItemBase.Cast(item_hands)))
  7186. {
  7187. mngr_client.PerformActionStart(mngr_client.GetAction(ActionSwapItemToHands),atrg,ItemBase.Cast(item_hands));
  7188. return true;
  7189. }
  7190. return super.PredictiveSwapEntities(item1, item2);
  7191. }
  7192. else
  7193. return super.PredictiveSwapEntities(item1, item2);
  7194. }
  7195. override bool PredictiveForceSwapEntities (notnull EntityAI item1, notnull EntityAI item2, notnull InventoryLocation item2_dst)
  7196. {
  7197. ForceStandUpForHeavyItemsSwap(item1, item2);
  7198. InventoryLocation il = new InventoryLocation;
  7199. if (item1.IsHeavyBehaviour() && item1.GetInventory().GetCurrentInventoryLocation(il) && il.GetType() == InventoryLocationType.GROUND && !m_ActionManager.GetRunningAction())
  7200. {
  7201. //Print("override bool PredictiveForceSwapEntities (notnull EntityAI item1, notnull EntityAI item2, notnull InventoryLocation item2_dst)");
  7202. ActionManagerClient mngr_client;
  7203. CastTo(mngr_client,m_ActionManager);
  7204. ActionTarget atrg = new ActionTarget(item1,null,-1,vector.Zero,-1.0);
  7205. if (mngr_client.GetAction(ActionSwapItemToHands).Can(this,atrg,ItemBase.Cast(item2)))
  7206. {
  7207. mngr_client.PerformActionStart(mngr_client.GetAction(ActionSwapItemToHands),atrg,ItemBase.Cast(item2));
  7208. }
  7209. return true;
  7210. }
  7211. else
  7212. return super.PredictiveForceSwapEntities(item1, item2, item2_dst);
  7213. }
  7214. override void PredictiveTakeEntityToHands(EntityAI item)
  7215. {
  7216. if (item.IsHeavyBehaviour() && !m_ActionManager.GetRunningAction() && !item.GetHierarchyParent())
  7217. {
  7218. ActionManagerClient mngr_client;
  7219. if (CastTo(mngr_client,m_ActionManager))
  7220. {
  7221. ActionTarget atrg = new ActionTarget(item,null,-1,vector.Zero,-1.0);
  7222. if (mngr_client.GetAction(ActionTakeItemToHands).Can(this,atrg,null))
  7223. {
  7224. mngr_client.PerformActionStart(mngr_client.GetAction(ActionTakeItemToHands),atrg,null);
  7225. }
  7226. /*).Can(this,
  7227. mngr_client.ActionStart(mngr_client.GetAction(ActionTakeItemToHands),mngr_client.FindActionTarget(),null);
  7228. return;*/
  7229. }
  7230. }
  7231. else
  7232. super.PredictiveTakeEntityToHands(item);
  7233. }
  7234. override bool PredictiveTakeToDst (notnull InventoryLocation src, notnull InventoryLocation dst)
  7235. {
  7236. EntityAI item = src.GetItem();
  7237. if (item)
  7238. {
  7239. bool can_detach;
  7240. if (CanRedirectToWeaponManager(item,can_detach))
  7241. {
  7242. if (can_detach)
  7243. {
  7244. return GetWeaponManager().DetachMagazine(dst);
  7245. }
  7246. return false;
  7247. }
  7248. return super.PredictiveTakeToDst(src,dst);
  7249. }
  7250. return false;
  7251. }
  7252. bool IsSwapBetweenHandsAndGroundLargeItem(notnull EntityAI item1, notnull EntityAI item2, out EntityAI item_hands, out EntityAI item_ground)
  7253. {
  7254. InventoryLocation il = new InventoryLocation;
  7255. if (item1.GetInventory().GetCurrentInventoryLocation(il) && il.GetType() == InventoryLocationType.HANDS)
  7256. item_hands = item1;
  7257. if (item2.GetInventory().GetCurrentInventoryLocation(il) && il.GetType() == InventoryLocationType.HANDS)
  7258. item_hands = item2;
  7259. if (item1.GetInventory().GetCurrentInventoryLocation(il) && il.GetType() == InventoryLocationType.GROUND)
  7260. item_ground = item1;
  7261. if (item2.GetInventory().GetCurrentInventoryLocation(il) && il.GetType() == InventoryLocationType.GROUND)
  7262. item_ground = item2;
  7263. return item_hands && item_ground && item_ground.IsHeavyBehaviour();
  7264. }
  7265. //! Dynamic hair hiding
  7266. void SetHairLevelToHide(int level, bool state, bool was_debug = false)
  7267. {
  7268. if (was_debug && GetInstanceType() != DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  7269. return;
  7270. if (!m_CharactersHead)
  7271. {
  7272. ErrorEx("No valid head detected on character!");
  7273. return;
  7274. }
  7275. if (level == -1) //hide/show ALL
  7276. {
  7277. m_HideHairAnimated = !m_HideHairAnimated;
  7278. for (int i = 0; i < m_CharactersHead.m_HeadHairSelectionArray.Count(); ++i)
  7279. {
  7280. //m_CharactersHead.SetSimpleHiddenSelectionState(i,m_HideHairAnimated);
  7281. SelectionTranslation stt = SelectionTranslation.Cast(m_CharactersHead.m_HeadHairHidingStateMap.Get(i));
  7282. stt.SetSelectionState(m_HideHairAnimated);
  7283. m_CharactersHead.m_HeadHairHidingStateMap.Set(i, stt);
  7284. #ifdef DIAG_DEVELOPER
  7285. #ifndef SERVER
  7286. PluginDiagMenuClient diagmenu = PluginDiagMenuClient.Cast(GetPlugin(PluginDiagMenuClient));
  7287. diagmenu.m_HairHidingStateMap.Set(i, m_HideHairAnimated);
  7288. #endif
  7289. #endif
  7290. }
  7291. }
  7292. else //hide/show selected level only
  7293. {
  7294. bool switchState;
  7295. if (was_debug)
  7296. {
  7297. #ifdef DIAG_DEVELOPER
  7298. #ifndef SERVER
  7299. PluginDiagMenuClient diagmenuu = PluginDiagMenuClient.Cast(GetPlugin(PluginDiagMenuClient));
  7300. switchState = !diagmenuu.m_HairHidingStateMap.Get(level);
  7301. diagmenuu.m_HairHidingStateMap.Set(level, switchState);
  7302. #endif
  7303. #endif
  7304. }
  7305. else
  7306. {
  7307. switchState = !state;
  7308. }
  7309. //m_CharactersHead.SetSimpleHiddenSelectionState(level,switchState);
  7310. stt = SelectionTranslation.Cast(m_CharactersHead.m_HeadHairHidingStateMap.Get(level));
  7311. stt.SetSelectionState(switchState);
  7312. m_CharactersHead.m_HeadHairHidingStateMap.Set(level, stt); //nescessary?
  7313. }
  7314. }
  7315. void HideHairSelections(ItemBase item, bool state)
  7316. {
  7317. if (!item || !item.GetHeadHidingSelection() || !m_CharactersHead)
  7318. return;
  7319. int slot_id; //item currently attached (or detaching from) here
  7320. string slot_name; //item currently attached (or detaching from) here
  7321. string str
  7322. int idx = 0;
  7323. int i;
  7324. int count;
  7325. item.GetInventory().GetCurrentAttachmentSlotInfo(slot_id,slot_name);
  7326. if (item.HidesSelectionBySlot())
  7327. {
  7328. count = item.GetInventory().GetSlotIdCount();
  7329. for (i = 0; i < count; i++)
  7330. {
  7331. if (item.GetInventory().GetSlotId(i) == slot_id)
  7332. {
  7333. str = item.GetHeadHidingSelection().Get(i);
  7334. idx = m_CharactersHead.m_HeadHairSelectionArray.Find(str);
  7335. if (idx != -1)
  7336. SetHairLevelToHide(idx,state);
  7337. #ifdef DEVELOPER
  7338. else
  7339. Debug.Log("No valid selection '" + str + "' found on head of " + GetType() + ". Verify the p3d, model config, and the 'HAIR_HIDING_SELECTIONS' macro in basicDefines.");
  7340. #endif
  7341. }
  7342. }
  7343. }
  7344. else
  7345. {
  7346. count = item.GetHeadHidingSelection().Count();
  7347. for (i = 0; i < count; i++)
  7348. {
  7349. str = item.GetHeadHidingSelection().Get(i);
  7350. idx = m_CharactersHead.m_HeadHairSelectionArray.Find(str);
  7351. if (idx != -1)
  7352. SetHairLevelToHide(idx,state);
  7353. #ifdef DEVELOPER
  7354. else
  7355. Debug.Log("No valid selection '" + str + "' found on head of " + GetType() + ". Verify the p3d, model config, and the 'HAIR_HIDING_SELECTIONS' macro in basicDefines.");
  7356. #endif
  7357. }
  7358. }
  7359. UpdateHairSelectionVisibility();
  7360. }
  7361. void UpdateHairSelectionVisibility(bool was_debug = false)
  7362. {
  7363. if (!m_CharactersHead)
  7364. return;
  7365. bool shown;
  7366. bool exception_hidden = false;
  7367. int i;
  7368. int count = m_CharactersHead.m_HeadHairHidingStateMap.Count();
  7369. SelectionTranslation stt;
  7370. //hide/show beard
  7371. if (IsMale() && m_CharactersHead.GetBeardIndex() > -1 && !was_debug)
  7372. {
  7373. SetHairLevelToHide(m_CharactersHead.GetBeardIndex(),GetLifeSpanState() != LifeSpanState.BEARD_EXTRA);
  7374. }
  7375. //show all first
  7376. for (i = 0; i < count; i++)
  7377. {
  7378. m_CharactersHead.SetSimpleHiddenSelectionState(i,true);
  7379. }
  7380. //then carve it up
  7381. for (i = 0; i < count; i++)
  7382. {
  7383. stt = m_CharactersHead.m_HeadHairHidingStateMap.Get(i);
  7384. shown = stt.GetSelectionState();
  7385. if (!shown)
  7386. {
  7387. if (/*IsMale() && */!m_CharactersHead.IsHandlingException())
  7388. {
  7389. m_CharactersHead.SetSimpleHiddenSelectionState(i,shown);
  7390. UpdateTranslatedSelections(stt);
  7391. //Print("hidden idx: " + i);
  7392. }
  7393. else
  7394. {
  7395. exception_hidden = true;
  7396. }
  7397. }
  7398. }
  7399. //exceptions handled differently; hides hair
  7400. if (exception_hidden)
  7401. {
  7402. m_CharactersHead.SetSimpleHiddenSelectionState(m_CharactersHead.GetHairIndex(),false);
  7403. if (IsMale())
  7404. m_CharactersHead.SetSimpleHiddenSelectionState(m_CharactersHead.GetBeardIndex(),false);
  7405. }
  7406. }
  7407. void UpdateTranslatedSelections(SelectionTranslation stt)
  7408. {
  7409. int index;
  7410. array<int> translatedSelectinosArray = stt.GetTranslatedSelections();
  7411. for (int i = 0; i < translatedSelectinosArray.Count(); i++)
  7412. {
  7413. index = translatedSelectinosArray.Get(i);
  7414. //if (index > -1)
  7415. m_CharactersHead.SetSimpleHiddenSelectionState(index,false); //safe this way, only hiding/carving from shown parts
  7416. }
  7417. }
  7418. //! helper method for re-checking hairhiding on character load
  7419. void CheckHairClippingOnCharacterLoad()
  7420. {
  7421. ItemBase headgear = ItemBase.Cast(GetInventory().FindAttachment(InventorySlots.HEADGEAR));
  7422. ItemBase mask = ItemBase.Cast(GetInventory().FindAttachment(InventorySlots.MASK));
  7423. HideHairSelections(headgear,true);
  7424. HideHairSelections(mask,true);
  7425. }
  7426. bool IsNVGWorking()
  7427. {
  7428. return m_ActiveNVTypes && m_ActiveNVTypes.Count() > 0;
  7429. }
  7430. bool IsNVGLowered()
  7431. {
  7432. return m_LoweredNVGHeadset;
  7433. }
  7434. int GetNVType()
  7435. {
  7436. if (!m_ActiveNVTypes || m_ActiveNVTypes.Count() == 0)
  7437. {
  7438. return NVTypes.NONE;
  7439. }
  7440. else
  7441. {
  7442. return m_ActiveNVTypes[m_ActiveNVTypes.Count() - 1];
  7443. }
  7444. }
  7445. array<int> GetNVTypesArray()
  7446. {
  7447. return m_ActiveNVTypes;
  7448. }
  7449. //!Deprecated
  7450. void SetNVGWorking(bool state)
  7451. {
  7452. //Deprecated, below is for legacy's sake
  7453. AddActiveNV(NVTypes.NV_GOGGLES);
  7454. }
  7455. void SetNVGLowered(bool state)
  7456. {
  7457. m_LoweredNVGHeadset = state;
  7458. }
  7459. void AddActiveNV(int type)
  7460. {
  7461. if (!m_ActiveNVTypes || (GetGame().IsMultiplayer() && GetGame().IsServer()))
  7462. {
  7463. #ifdef DEVELOPER
  7464. Error("AddActiveNV | illegal server-side call!");
  7465. #endif
  7466. return;
  7467. }
  7468. if (m_ActiveNVTypes.Find(type) == -1)
  7469. m_ActiveNVTypes.Insert(type);
  7470. }
  7471. void RemoveActiveNV(int type)
  7472. {
  7473. if (!m_ActiveNVTypes || (GetGame().IsMultiplayer() && GetGame().IsServer()))
  7474. {
  7475. #ifdef DEVELOPER
  7476. Error("RemoveActiveNV | illegal server-side call!");
  7477. #endif
  7478. return;
  7479. }
  7480. if (m_ActiveNVTypes.Find(type) != -1)
  7481. m_ActiveNVTypes.RemoveItem(type);
  7482. }
  7483. void ResetActiveNV()
  7484. {
  7485. m_ActiveNVTypes.Clear();
  7486. }
  7487. #ifdef DEVELOPER
  7488. override string GetDebugText()
  7489. {
  7490. string text = super.GetDebugText();
  7491. /*
  7492. text += "GetMovementTimeToStrafeJog:" + CfgGameplayHandler.GetMovementTimeToStrafeJog() + "\n";
  7493. text += "GetMovementTimeToStrafeSprint:" + CfgGameplayHandler.GetMovementTimeToStrafeSprint()+ "\n";
  7494. SHumanCommandMoveSettings moveSettings = GetDayZPlayerType().CommandMoveSettingsW();
  7495. if (moveSettings)
  7496. {
  7497. text += "hmcs.m_fDirFilterTimeout:" + moveSettings.m_fDirFilterTimeout + "\n";
  7498. text += "hmcs.m_fDirFilterSprintTimeout:" + moveSettings.m_fDirFilterSprintTimeout+ "\n";
  7499. }*/
  7500. return text;
  7501. }
  7502. void DEBUGRotateNVG()
  7503. {
  7504. NVGoggles nvg;
  7505. if (FindAttachmentBySlotName("Eyewear"))
  7506. {
  7507. nvg = NVGoggles.Cast(FindAttachmentBySlotName("Eyewear").FindAttachmentBySlotName("NVG"));
  7508. }
  7509. else if (FindAttachmentBySlotName("Headgear"))
  7510. {
  7511. nvg = NVGoggles.Cast(FindAttachmentBySlotName("Headgear").FindAttachmentBySlotName("NVG"));
  7512. }
  7513. if (nvg)
  7514. {
  7515. nvg.RotateGoggles(nvg.m_IsLowered);
  7516. }
  7517. }
  7518. #endif
  7519. void AdjustBandana(EntityAI item, string slot_name)
  7520. {
  7521. if (Bandana_ColorBase.Cast(item))
  7522. {
  7523. if (slot_name == "Headgear")
  7524. {
  7525. item.SetSimpleHiddenSelectionState(0,1);
  7526. item.SetSimpleHiddenSelectionState(1,0);
  7527. }
  7528. else if (slot_name == "Mask")
  7529. {
  7530. item.SetSimpleHiddenSelectionState(0,0);
  7531. item.SetSimpleHiddenSelectionState(1,1);
  7532. }
  7533. }
  7534. }
  7535. void AdjustShemag(EntityAI item, string slot_name)
  7536. {
  7537. if (Shemag_ColorBase.Cast(item))
  7538. {
  7539. if (slot_name == "Headgear")
  7540. {
  7541. item.SetSimpleHiddenSelectionState(0,1);
  7542. item.SetSimpleHiddenSelectionState(1,0);
  7543. }
  7544. else if (slot_name == "Mask")
  7545. {
  7546. item.SetSimpleHiddenSelectionState(0,0);
  7547. item.SetSimpleHiddenSelectionState(1,1);
  7548. }
  7549. }
  7550. }
  7551. //client-side
  7552. void UpdateCorpseStateVisual()
  7553. {
  7554. //Print("---Prettying up corpses... | " + GetGame().GetTime() + " | " + this + " | " + GetType() + "---");
  7555. //Print("m_DecayedTexture = " + m_DecayedTexture);
  7556. int state = Math.AbsInt(m_CorpseState);//negative sign denotes a special meaning(state was forced to a live player), but we are only intetested in the positive value here
  7557. if (state == PlayerConstants.CORPSE_STATE_DECAYED)
  7558. {
  7559. EntityAI bodypart;
  7560. ItemBase item;
  7561. string path;
  7562. int idx;
  7563. int slot_id;
  7564. array<string> bodyparts = {"Gloves","Body","Legs","Feet"};
  7565. for (int i = 0; i < bodyparts.Count(); i++)
  7566. {
  7567. slot_id = InventorySlots.GetSlotIdFromString(bodyparts.Get(i));
  7568. bodypart = GetInventory().FindPlaceholderForSlot(slot_id);
  7569. item = ItemBase.Cast(GetInventory().FindAttachment(slot_id));
  7570. if (bodypart)
  7571. {
  7572. path = "cfgVehicles " + bodypart.GetType();
  7573. idx = bodypart.GetHiddenSelectionIndex("personality");
  7574. if (idx > -1)
  7575. {
  7576. bodypart.SetObjectTexture(idx,m_DecayedTexture);
  7577. }
  7578. }
  7579. if (item)
  7580. {
  7581. path = "cfgVehicles " + item.GetType();
  7582. idx = item.GetHiddenSelectionIndex("personality");
  7583. if (idx > -1)
  7584. {
  7585. item.SetObjectTexture(idx,m_DecayedTexture);
  7586. }
  7587. }
  7588. }
  7589. SetFaceTexture(m_DecayedTexture);
  7590. }
  7591. }
  7592. void SetDecayEffects(int effect = -1)
  7593. {
  7594. int boneIdx = GetBoneIndexByName("Spine2");
  7595. Particle p;
  7596. switch (effect)
  7597. {
  7598. case PlayerConstants.CORPSE_STATE_MEDIUM :
  7599. //play medium sound/flies particle
  7600. if (!m_FliesEff)
  7601. m_FliesEff = new EffSwarmingFlies();
  7602. if (m_FliesEff && !SEffectManager.IsEffectExist(m_FliesIndex))
  7603. {
  7604. m_FliesEff.SetDecalOwner(this);
  7605. m_FliesIndex = SEffectManager.PlayOnObject(m_FliesEff, this, "0 0.25 0");
  7606. p = m_FliesEff.GetParticle();
  7607. AddChild(p, boneIdx);
  7608. if (!m_SoundFliesEffect)
  7609. {
  7610. PlaySoundSetLoop(m_SoundFliesEffect, "Flies_SoundSet", 1.0, 1.0);
  7611. }
  7612. }
  7613. break;
  7614. case PlayerConstants.CORPSE_STATE_DECAYED :
  7615. //play serious sound/flies particle
  7616. if (!m_FliesEff)
  7617. m_FliesEff = new EffSwarmingFlies();
  7618. if (m_FliesEff && !SEffectManager.IsEffectExist(m_FliesIndex))
  7619. {
  7620. m_FliesEff.SetDecalOwner(this);
  7621. m_FliesIndex = SEffectManager.PlayOnObject(m_FliesEff, this, "0 0.25 0");
  7622. p = m_FliesEff.GetParticle();
  7623. AddChild(p, boneIdx);
  7624. if (!m_SoundFliesEffect)
  7625. {
  7626. PlaySoundSetLoop(m_SoundFliesEffect, "Flies_SoundSet", 1.0, 1.0);
  7627. }
  7628. }
  7629. break;
  7630. //remove
  7631. default:
  7632. SEffectManager.DestroyEffect(m_FliesEff);
  7633. StopSoundSet(m_SoundFliesEffect);
  7634. break;
  7635. }
  7636. }
  7637. void PreloadDecayTexture()
  7638. {
  7639. int idx = GetHiddenSelectionIndex("decay_preload");
  7640. if (idx > -1)
  7641. SetObjectTexture(idx, m_DecayedTexture);
  7642. }
  7643. void SetLastMapInfo(float scale, vector pos)
  7644. {
  7645. m_LastMapScale = scale;
  7646. m_LastMapPos = pos;
  7647. }
  7648. bool GetLastMapInfo(out float scale, out vector pos)
  7649. {
  7650. scale = m_LastMapScale;
  7651. pos = m_LastMapPos;
  7652. return m_LastMapScale != -1.0;
  7653. }
  7654. override bool PhysicalPredictiveDropItem(EntityAI entity, bool heavy_item_only = true)
  7655. {
  7656. vector dir;
  7657. ItemBase item = ItemBase.Cast(entity);
  7658. //! from hands
  7659. if (GetItemInHands() == item)
  7660. {
  7661. return PredictiveDropEntity(item);
  7662. }
  7663. else
  7664. {
  7665. ActionManagerClient actionManager = ActionManagerClient.Cast(m_ActionManager);
  7666. if (actionManager)
  7667. {
  7668. ActionTarget actionTarget = new ActionTarget(null, null, -1, vector.Zero, -1);
  7669. if (actionManager.GetAction(ActionDropItemSimple).Can(this, actionTarget, item))
  7670. {
  7671. actionManager.PerformActionStart(actionManager.GetAction(ActionDropItemSimple), actionTarget, item);
  7672. return true;
  7673. }
  7674. }
  7675. else
  7676. return true;
  7677. }
  7678. return false;
  7679. }
  7680. override void SetProcessUIWarning(bool state)
  7681. {
  7682. m_ProcessUIWarning = state;
  7683. }
  7684. void dmgDebugPrint(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
  7685. {
  7686. /*Print("ProjectileDebugging | Damage Health: " + damageResult.GetDamage(dmgZone,"Health") + " | Component: " + component + " | Zone: " + dmgZone + "| Timestamp: " + GetSimulationTimeStamp());
  7687. Print("ProjectileDebugging | speedCoef: " + speedCoef);
  7688. Print("ProjectileDebugging | GetWorldTime(): " + GetWorldTime());
  7689. Print("-----------------------------------------------");*/
  7690. }
  7691. //Use this method to process additionnal dmg to legs specifically (must use the dmg system to fire relevant events)
  7692. //Legzone is a dummy to inflict damage once and NOT transfer damage to other zones. All leg zones will drop to 0 anyway
  7693. void DamageAllLegs(float inputDmg)
  7694. {
  7695. array<string> legZones = new array<string>;
  7696. legZones.Insert("LeftLeg");
  7697. legZones.Insert("RightLeg");
  7698. legZones.Insert("RightFoot");
  7699. legZones.Insert("LeftFoot");
  7700. foreach (string legZone : legZones)
  7701. DecreaseHealth(legZone, "", inputDmg);
  7702. }
  7703. //! tries to hide item in player's hands, some exceptions for various movement states
  7704. void TryHideItemInHands(bool hide, bool force = false)
  7705. {
  7706. if (!hide && ((!IsSwimming() && !IsClimbingLadder() && !IsInVehicle() && !AnimCommandCheck(HumanMoveCommandID.CommandSwim | HumanMoveCommandID.CommandLadder | HumanMoveCommandID.CommandVehicle)) || force))
  7707. {
  7708. GetItemAccessor().HideItemInHands(false);
  7709. }
  7710. else
  7711. {
  7712. GetItemAccessor().HideItemInHands(true);
  7713. }
  7714. }
  7715. //!
  7716. bool CheckAndExecuteStackSplit(FindInventoryLocationType flags, notnull EntityAI item, notnull EntityAI target)
  7717. {
  7718. float stackable = item.GetTargetQuantityMax();
  7719. if (!(stackable == 0 || stackable >= item.GetQuantity()))
  7720. {
  7721. InventoryLocation il = new InventoryLocation;
  7722. if (target && target.GetInventory().FindFreeLocationFor(item, flags, il))
  7723. {
  7724. ItemBase itemB;
  7725. if (CastTo(itemB, item))
  7726. {
  7727. itemB.SplitIntoStackMaxToInventoryLocationClient(il);
  7728. return true;
  7729. }
  7730. }
  7731. }
  7732. return false;
  7733. }
  7734. bool CheckAndExecuteStackSplitToInventoryLocation(InventoryLocation il, notnull EntityAI item)
  7735. {
  7736. float stackable = item.GetTargetQuantityMax();
  7737. if (!(stackable == 0 || stackable >= item.GetQuantity()))
  7738. {
  7739. ItemBase itemB;
  7740. if (CastTo(itemB, item))
  7741. {
  7742. itemB.SplitIntoStackMaxToInventoryLocationClient(il);
  7743. return true;
  7744. }
  7745. }
  7746. return false;
  7747. }
  7748. override protected bool TakeEntityToInventoryImpl(InventoryMode mode, FindInventoryLocationType flags, notnull EntityAI item)
  7749. {
  7750. if (CheckAndExecuteStackSplit(flags, item, this))
  7751. {
  7752. if (LogManager.IsSyncLogEnable()) syncDebugPrint("[inv] " + GetDebugName(this) + " STS=" + GetSimulationTimeStamp() + " Take2Inv(SPLIT) item=" + GetDebugName(item));
  7753. return true;
  7754. }
  7755. return super.TakeEntityToInventoryImpl(mode, flags, item);
  7756. }
  7757. override protected bool TakeEntityToCargoImpl(InventoryMode mode, notnull EntityAI item)
  7758. {
  7759. if (CheckAndExecuteStackSplit(FindInventoryLocationType.CARGO, item, this))
  7760. {
  7761. if (LogManager.IsSyncLogEnable()) syncDebugPrint("[inv] " + GetDebugName(this) + " STS=" + GetSimulationTimeStamp() + " Take2Cgo(SPLIT) item=" +GetDebugName(item));
  7762. return true;
  7763. }
  7764. return super.TakeEntityToCargoImpl(mode, item);
  7765. }
  7766. override protected bool TakeEntityAsAttachmentImpl(InventoryMode mode, notnull EntityAI item)
  7767. {
  7768. if (CheckAndExecuteStackSplit(FindInventoryLocationType.ATTACHMENT, item, this))
  7769. {
  7770. if (LogManager.IsSyncLogEnable()) syncDebugPrint("[inv] " + GetDebugName(this) + " STS=" + GetSimulationTimeStamp() + " Take2Att(SPLIT) item=" + GetDebugName(item));
  7771. return true;
  7772. }
  7773. return super.TakeEntityAsAttachmentImpl(mode, item);
  7774. }
  7775. override void TakeEntityToHandsImpl(InventoryMode mode, EntityAI item)
  7776. {
  7777. if (CheckAndExecuteStackSplit(FindInventoryLocationType.HANDS, item, this))
  7778. {
  7779. if (LogManager.IsSyncLogEnable()) syncDebugPrint("[inv] " + GetDebugName(this) + " STS=" + GetSimulationTimeStamp() + " Take2Hands(SPLIT) item=" + GetDebugName(item));
  7780. return;
  7781. }
  7782. super.TakeEntityToHandsImpl(mode, item);
  7783. }
  7784. override protected bool TakeEntityToTargetInventoryImpl(InventoryMode mode, notnull EntityAI target, FindInventoryLocationType flags, notnull EntityAI item)
  7785. {
  7786. if (CheckAndExecuteStackSplit(flags, item, target))
  7787. {
  7788. if (LogManager.IsSyncLogEnable()) syncDebugPrint("[inv] " + GetDebugName(this) + " STS=" + GetSimulationTimeStamp() + " Take2TargetInv(SPLIT) item=" + GetDebugName(item));
  7789. return true;
  7790. }
  7791. return super.TakeEntityToTargetInventoryImpl(mode, target, flags, item);
  7792. }
  7793. override protected bool TakeEntityToTargetCargoImpl(InventoryMode mode, notnull EntityAI target, notnull EntityAI item)
  7794. {
  7795. if (CheckAndExecuteStackSplit(FindInventoryLocationType.CARGO, item, target))
  7796. {
  7797. if (LogManager.IsSyncLogEnable()) syncDebugPrint("[inv] " + GetDebugName(this) + " STS=" + GetSimulationTimeStamp() + " Take2TargetCgo(SPLIT) item=" + GetDebugName(item));
  7798. return true;
  7799. }
  7800. return super.TakeEntityToTargetCargoImpl(mode, target, item);
  7801. }
  7802. override protected bool TakeEntityToTargetAttachmentImpl(InventoryMode mode, notnull EntityAI target, notnull EntityAI item)
  7803. {
  7804. if (CheckAndExecuteStackSplit(FindInventoryLocationType.ATTACHMENT, item, target))
  7805. {
  7806. if (LogManager.IsSyncLogEnable()) syncDebugPrint("[inv] " + GetDebugName(this) + " STS=" + GetSimulationTimeStamp() + " Take2TargetAtt(SPLIT) item=" + GetDebugName(item));
  7807. return true;
  7808. }
  7809. return super.TakeEntityToTargetAttachmentImpl(mode, target, item);
  7810. }
  7811. override protected bool TakeToDstImpl(InventoryMode mode, notnull InventoryLocation src, notnull InventoryLocation dst)
  7812. {
  7813. if (CheckAndExecuteStackSplitToInventoryLocation(dst, dst.GetItem()))
  7814. {
  7815. if (LogManager.IsSyncLogEnable()) syncDebugPrint("[inv] " + GetDebugName(this) + " STS=" + GetSimulationTimeStamp() + " Take2Dst(SPLIT) item=" + GetDebugName(dst.GetItem()));
  7816. return true;
  7817. }
  7818. return super.TakeToDstImpl(mode, src, dst);
  7819. }
  7820. override vector GetCenter()
  7821. {
  7822. return GetBonePositionWS(GetBoneIndexByName("spine3"));
  7823. }
  7824. // contaminated areas - temp stuff
  7825. void ContaminatedParticleAdjustment()
  7826. {
  7827. if (GetCommand_Move() && m_ContaminatedAroundPlayer && m_ContaminatedAroundPlayerTiny)
  7828. {
  7829. float playerSpeed = GetCommand_Move().GetCurrentMovementSpeed();
  7830. //Print(playerSpeed);
  7831. // 1 - prone, crouch
  7832. // 2 - jog
  7833. // 3 - sprint
  7834. float particleLifetime = 5.25;
  7835. float particleSpeed = 0.25;
  7836. if (playerSpeed >= 1)
  7837. {
  7838. particleLifetime = 3.5;
  7839. particleSpeed = 3.25;
  7840. }
  7841. if (playerSpeed >= 2)
  7842. {
  7843. particleLifetime = 2.5;
  7844. particleSpeed = 5.25;
  7845. }
  7846. if (playerSpeed >= 3)
  7847. {
  7848. particleLifetime = 1.5;
  7849. particleSpeed = 8.25;
  7850. }
  7851. m_ContaminatedAroundPlayer.SetParameter(0, EmitorParam.LIFETIME, particleLifetime);
  7852. m_ContaminatedAroundPlayer.SetParameter(1, EmitorParam.LIFETIME, particleLifetime);
  7853. m_ContaminatedAroundPlayer.SetParameter(2, EmitorParam.LIFETIME, particleLifetime);
  7854. m_ContaminatedAroundPlayer.SetParameter(3, EmitorParam.LIFETIME, particleLifetime);
  7855. m_ContaminatedAroundPlayerTiny.SetParameter(0, EmitorParam.VELOCITY, particleSpeed);
  7856. vector transform[4];
  7857. GetTransform(transform);
  7858. m_ContaminatedAroundPlayer.SetTransform(transform);
  7859. m_ContaminatedAroundPlayerTiny.SetTransform(transform);
  7860. }
  7861. }
  7862. void HandleGlassesEffect()
  7863. {
  7864. if (!IsControlledPlayer())
  7865. return;
  7866. int i;
  7867. if (m_ProcessRemoveGlassesEffects)
  7868. {
  7869. for (i = 0; i < m_ProcessRemoveGlassesEffects.Count(); i++)
  7870. {
  7871. PPERequesterBank.GetRequester(m_ProcessRemoveGlassesEffects[i]).Stop();
  7872. }
  7873. m_ProcessRemoveGlassesEffects.Clear();
  7874. }
  7875. if (m_ProcessAddGlassesEffects)
  7876. {
  7877. for (i = 0; i < m_ProcessAddGlassesEffects.Count(); i++)
  7878. {
  7879. PPERequesterBank.GetRequester(m_ProcessAddGlassesEffects[i]).Start();
  7880. }
  7881. m_ProcessAddGlassesEffects.Clear();
  7882. }
  7883. }
  7884. override void AddArrow(Object arrow, int componentIndex, vector closeBonePosWS, vector closeBoneRotWS)
  7885. {
  7886. CachedObjectsArrays.ARRAY_STRING.Clear();
  7887. GetActionComponentNameList(componentIndex, CachedObjectsArrays.ARRAY_STRING, LOD.NAME_FIRE);
  7888. int pivot = componentIndex;
  7889. int newPivot = -1;
  7890. string compName;
  7891. for (int i = 0; i < CachedObjectsArrays.ARRAY_STRING.Count() && newPivot == -1; i++)
  7892. {
  7893. compName = CachedObjectsArrays.ARRAY_STRING.Get(i);
  7894. newPivot = GetBoneIndexByName(compName);
  7895. }
  7896. if (newPivot != -1)
  7897. {
  7898. pivot = newPivot;
  7899. }
  7900. vector parentTransMat[4];
  7901. vector arrowTransMat[4];
  7902. arrow.GetTransform(arrowTransMat);
  7903. if (pivot == -1)
  7904. {
  7905. GetTransformWS(parentTransMat);
  7906. }
  7907. else
  7908. {
  7909. vector rotMatrix[3];
  7910. Math3D.YawPitchRollMatrix(closeBoneRotWS * Math.RAD2DEG,rotMatrix);
  7911. parentTransMat[0] = rotMatrix[0];
  7912. parentTransMat[1] = rotMatrix[1];
  7913. parentTransMat[2] = rotMatrix[2];
  7914. parentTransMat[3] = closeBonePosWS;
  7915. }
  7916. Math3D.MatrixInvMultiply4(parentTransMat, arrowTransMat, arrowTransMat);
  7917. Math3D.MatrixOrthogonalize4(arrowTransMat);
  7918. arrow.SetTransform(arrowTransMat);
  7919. AddChild(arrow, pivot);
  7920. #ifdef SERVER
  7921. // creating bleeding source
  7922. BleedingSourcesManagerServer bleedingManager = GetBleedingManagerServer();
  7923. if (bleedingManager)
  7924. {
  7925. if (!bleedingManager.AttemptAddBleedingSourceBySelection(compName))
  7926. bleedingManager.AttemptAddBleedingSourceBySelection("Pelvis");//fallback, if we can't attach bleeding source to the fallback location because there already is another one, it's fine, we are just trying make sure there is at least one
  7927. }
  7928. #endif
  7929. }
  7930. override bool IsManagingArrows()
  7931. {
  7932. return true;
  7933. }
  7934. string GetCachedName()
  7935. {
  7936. return m_CachedPlayerName;
  7937. }
  7938. string GetCachedID()
  7939. {
  7940. return m_CachedPlayerID;
  7941. }
  7942. override void OnFreezeStateChangeClient()
  7943. {
  7944. super.OnFreezeStateChangeClient();
  7945. UpdateCorpseState();
  7946. }
  7947. bool HasHeatBuffer()
  7948. {
  7949. return m_HasHeatBuffer;
  7950. }
  7951. int GetHeatBufferStage()
  7952. {
  7953. return m_HeatBufferStage;
  7954. }
  7955. //! ----------
  7956. //! DEPRECATED
  7957. //! ----------
  7958. static ref array<Object> SPREAD_AGENTS_OBJECTS = new array<Object>;
  7959. static ref array<CargoBase> SPREAD_AGENTS_PROXY_CARGOS = new array<CargoBase>;
  7960. private int m_FaceCoveredForShaveLayers = 0;
  7961. int m_AntibioticsActive;
  7962. void SwitchItemTypeAttach(EntityAI item, string slot)
  7963. {
  7964. if (!GetGame().IsServer())
  7965. return;
  7966. }
  7967. void SwitchItemTypeDetach(EntityAI item, string slot);
  7968. void AddToEnvironmentTemperature(float pTemperature);
  7969. void IncreaseAntibioticsCount()
  7970. {
  7971. AddMedicalDrugsInUse(EMedicalDrugsType.ANTIBIOTICS);
  7972. }
  7973. void DecreaseAntibioticsCount()
  7974. {
  7975. RemoveMedicalDrugsInUse(EMedicalDrugsType.ANTIBIOTICS);
  7976. }
  7977. bool HasStaminaRemaining()
  7978. {
  7979. if (!GetStaminaHandler())
  7980. return false;
  7981. return GetStaminaHandler().GetStamina() > 0;
  7982. }
  7983. }
  7984. #ifdef DEVELOPER
  7985. PlayerBase _player;
  7986. #endif