1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269 |
- /******************************************************************************
- *******************************************************************************/
- // Player intelligence and decision making routines...
- /******************************************************************************
- *****************************************************************************/
- #include "global.h"
- #include "defines.h"
- #include "externs.h"
- #include "data.h"
- #include "audio.h" // Kev's audio calls.
- #include "front.h"
- #include "eurofrnt\euro_int.h"
- extern match_data match_info;
- extern team_info game_data[];
- extern float save_offs[];
- extern setup_info setup;
- extern stad_info stadlist[];
- extern void reselect_a();
- extern void reselect_b();
- /******************************************************************************
- *****************************************************************************/
- // Intelligence Flags and Variables...
- char cross_on=FALSE;
- /******************************************************************************
- *****************************************************************************/
- short get_there_time(int p_num,float x,float y)
- {
- stop_and_face=FALSE;
- must_face_time=0;
- int t1=0;
- int t2=0;
- int mft1=0;
- int mft2=0;
- int t;
- int mft;
- float d;
- float rate=full_spd(&teams[p_num-1]); // Running speed!
- float px,py;
- px=teams[p_num-1].tm_x;
- py=teams[p_num-1].tm_y;
- x=x-px;
- y=y-py; // Offset.
- float sx=x;
- float sy=y;
- float xd=teams[p_num-1].tm_xdis;
- float yd=teams[p_num-1].tm_ydis; //Current facing dir.
- float max=MAX_TURN2;
- float old_max=max;
- float cmax=cos(max);
- float ox,oy,a,turn_spd,last_a;
- // Player must have ball slightly
- if (teams[p_num-1].tm_act<=TURN_ACT)
- {
- // Can i turn on the spot?
- a=angle_to_xy(x,y,xd,yd);
- t1=ABS(acos(a)/max); // time to turn!
- // Time to go straight to point...
- d=calc_dist(x,y);
- t1+=d/rate+1;
- if (must_face)
- {
- // User forced to face in a particular direction (after getting to target)...
- a=angle_to_xy(must_face_x,must_face_y,x/d,y/d);
- mft1=ABS(acos(a)/max)+1; // time to turn!
- }
- }
- else
- t1=2000;
- a=angle_to_xy(x,y,xd,yd);
- last_a=a;
- d=calc_dist(x,y);
- // Time to get to target point...
- for (int i=0; i<50; i++)
- {
- // Init run...
- if (d<IM_THERE_DIST)
- break;
- else
- t2++;
- // Go forward...
- turn_spd=(1.0+a)/2;
- x-=xd*rate*turn_spd; // Move on...
- y-=yd*rate*turn_spd;
- // Turn...
- d=calc_dist(x,y);
- ox=xd;
- oy=yd;
- max=old_max;
- if (a<cmax)
- {
- // Need to turn...
- if ((x*oy/d)>(y*ox/d))
- max=-max;
- xd=(ox*cos(max))-(oy*sin(max));
- yd=(oy*cos(max))+(ox*sin(max));
- }
- else
- {
- // Final turn...
- // xd=x/d;
- // yd=y/d;
- t2+=d/rate;
- if (d-((t2-1)*rate)>.1)
- t2++;
- break;
- }
- last_a=a;
- a=angle_to_xy(x,y,xd,yd);
- if (last_a>a)
- // Getting further forget it!
- {
- t2=2000;
- break; // (exit)
- }
- }
- if (i>50)
- t=2000; // Could not find intersection!
- if (must_face)
- {
- // User forced to face in a particular direction (after getting to target)...
- a=angle_to_xy(must_face_x,must_face_y,xd,yd);
- mft2=ABS(acos(a)/max)+1; // time to turn!
- }
- if ((t1+mft1)<(t2+mft2))
- {
- // Rotate and run...
- t=t1+mft1;
- mft=mft1;
- d=calc_dist(sx,sy);
- x_face=sx/d; // New dir...
- y_face=sy/d;
- stop_and_face=TRUE;
- }
- else
- {
- // Turn and run...
- t=t2+mft2;
- mft=mft2;
- x_face=x/d; // New dir...
- y_face=y/d;
- }
- if (must_face)
- {
- x_face=must_face_x;
- y_face=must_face_y;
- must_face_time=mft;
- }
- return(t);
- }
- /******************************************************************************
- *****************************************************************************/
- short get_facing_opp_dir(match_player *player)
- {
- /*
- Output: 1 = Side On.
- -1 = Behind.
- 0 = Face On.
- */
- int d=get_dir(ballx-player->tm_x,bally-player->tm_y);
- // Direction to ball!
- int opp=teams[ball_poss-1].face_dir;
- if (opp==d)
- return(-1);
- d=d-opp;
- if (d<0)
- d+=8;
- if ((d==1) || (d==7))
- return(-1);
-
- if ((d==2) || (d==6))
- return(1);
- else
- return(0);
- }
- /******************************************************************************
- *****************************************************************************/
- char thinking(match_player *player)
- {
- int f=(130-player->tm_flair)/2;
- int t=logic_cnt/f;
- int r=logic_cnt-(t*f);
- return(!r);
- }
- /******************************************************************************
- *****************************************************************************/
- char plr_facing(float x,float y,match_player *player)
- {
- float xd=player->tm_xdis;
- float yd=player->tm_ydis;
- float d=calc_dist(x,y);
- float a=((x*xd)+(y*yd))/d;
- if (a>FACING_ANGLE) // 5 degrees!
- return(TRUE);
- else
- return(FALSE);
- }
- /******************************************************************************
- *****************************************************************************/
- char plr_facing_goal(float x,float y,match_player *player)
- {
- // Is the player facing between the goal posts of goal(x,y)?
- float xd=player->tm_xdis;
- float yd=player->tm_ydis;
- if ((x>0 && xd<0) || (x<0 && xd>0))
- return(FALSE);
- float yt;
- if (user_controlled)
- yt=(top_post_y-prat*6)-player->tm_y;
- else
- yt=top_post_y-player->tm_y;
- float d=calc_dist(x,yt);
- float xt=x/d;
- yt=yt/d;
- float yb;
- if (user_controlled)
- yb=(bot_post_y+prat*6)-player->tm_y;
- else
- yb=bot_post_y-player->tm_y;
- d=calc_dist(x,yb);
- float xb=x/d;
- yb=yb/d;
- char dir=0;
- if ((xt*yd)>(yt*xd))
- dir=TRUE;
- if ((xb*yd)>(yb*xd))
- {
- if (dir)
- return(FALSE);
- else
- return(TRUE);
- }
- else
- {
- if (dir)
- return(TRUE);
- else
- return(FALSE);
- }
- return(FALSE);
- }
- /******************************************************************************
- *****************************************************************************/
- void run_back(match_player *player)
- {
- player->tm_off=-2;
- if (player->tm_player<12)
- // Team A...
- {
- init_run_act(player,defense_b-(prat*3),player->tm_y,TRUE);
- }
- else
- // Team B...
- {
- init_run_act(player,defense_a+(prat*3),player->tm_y,TRUE);
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void keeper_boxes()
- {
- if ((teams[KP_A-1].tm_x>(prat*16)) || (teams[KP_A-1].tm_y>(cntspot_y+(19*prat)))
- || (teams[KP_A-1].tm_y<(cntspot_y-(19*prat))) || (teams[KP_A-1].tm_x<0))
- keeper_a_in_box=FALSE;
- else
- keeper_a_in_box=TRUE;
- if ((teams[KP_B-1].tm_x<pitch_len-(prat*16)) || (teams[KP_B-1].tm_y>(cntspot_y+(19*prat)))
- || (teams[KP_B-1].tm_y<(cntspot_y-(19*prat))) || (teams[KP_B-1].tm_x>pitch_len))
- keeper_b_in_box=FALSE;
- else
- keeper_b_in_box=TRUE;
- }
- /******************************************************************************
- *****************************************************************************/
- void reset_ideas(match_player *player)
- {
- player->tm_strike=FALSE;
- player->special=FALSE;
- player->tm_z=0;
- if (player->int_move!=I_OFF)
- {
- if ((player->int_move==I_INTERCEPT) && (player->tm_act==RUN_ACT))
- player->go_cnt=1; // Stop running!
- if (player->int_move==I_RUN_ON)
- {
- want_pass=0;
- player->int_move=0;
- player->int_cnt=0;
- }
- if (player->int_cnt)
- {
- if (player->tm_player==interceptor_a)
- interceptor_a=0;
- if (player->tm_player==interceptor_b)
- interceptor_b=0;
- player->int_move=0;
- player->int_cnt=0;
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void reset_all_ideas()
- {
- for (int i=0; i<players; i++)
- {
- reset_ideas(&teams[i]);
- teams[i].tm_leave=FALSE;
- }
- keep_dive=FALSE;
- }
- /******************************************************************************
- *****************************************************************************/
- void reset_leaves()
- {
- for (int i=0; i<players; i++)
- {
- teams[i].tm_leave=FALSE;
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void save_in_zone_a(match_player *player,float x,float y,float z,int bp,char forced)
- {
- float factor;
- keeper_on_grnd=FALSE;
- keeper_will_save=TRUE;
- int zone=1;
- if (z<SAVE_FEET_HGT)
- // Feet level...
- {
- if (bp<=SAVE_AFOOTB_TIME/keeper_spd && !keep_dive)
- {
- keeper_contact=MCC_AFOOTB;
- factor=1./((float)bp/(SAVE_AFOOTB_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_AFOOTB_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=TRUE;
- init_save_act(player,x,y,z,MC_AFOOTB,zone,bp,(int)(SAVE_AFOOTB_TIME/keeper_spd));
- }
- else
- if (bp<=SAVE_AFOOTC_TIME/keeper_spd || keep_dive)
- {
- keeper_contact=MCC_AFOOTC;
- factor=1./((float)bp/(SAVE_AFOOTC_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_AFOOTC_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=FALSE;
- keeper_on_grnd=TRUE;
- init_save_act(player,x,y,z,MC_AFOOTC,zone,bp,(int)(SAVE_AFOOTC_TIME/keeper_spd));
- }
- else
- // Move to best position...
- {
- shot_acknowledged=1;
- }
- }
- else
- if (z<SAVE_CHEST_HGT)
- // Chest level...
- {
- if (bp<=SAVE_ABODYB_TIME/keeper_spd && !keep_dive)
- {
- keeper_contact=MCC_ABODYB;
- factor=1./((float)bp/(SAVE_ABODYB_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_ABODYB_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=TRUE;
- init_save_act(player,x,y,z,MC_ABODYB,zone,bp,(int)(SAVE_ABODYB_TIME/keeper_spd));
- }
- else
- if (bp<=SAVE_ABODYC_TIME/keeper_spd || keep_dive)
- {
- keeper_contact=MCC_ABODYC;
- factor=1./((float)bp/(SAVE_ABODYC_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_ABODYC_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=FALSE;
- init_save_act(player,x,y,z,MC_ABODYC,zone,bp,(int)(SAVE_ABODYC_TIME/keeper_spd));
- }
- else
- // Move to best position...
- {
- shot_acknowledged=1;
- }
- }
- else
- if (z<SAVE_HEAD_HGT)
- // Head level...
- {
- if (bp<=SAVE_AHEADB_TIME/keeper_spd && !keep_dive)
- {
- keeper_contact=MCC_AHEADB;
- factor=1./((float)bp/(SAVE_AHEADB_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_AHEADB_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=TRUE;
- init_save_act(player,x,y,z,MC_AHEADB,zone,bp,(int)(SAVE_AHEADB_TIME/keeper_spd));
- }
- else
- if (bp<=SAVE_AHEADC_TIME/keeper_spd || keep_dive)
- {
- keeper_contact=MCC_AHEADC;
- factor=1./((float)bp/(SAVE_AHEADC_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_AHEADC_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=FALSE;
- init_save_act(player,x,y,z,MC_AHEADC,zone,bp,(int)(SAVE_AHEADC_TIME/keeper_spd));
- }
- else
- // Move to best position...
- {
- shot_acknowledged=1;
- }
- }
- else
- if (z<SAVE_JUMP_HGT)
- // Above head level...
- {
- if (bp<=SAVE_AJUMPB_TIME/keeper_spd && !keep_dive)
- {
- keeper_contact=MCC_AJUMPB;
- factor=1./((float)bp/(SAVE_AJUMPB_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_AJUMPB_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=TRUE;
- init_save_act(player,x,y,z,MC_AJUMPB,zone,bp,(int)(SAVE_AJUMPB_TIME/keeper_spd));
- }
- else
- if (bp<=SAVE_AJUMPC_TIME/keeper_spd || keep_dive)
- {
- keeper_contact=MCC_AJUMPC;
- factor=1./((float)bp/(SAVE_AJUMPC_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_AJUMPC_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=FALSE;
- init_save_act(player,x,y,z,MC_AJUMPC,zone,bp,(int)(SAVE_AJUMPC_TIME/keeper_spd));
- }
- else
- // Move to best position...
- {
- shot_acknowledged=1;
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void save_in_zone_b(match_player *player,float x,float y,float z,int bp,char forced)
- {
- float factor;
- keeper_on_grnd=FALSE;
- keeper_will_save=TRUE;
- int zone=2;
- if (z<SAVE_FEET_HGT)
- // Feet level...
- {
- if (bp<=SAVE_BFOOTB_TIME/keeper_spd && !keep_dive)
- {
- keeper_contact=MCC_BFOOTB;
- factor=1./((float)bp/(SAVE_BFOOTB_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_BFOOTB_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=TRUE;
- init_save_act(player,x,y,z,MC_BFOOTBL,zone,bp,(int)(SAVE_BFOOTB_TIME/keeper_spd));
- }
- else
- if (bp<=SAVE_BFOOTC_TIME/keeper_spd || keep_dive)
- {
- keeper_contact=MCC_BFOOTC;
- factor=1./((float)bp/(SAVE_BFOOTC_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_BFOOTC_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=FALSE;
- keeper_on_grnd=TRUE;
- init_save_act(player,x,y,z,MC_BFOOTCL,zone,bp,(int)(SAVE_BFOOTC_TIME/keeper_spd));
- }
- else
- // Move to best position...
- {
- shot_acknowledged=1;
- }
- }
- else
- if (z<SAVE_CHEST_HGT)
- // Chest level...
- {
- if (bp<=SAVE_BBODYB_TIME/keeper_spd && !keep_dive)
- {
- keeper_contact=MCC_BBODYB;
- factor=1./((float)bp/(SAVE_BBODYB_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_BBODYB_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=TRUE;
- keeper_on_grnd=TRUE;
- init_save_act(player,x,y,z,MC_BBODYBL,zone,bp,(int)(SAVE_BBODYB_TIME/keeper_spd));
- }
- else
- if (bp<=SAVE_BBODYC_TIME/keeper_spd || keep_dive)
- {
- keeper_contact=MCC_BBODYC;
- factor=1./((float)bp/(SAVE_BBODYC_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_BBODYC_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=FALSE;
- keeper_on_grnd=TRUE;
- init_save_act(player,x,y,z,MC_BBODYCL,zone,bp,(int)(SAVE_BBODYC_TIME/keeper_spd));
- }
- else
- // Move to best position...
- {
- shot_acknowledged=1;
- }
- }
- else
- if (z<SAVE_HEAD_HGT)
- // Head level...
- {
- if (bp<=SAVE_BHEADB_TIME/keeper_spd && !keep_dive)
- {
- keeper_contact=MCC_BHEADB;
- factor=1./((float)bp/(SAVE_BHEADB_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_BHEADB_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=TRUE;
- init_save_act(player,x,y,z,MC_BHEADBL,zone,bp,(int)(SAVE_BHEADB_TIME/keeper_spd));
- }
- else
- if (bp<=SAVE_BHEADC_TIME/keeper_spd || keep_dive)
- {
- keeper_contact=MCC_BHEADC;
- factor=1./((float)bp/(SAVE_BHEADC_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_BHEADC_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=FALSE;
- init_save_act(player,x,y,z,MC_BHEADCL,zone,bp,(int)(SAVE_BHEADC_TIME/keeper_spd));
- }
- else
- // Move to best position...
- {
- shot_acknowledged=1;
- }
- }
- else
- if (z<SAVE_JUMP_HGT)
- // Above head level...
- {
- if (bp<=SAVE_BJUMPB_TIME/keeper_spd && !keep_dive)
- {
- keeper_contact=MCC_BJUMPB;
- factor=1./((float)bp/(SAVE_BJUMPB_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_BJUMPB_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=TRUE;
- init_save_act(player,x,y,z,MC_BJUMPBL,zone,bp,(int)(SAVE_BJUMPB_TIME/keeper_spd));
- }
- else
- // Move to best position...
- {
- shot_acknowledged=1;
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void save_in_zone_c(match_player *player,float x,float y,float z,int bp,char forced)
- {
- float factor;
- keeper_will_save=TRUE;
- keeper_on_grnd=FALSE;
- int zone=3;
- if (z<SAVE_FEET_HGT)
- // Feet level...
- {
- if (bp<=SAVE_CFOOTB_TIME/keeper_spd && !keep_dive)
- {
- keeper_contact=MCC_CFOOTB;
- factor=1./((float)bp/(SAVE_CFOOTB_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_CFOOTB_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=TRUE;
- keeper_on_grnd=TRUE;
- init_save_act(player,x,y,z,MC_CFOOTBL,zone,bp,(int)(SAVE_CFOOTB_TIME/keeper_spd));
- }
- else
- if (bp<=SAVE_CFOOTC_TIME/keeper_spd || keep_dive)
- {
- keeper_contact=MCC_CFOOTC;
- factor=1./((float)bp/(SAVE_CFOOTC_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_CFOOTC_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=FALSE;
- keeper_on_grnd=TRUE;
- init_save_act(player,x,y,z,MC_CFOOTCL,zone,bp,(int)(SAVE_CFOOTC_TIME/keeper_spd));
- }
- else
- // Move to best position...
- {
- shot_acknowledged=1;
- }
- }
- else
- if (z<SAVE_CHEST_HGT)
- // Chest level...
- {
- if (bp<=SAVE_CBODYB_TIME/keeper_spd && !keep_dive)
- {
- keeper_contact=MCC_CBODYB;
- factor=1./((float)bp/(SAVE_CBODYB_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_CBODYB_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=TRUE;
- keeper_on_grnd=TRUE;
- init_save_act(player,x,y,z,MC_CBODYBL,zone,bp,(int)(SAVE_CBODYB_TIME/keeper_spd));
- }
- else
- if (bp<=SAVE_CBODYC_TIME/keeper_spd || keep_dive)
- {
- keeper_contact=MCC_CBODYC;
- factor=1./((float)bp/(SAVE_CBODYC_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_CBODYC_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=FALSE;
- keeper_on_grnd=TRUE;
- init_save_act(player,x,y,z,MC_CBODYCL,zone,bp,(int)(SAVE_CBODYC_TIME/keeper_spd));
- }
- else
- // Move to best position...
- {
- shot_acknowledged=1;
- }
- }
- else
- if (z<SAVE_HEAD_HGT)
- // Head level...
- {
- if (bp<=SAVE_CHEADB_TIME/keeper_spd && !keep_dive)
- {
- keeper_contact=MCC_CHEADB;
- factor=1./((float)bp/(SAVE_CHEADB_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_CHEADB_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=TRUE;
- init_save_act(player,x,y,z,MC_CHEADBL,zone,bp,(int)(SAVE_CHEADB_TIME/keeper_spd));
- }
- else
- // Move to best position...
- {
- shot_acknowledged=1;
- }
- }
- else
- if (z<SAVE_JUMP_HGT)
- // Above head level...
- {
- if (bp<=SAVE_CJUMPB_TIME/keeper_spd || keep_dive)
- {
- keeper_contact=MCC_CJUMPB;
- factor=1./((float)bp/(SAVE_CJUMPB_TIME/keeper_spd));
- if (factor>max_kp_margin && !forced)
- {
- // Ball is too fast!
- factor=max_kp_margin;
- keeper_will_save=FALSE;
- player->tm_fstep=MC_CJUMPB_FS*factor*keeper_spd;
- }
- else
- player->tm_fstep=keeper_contact/bp;
- if (player->tm_fstep>=1)
- player->tm_fstep=1;
- save_block=TRUE;
- init_save_act(player,x,y,z,MC_CJUMPBL,zone,bp,(int)(SAVE_CJUMPB_TIME/keeper_spd));
- }
- else
- // Move to best position...
- {
- shot_acknowledged=1;
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- // Send keeper to point between centre of goal and ball!
- // Point ratio between goal and ball varies with distance to ball.
- // i.e. If opponent is close then point will be further from goal.
- void close_angle(match_player *player,float d,float &x,float &y)
- {
- float gx,gd,cd;
- cd=CLOSE_ANG_DIST+(prat*player->tm_vis)/8;
- if (player->tm_player<12)
- // Keeper A...
- gx=0;
- else
- // Keeper B...
- gx=pitch_len;
- gd=prat+(d*((cd-d)/cd)); // How far target point is along line.
- x=gx+((ballx-gx)*gd/d);
- y=cntspot_y+((bally-cntspot_y)*gd/d);
- }
- /******************************************************************************
- *****************************************************************************/
- char target_towards_ball(float tx,float ty,float px,float py)
- {
- // Get distance of target to present ball pos.
- float d=calc_dist(tx-ballx,ty-bally);
- if (d<=calc_dist(px-ballx,py-bally))
- return(TRUE); // Player is further from ball than target!
- return(FALSE);
- }
- /******************************************************************************
- *****************************************************************************/
- void init_user_save(match_player *player)
- {
- int t;
- float dist=prat*1.4;
- keeper_will_save=FALSE;
- save_block=TRUE;
- reset_ideas(player);
- if (save_direction)
- {
- // Direction selected...
- if (save_direction>0)
- {
- // Raw Left...
- if (match_mode==PEN_KICK_A)
- {
- // Dive Right and Up-field...
- init_anim(player,MC_CBODYBR);
- t=(SAVE_BBODYB_TIME/keeper_spd);
- dist=-dist;
- }
- else
- {
- // Dive Right and Down-field...
- init_anim(player,MC_CBODYBR);
- t=(SAVE_BBODYB_TIME/keeper_spd);
- }
- }
- else
- {
- // Raw Right...
- if (match_mode==PEN_KICK_A)
- {
- // Dive Left and Down-field...
- init_anim(player,MC_CBODYBL);
- t=(SAVE_BBODYB_TIME/keeper_spd);
- }
- else
- {
- // Dive Left and Up-field...
- init_anim(player,MC_CBODYBL);
- t=(SAVE_BBODYB_TIME/keeper_spd);
- dist=-dist;
- }
- }
- }
- else
- {
- init_anim(player,MC_ABODYB);
- t=(SAVE_ABODYB_TIME/keeper_spd);
- dist=0;
- }
- player->go_tx=player->tm_x;
- player->go_ty=player->tm_y+dist;
- player->go_txdis=0;
- player->go_tydis=dist/t;
- player->go_cnt=1/player->tm_fstep;
- player->dir_mode=5;
- player->tm_zdis=0;
- if (keeper_on_grnd)
- // Stay down for a bit after save...
- if (save_block)
- player->int_cnt=4+((128-player->tm_rate)/12)+1/player->tm_fstep; // Time to get up!
- else
- player->int_cnt=18+1/player->tm_fstep; // Time to get up!
- else
- player->int_cnt=2+1/player->tm_fstep;
- player->int_move=I_SAVE_WAIT;
- action="Save";
- player->tm_act=SAVE_ACT;
- newdx=player->tm_xdis;
- newdy=player->tm_ydis;
- }
- /******************************************************************************
- *****************************************************************************/
- #define DIVE_POINT 3
- #define DIVE_FEET_DIST (prat*4)
- // Someone has shot...
- // Send keeper to intersection with ball path.
- // If he cannot meet ball then best try!
- void go_to_save_path(match_player *player,char forced=FALSE)
- {
- keeper_spd=((float)(player->tm_flair+player->tm_rate)/128)*(forced ? 2:1);
- // Calculate next frame distance to the ball...
- float d=calc_dist(player->tm_x-(ballx+ballxdis),player->tm_y-(bally+ballydis));
- if (!forced)
- {
- if (d<player->tm_dist)
- // Ball is getting closer...
- {
- if (player->tm_player==KP_A)
- {
- // Keeper A
- if (ballx<cntspot_x)
- shot_acknowledged=1+((128-player->tm_vis)/8);
- }
- else
- {
- // Keeper B
- if (ballx>cntspot_x)
- shot_acknowledged=1+((128-player->tm_vis)/8);
- }
- }
- }
- if (shot_acknowledged || forced)
- {
- int flag;
- int vision=((128-player->tm_vis)/2);
- // Is shot on Target?
- // if (ABS(ballxdis)>0)
- {
- float kp_xoff;
- float x,y,z,ox,oy,oz;
- float xc,yc,zc;
- float xf,yf,zf;
- float xns,yns,zns;
- int bp,ob;
- float min_d=2000;
- float d,t,fd;
- float px=player->tm_x;
- float py=player->tm_y;
- float rate=actual_spd(player); // Dive is 2 x rate.
- flag=FALSE;
- char in_area=FALSE;
- bp=1;
- ob=1;
- ox=ballx;
- oy=bally;
- oz=ballz;
- xc=ballx;
- yc=bally;
- zc=ballz;
-
- if (!keep_dive)
- {
- float see_swerve;
- see_swerve=(64.+(player->tm_vis/2))/128;
- for (int i=1; i<50; i++)
- {
- // Coords without swerve...
- xns=ns_ball_pred_tab[i][0];
- yns=ns_ball_pred_tab[i][1];
- zns=ns_ball_pred_tab[i][2];
- // Coords with swerve...
- x=ball_pred_tab[i][0];
- y=ball_pred_tab[i][1];
- z=ball_pred_tab[i][2];
- // Coords seeing some swerve...
- x=xns+((x-xns)*see_swerve);
- y=yns+((y-yns)*see_swerve);
- z=zns+((z-zns)*see_swerve);
- in_area=FALSE;
- if (y>top_post_y && y<bot_post_y)
- kp_xoff=4;
- else
- kp_xoff=0;
- // Try and stop keeper saving and carrying ball behind line...
- if (x>cntspot_x)
- {
- // Team B goal-line...
- if (x>=pitch_len-kp_xoff)
- {
- i=60;
- if (ABS(y-cntspot_y)>((prat*4.5)+(128-player->tm_flair)/4))
- // Too wide!
- flag=FALSE; // Don't bother saving!
- }
- }
-
- if (x<=cntspot_x)
- {
- // Team A goal-line...
- if (x<0+kp_xoff)
- {
- i=60;
- if (ABS(y-cntspot_y)>((prat*4.5)+(128-player->tm_flair)/4))
- // Too wide!
- flag=FALSE; // Don't bother saving!
- }
- }
- if (i!=60)
- {
- if (player->tm_player<12)
- {
- if (x<prat*18 && y>cntspot_y-(21*prat)
- && (y<cntspot_y+(21*prat)))
- in_area=TRUE;
- }
- else
- {
- if (x>pitch_len-(prat*18) && y>cntspot_y-(21*prat)
- && (y<cntspot_y+(21*prat)))
- in_area=TRUE;
- }
-
- if (in_area)
- {
- d=calc_dist(x-px,y-py);
- // if (d<min_d && z<SAVE_JUMP_HGT+prat && target_towards_ball(x,y,px,py))
- if (d<min_d && z<SAVE_JUMP_HGT+prat/2)
- // Store closest ball!
- {
- ox=xc;
- oy=yc;
- oz=zc;
- ob=bp;
- min_d=d;
- bp=i;
- xc=x;
- yc=y;
- zc=z;
- flag=TRUE;
- }
- else
- // Getting further away...
- {
- if (d-min_d>prat)
- // Definately not getting any closer...
- {
- i=60; // Quit.
- }
- }
- }
- }
- }
- }
- else
- {
- flag=TRUE;
- xc=ball_pred_tab[DIVE_POINT][0];
- yc=ball_pred_tab[DIVE_POINT][1];
- zc=ball_pred_tab[DIVE_POINT][2];
- d=calc_dist(xc-px,yc-py);
- x=(xc-px)/d;
- y=(yc-py)/d;
- if (keep_dive)
- {
- xc+=x*prat;
- yc+=y*prat;
- }
- ox=xc;
- oy=yc;
- oz=zc;
- ob=DIVE_POINT;
- bp=DIVE_POINT;
- }
- if (flag)
- // Shot is in area...
- {
- x=ox+((xc-ox)/2); // Between closest and one before...
- y=oy+((yc-oy)/2);
- z=oz+((zc-oz)/2);
- if (forced) // Forced to dive at attackers feet...
- {
- fd=calc_dist(x-px,y-py);
- xf=(x-px)/fd;
- yf=(y-py)/fd;
- x+=xf*3;
- y+=yf*3; // Dive beyond point of contact...
- }
- // bp=ob;
- // Nearest ball coord.
- d=calc_dist(x-px,y-py); // Distance to keeper...
-
- char st=player->go_step;
- player->go_step=TRUE;
- t=d/actual_spd(player); // Time to step there...
- player->go_step=st;
- max_kp_margin=1.5+(1.8*time_factor/90);
- /*************************************************************/
- /*************************************************************/
- #ifdef EURO96
- if (penalty_shot && user_controlled)
- {
- if (users_dir[user_controlled-1].f&8)
- save_direction=-1;
- if (users_dir[user_controlled-1].f&4)
- save_direction=1;
- char good_choice=FALSE;
- // User decides which way to dive...
- if (t<1 && !save_direction)
- {
- // Straight on...(good choice!)
- good_choice=TRUE;
- }
- else
- {
- if (save_direction)
- {
- // User has chosen a direction...
- if (save_direction<0)
- {
- // Left selected...
- if ((x<cntspot_x && player->tm_y>(y+(SAVE_ZONE_A/2)))
- || (x>cntspot_x && player->tm_y<(y-(SAVE_ZONE_A/2))))
- {
- good_choice=TRUE;
- }
- }
- else
- {
- // Right selected...
- if ((x<cntspot_x && player->tm_y<(y-(SAVE_ZONE_A/2)))
- || (x>cntspot_x && player->tm_y>(y+(SAVE_ZONE_A/2))))
- {
- good_choice=TRUE;
- }
- }
- }
- else
- {
- if (d<=SAVE_ZONE_A)
- good_choice=TRUE;
- }
- }
- if (good_choice)
- {
- // Let computer save...
- if (t<1)
- {
- save_in_zone_a(player,x,y,z,bp,forced);
- }
- else
- {
- if (d<=SAVE_ZONE_A)
- save_in_zone_a(player,x,y,z,bp,forced);
- else
- if (d<=SAVE_ZONE_B)
- save_in_zone_b(player,x,y,z,bp,forced);
- else
- if (d<=(SAVE_ZONE_C+prat*2))
- save_in_zone_c(player,x,y,z,bp,forced);
- else
- keep_dive=FALSE;
- }
- }
- else
- {
- // Save in the direction of user's choice...
- init_user_save(player);
- }
- }
- else
- #endif
- /*************************************************************/
- /*************************************************************/
- {
- if (t<1)
- /************************************/
- // Already in preferred position... //
- /************************************/
- {
- save_in_zone_a(player,x,y,z,bp,forced);
- }
- else
- {
- if (t<bp-SAVE_AHEADC_TIME)
- /************************************************************/
- // Can get body behind it and still have time to animate... //
- /************************************************************/
- {
- reset_ideas(player);
- player->go_step=TRUE;
- if (player->tm_player<12)
- init_run_act(player,x-prat,y,TRUE); //ball meet point
- else
- init_run_act(player,x+prat,y,TRUE); //ball meet point
- }
- else
- {
- if (d<=SAVE_ZONE_A)
- save_in_zone_a(player,x,y,z,bp,forced);
- else
- if (d<=SAVE_ZONE_B)
- save_in_zone_b(player,x,y,z,bp,forced);
- else
- if (d<=(SAVE_ZONE_C+prat*2))
- save_in_zone_c(player,x,y,z,bp,forced);
- else
- keep_dive=FALSE;
- }
- }
- }
- }
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void fake_ball_poss(int p,float x,float y,float z)
- {
- save_ball_poss=ball_poss;
- save_ballx=ballx;
- save_bally=bally;
- save_ballz=ballz;
- ballx=x;
- bally=y;
- ballz=z;
- ball_poss=p;
- }
- /******************************************************************************
- *****************************************************************************/
- void restore_ball_poss()
- {
- ball_poss=save_ball_poss;
- ballx=save_ballx;
- bally=save_bally;
- ballz=save_ballz;
- }
- /******************************************************************************
- *****************************************************************************/
- char kick_straight()
- {
- if (pass_type==-1 || (pass_type>=4 && pass_type<=6))
- return(TRUE);
- else
- return(FALSE);
- }
- /******************************************************************************
- *****************************************************************************/
- char first_time_strike(int p,float x,float y,float z,float px,float py)
- {
- float d;
- float obx=ballx;
- float oby=bally;
- char sr=teams[p-1].tm_srng;
- if (p<12)
- d=calc_dist(pitch_len-x,cntspot_y-y);
- else
- d=calc_dist(x,cntspot_y-y);
- if (d<(MIN_SHOOT_DIST+((float)teams[p-1].tm_pow*3)))
- teams[p-1].tm_srng=TRUE;
- else
- teams[p-1].tm_srng=FALSE;
- float xpd=teams[p-1].tm_xdis;
- float ypd=teams[p-1].tm_ydis;
- teams[p-1].tm_xdis=x_face;
- teams[p-1].tm_ydis=y_face;
- ballx=teams[p-1].tm_x;
- bally=teams[p-1].tm_y;
-
- pass_type=FALSE;
- receiver=FALSE;
- char allow=0;
- float gx,gy;
- if (p<12)
- gx=pitch_len;
- else
- gx=0;
- gy=cntspot_y;
- gx-=x;
- gy-=y;
- d=calc_dist(gx,gy);
- fake_ball_poss(p,x,y,z);
- if (auto_select)
- {
- if (ball_int_speed>6)
- {
- // Ball is moving so he can trap...
- allow=128; // Can control it...
- }
- if (shoot_decide(&teams[p-1]))
- {
- pass_type=0;
- allow+=3; // Kick or volley!
- if (d<MIN_HEADER_RNG+(prat*teams[p-1].tm_pow/8))
- // In head range also!
- {
- allow+=8+16; // Standing or Jumping header!
- if (kick_straight())
- // Target is forward!
- allow+=4; // Diving header!
- }
- }
- else
- {
- teams[p-1].tm_xdis=-teams[p-1].tm_xdis;
- teams[p-1].tm_ydis=-teams[p-1].tm_ydis; // Reverse face!
- if (shoot_decide(&teams[p-1]))
- {
- pass_type=0;
- allow+=32; // Overhead!
- }
- else
- {
- if (punt_decide(&teams[p-1])) // Overhead punt???
- {
- pass_type=0;
- allow+=32; // Overhead!
- }
- else
- {
- teams[p-1].tm_xdis=-teams[p-1].tm_xdis;
- teams[p-1].tm_ydis=-teams[p-1].tm_ydis; // Reverse face!
- if (punt_decide(&teams[p-1]))
- {
- pass_type=0;
- allow+=1+2+4+8+16; // Kick or volley or any header!
- }
- else
- {
- receiver=pass_decide(&teams[p-1],FALSE);
- if (receiver)
- {
- if (pass_type==-1)
- // Chip pass!
- allow+=64+8+16; // Chip, S-head, J-head!
- else
- {
- if (kick_straight())
- allow+=8+16; // S-head, J-head!
- }
- }
- }
- }
- }
- }
- }
- else
- allow=0;
- restore_ball_poss();
- teams[p-1].tm_srng=sr; // Restore range flag!
- teams[p-1].tm_xdis=xpd;
- teams[p-1].tm_ydis=ypd;
- ballx=obx;
- bally=oby;
- return(allow);
- }
- /******************************************************************************
- *****************************************************************************/
- char user_pass_check(int p,float x,float y,float z,float px,float py)
- {
- float d;
- float obx=ballx;
- float oby=bally;
- char sr=teams[p-1].tm_srng;
- if (p<12)
- d=calc_dist(pitch_len-x,cntspot_y-y);
- else
- d=calc_dist(x,cntspot_y-y);
- if (d<(MIN_SHOOT_DIST+((float)teams[p-1].tm_pow*3)))
- teams[p-1].tm_srng=TRUE;
- else
- teams[p-1].tm_srng=FALSE;
- float xpd=teams[p-1].tm_xdis;
- float ypd=teams[p-1].tm_ydis;
- teams[p-1].tm_xdis=x_face;
- teams[p-1].tm_ydis=y_face;
- ballx=teams[p-1].tm_x;
- bally=teams[p-1].tm_y;
-
- pass_type=FALSE;
- receiver=FALSE;
- char allow=0;
- float gx,gy;
- if (p<12)
- gx=pitch_len;
- else
- gx=0;
- gy=cntspot_y;
- gx-=x;
- gy-=y;
- d=calc_dist(gx,gy);
- fake_ball_poss(p,x,y,z);
- receiver=pass_decide(&teams[p-1],FALSE);
- if (receiver)
- {
- if (pass_type==-1)
- // Chip pass!
- allow+=64+8+16; // Chip, S-head, J-head!
- else
- {
- if (kick_straight())
- allow+=8+16; // S-head, J-head!
- }
- }
- else
- allow=0;
- restore_ball_poss();
- teams[p-1].tm_srng=sr; // Restore range flag!
- teams[p-1].tm_xdis=xpd;
- teams[p-1].tm_ydis=ypd;
- ballx=obx;
- bally=oby;
- return(allow);
- }
- /******************************************************************************
- *****************************************************************************/
- void decide_strike(match_player *p,short t,char c,char s)
- {
- float x=ball_pred_tab[t][0];
- float y=ball_pred_tab[t][1];
- float z=ball_pred_tab[t][1];
- p->int_cnt=t; // Flair factor.
- init_run_act(p,x,y,TRUE);
- p->tm_strike=TRUE;
- }
- /******************************************************************************
- *****************************************************************************/
- void strike_and_control(match_player *player,intercept_data *s,short action)
- {
- player->tm_stime=s->atime+1;
- // player->int_cnt=player->tm_stime+alarm+free+1; // Make sure he seems busy for the duration!
- float x=s->x;
- float y=s->y;
- switch(action)
- {
- case(7):
- case(9):
- case(10):
- if (player->tm_fpass_type=s->ptype)
- // Equate pass type and test!
- player->tm_fpass_to=s->pplr;
- break;
- }
- short gt=get_there_time(player->tm_player,x,y);
- player->tm_ftime=s->free;
- player->tm_strike=action;
- init_run_act(player,x,y,FALSE);
- player->int_cnt=player->go_cnt+player->tm_ftime+player->tm_stime;
- if (must_face)
- player->int_cnt+=player->mface_time;
- if (user_controlled)
- {
- player->special=-TRUE; // Special action decided!
- /*
- if (player->go_cnt>1)
- {
- player->go_cnt=1;
- player->int_cnt=1;
- }
- */
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void cancel_int(int p)
- {
- // should never get here!
- init_stand_act(&teams[p-1]);
- }
- /******************************************************************************
- *****************************************************************************/
- void intercept(int p)
- {
- action="Intercept";
- reset_ideas(&teams[p-1]);
- if (p<12)
- interceptor_a=p;
- else
- interceptor_b=p;
- // His intention is to intercept ball.
- // Therefore his flair determines no. of turns before rethink!
- int ff=33-(teams[p-1].tm_flair/4);
- teams[p-1].int_move=I_INTERCEPT; // Intercept ball!
- teams[p-1].int_cnt=ff; // Intercept ball!
- float x,y;
- if (special_move)
- teams[p-1].special=TRUE;
- else
- teams[p-1].special=FALSE;
- {
- for (short i=10; i>=0; i--)
- {
- if (strike[i].t)
- {
- if (i>0)
- {
- if (user_controlled)
- {
- // uf1 = strike, uf2 = control!
- if (uf1 && i>4)
- {
- strike_and_control(&teams[p-1],&strike[i],i);
- break;
- }
- else
- {
- if (uf2 && i<=4 && i)
- {
- strike_and_control(&teams[p-1],&strike[i],i);
- break;
- }
- }
- }
- else
- {
- strike_and_control(&teams[p-1],&strike[i],i);
- break;
- }
- }
- else
- {
- // Run onto ball...
- if (strike[0].stop)
- init_stop_act(&teams[p-1],strike[0].x,strike[0].y);
- else
- init_run_act(&teams[p-1],strike[0].x,strike[0].y,FALSE);
- teams[p-1].go_cnt++;
- break;
- }
- }
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- float fstep_factor(short c)
- {
- // Returns a range of 0.6(c=0) to 1.6(c=128)
- float f=0.6+((float)c/128);
- return(f);
- }
- /******************************************************************************
- *****************************************************************************/
- #ifdef EURO96
- // Euro 96 has first time pass implemented...
- char can_i_intercept(int p_num,float x,float y,float z,float px,float py,short i)
- {
- if (z>=teams[p_num-1].tm_jump)
- return(FALSE);
- float cx,cy,cz,cx2,cy2,ang;
- float rate=full_spd(&teams[p_num-1]);
- float d=calc_dist(x-px,y-py);
- char can_strike;
- char do_it=FALSE;
- char stand;
- char strike_option=FALSE;
- char trap_option=FALSE;
- char pass_option=FALSE;
- short ff=1+teams[p_num-1].tm_flair/16; // Reaction times.
- short gt=get_there_time(p_num,x,y);
- short t;
- if (gt<=i)
- {
- // He can get to ball in time...
- if (ball_poss)
- {
- // Opponent has ball... (No control or strike!)
- /***** RUN ONTO BALL *****/
- t=i-gt;
- if (t>0 && t<strike[0].free && (teams[p_num-1].control || t<ff))
- {
- strike[0].t=i;
- strike[0].free=t;
- strike[0].x=x;
- strike[0].y=y;
- strike[0].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- else
- {
- if (user_controlled)
- {
- can_strike=128+32+16+8+4+2+1;
- pass_type=0;
- strike_option=uf1&(!uf2);
- trap_option=uf2&(!uf1);
- pass_option=uf1&uf2;
- if (pass_option)
- can_strike=user_pass_check(p_num,x,y,z,px,py);
- }
- else
- can_strike=first_time_strike(p_num,x,y,z,px,py);
- /***** RUN ONTO BALL *****/
- if (z<PLAYER_HEIGHT/3)
- {
- // Feet level...
- ang=angle_to_xy(x-px,y-py,teams[p_num-1].tm_xdis,teams[p_num-1].tm_ydis);
- if (ang>0 || user_controlled)
- {
- // Target is in front of player...
- t=i-gt;
- if (t>=0 && t<strike[0].free && (teams[p_num-1].control || t<ff))
- {
- strike[0].t=i;
- strike[0].free=t;
- strike[0].x=x;
- strike[0].y=y;
- strike[0].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- // if (plr_facing(x-px,y-py,&teams[p_num-1]) && target_towards_ball(x,y,px,py)
- // if ((target_towards_ball(x,y,px,py) || stop_and_face) &&
- // if (
- // teams[p_num-1].tm_act<=TURN_ACT)
-
- if ((p_num!=KP_A && p_num!=KP_B)
- || (p_num==KP_A && cannot_pick_up<12) || (p_num==KP_B && cannot_pick_up>11))
- {
- // Keeper cannot pick ball up...
- // Player must be running or standing...
- if (teams[p_num-1].tm_trap>=0)
- {
- // Must control ball or may hit it first time...
- /***** TRAP AND CONTROL *****/
- if (can_strike&128)
- {
- if (z<PLAYER_HEIGHT/2)
- {
- // Feet level...
- rotate_offs(MC_TRAPL,cx,cy,cz,x_face,y_face);
- rotate_offs(MC_TRAPR,cx2,cy2,cz,x_face,y_face);
- cx=(cx+cx2)/2;
- cy=(cy+cy2)/2;
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_ttm);
- if (t>=0 && t<strike[1].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if (trap_option || !user_controlled)
- {
- strike[1].t=i;
- strike[1].free=t;
- strike[1].atime=ft_ttm;
- strike[1].gt=gt;
- strike[1].x=x-cx;
- strike[1].y=y-cy;
- strike[1].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- else
- {
- if (z<(PLAYER_HEIGHT-2))
- {
- // Chest level...
- rotate_offs(MC_CHEST,cx,cy,cz,x_face,y_face);
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_ctm);
- if (t>=0 && t<strike[2].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if (trap_option || !user_controlled)
- {
- strike[2].t=i;
- strike[2].free=t;
- strike[2].atime=ft_ctm;
- strike[2].gt=gt;
- strike[2].x=x-cx;
- strike[2].y=y-cy;
- strike[2].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- else
- {
- if (z<(PLAYER_HEIGHT+4))
- {
- // Head level...
- rotate_offs(MC_D_HEAD,cx,cy,cz,x_face,y_face);
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_utm);
- if (t>=0 && t<strike[3].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if (trap_option || !user_controlled)
- {
- strike[3].t=i;
- strike[3].free=t;
- strike[3].atime=ft_utm;
- strike[3].gt=gt;
- strike[3].x=x-cx;
- strike[3].y=y-cy;
- strike[3].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- }
- }
- }
- }
- if (teams[p_num-1].tm_trap<=0)
- {
-
- // May hit it first time...
- /***** FIRST TIME STRIKE *****/
- if (z<PLAYER_HEIGHT/4)
- {
- if (can_strike&1)
- {
- // Feet level...
- rotate_offs(MC_SHOOTL,cx,cy,cz,x_face,y_face);
- rotate_offs(MC_SHOOTR,cx2,cy2,cz,x_face,y_face);
- cx=(cx+cx2)/2;
- cy=(cy+cy2)/2;
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_ktm);
- if (t>=0 && t<strike[8].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if (strike_option || !user_controlled)
- {
- strike[8].t=i;
- strike[8].free=t;
- strike[8].atime=ft_ktm;
- strike[8].gt=gt;
- strike[8].x=x-cx;
- strike[8].y=y-cy;
- strike[8].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- if (can_strike&64)
- {
- // Feet level...
- rotate_offs(MC_CHIPL,cx,cy,cz,x_face,y_face);
- rotate_offs(MC_CHIPR,cx2,cy2,cz,x_face,y_face);
- cx=(cx+cx2)/2;
- cy=(cy+cy2)/2;
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_ctm);
- if (t>=0 && t<strike[10].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if (strike_option || !user_controlled)
- {
- strike[10].t=i;
- strike[10].free=t;
- strike[10].ptype=pass_type;
- strike[10].pplr=receiver;
- strike[10].atime=ft_ctm;
- strike[10].gt=gt;
- strike[10].x=x-cx;
- strike[10].y=y-cy;
- strike[10].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- }
- else
- {
- if (z<PLAYER_HEIGHT*.5)
- {
- // volley level...
- if (can_strike&2)
- {
- rotate_offs(MC_VOLLEYL,cx,cy,cz,x_face,y_face);
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_vtm);
- if (t>=0 && t<strike[5].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if (strike_option || !user_controlled)
- {
- strike[5].t=i;
- strike[5].free=t;
- strike[5].atime=ft_vtm;
- strike[5].gt=gt;
- strike[5].x=x-cx;
- strike[5].y=y-cy;
- strike[5].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- }
- else
- {
- if (z<PLAYER_HEIGHT*.67)
- {
- if (can_strike&4)
- {
- rotate_offs(MC_DV_HEAD,cx,cy,cz,x_face,y_face);
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_dtm);
- if (t>=0 && t<strike[6].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if (strike_option || !user_controlled)
- {
- strike[6].t=i;
- strike[6].free=t;
- strike[6].atime=ft_dtm;
- strike[6].gt=gt;
- strike[6].x=x-cx;
- strike[6].y=y-cy;
- strike[6].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- }
- else
- {
- if (z<PLAYER_HEIGHT+2)
- {
- // head level...
- if (can_strike&32)
- {
- rotate_offs(MC_OVERHEAD,cx,cy,cz,x_face,y_face);
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_otm);
- if (t>=0 && t<strike[4].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if (strike_option || !user_controlled)
- {
- strike[4].t=i;
- strike[4].free=t;
- strike[4].atime=ft_otm;
- strike[4].gt=gt;
- strike[4].x=x-cx;
- strike[4].y=y-cy;
- strike[4].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- if (can_strike&8)
- {
- // He has time...
- rotate_offs(MC_S_HEAD,cx,cy,cz,x_face,y_face);
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_stm);
- if (t>=0 && t<strike[9].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if (strike_option || !user_controlled)
- {
- strike[9].t=i;
- strike[9].free=t;
- strike[9].ptype=pass_type;
- strike[9].pplr=receiver;
- strike[9].atime=ft_stm;
- strike[9].gt=gt;
- strike[9].x=x-cx;
- strike[9].y=y-cy;
- strike[9].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- }
- else
- {
- if (z<teams[p_num-1].tm_jump)
- {
- // Jump level...
- if (can_strike&16)
- {
- // He has time...
- rotate_offs(MC_J_HEAD,cx,cy,cz,x_face,y_face);
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_jtm);
- if (ABS(cz+prat-z)<8 && t>=0 && t<strike[7].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if (strike_option || !user_controlled)
- {
- strike[7].t=i;
- strike[7].free=t;
- strike[7].ptype=pass_type;
- strike[7].pplr=receiver;
- strike[7].atime=ft_jtm;
- strike[7].gt=gt;
- strike[7].x=x-cx;
- strike[7].y=y-cy;
- strike[7].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- return(do_it);
- }
- #else
- // No first-time passing...
- char can_i_intercept(int p_num,float x,float y,float z,float px,float py,short i)
- {
- if (z>=teams[p_num-1].tm_jump)
- return(FALSE);
- float cx,cy,cz,cx2,cy2,ang;
- float rate=full_spd(&teams[p_num-1]);
- float d=calc_dist(x-px,y-py);
- char can_strike;
- char do_it=FALSE;
- char stand;
- short ff=1+teams[p_num-1].tm_flair/16; // Reaction times.
- short gt=get_there_time(p_num,x,y);
- short t;
- if (gt<=i)
- {
- // He can get to ball in time...
- if (ball_poss)
- {
- // Opponent has ball... (No control or strike!)
- /***** RUN ONTO BALL *****/
- t=i-gt;
- if (t>0 && t<strike[0].free && (teams[p_num-1].control || t<ff))
- {
- strike[0].t=i;
- strike[0].free=t;
- strike[0].x=x;
- strike[0].y=y;
- strike[0].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- else
- {
- if (user_controlled)
- {
- can_strike=128+32+16+8+4+2+1;
- pass_type=0;
- }
- else
- can_strike=first_time_strike(p_num,x,y,z,px,py);
- /***** RUN ONTO BALL *****/
- if (z<PLAYER_HEIGHT/3)
- {
- // Feet level...
- ang=angle_to_xy(x-px,y-py,teams[p_num-1].tm_xdis,teams[p_num-1].tm_ydis);
- if (ang>0 || user_controlled)
- {
- // Target is in front of player...
- t=i-gt;
- if (t>=0 && t<strike[0].free && (teams[p_num-1].control || t<ff))
- {
- strike[0].t=i;
- strike[0].free=t;
- strike[0].x=x;
- strike[0].y=y;
- strike[0].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- // if (plr_facing(x-px,y-py,&teams[p_num-1]) && target_towards_ball(x,y,px,py)
- // if ((target_towards_ball(x,y,px,py) || stop_and_face) &&
- // if (
- // teams[p_num-1].tm_act<=TURN_ACT)
-
- if ((p_num!=KP_A && p_num!=KP_B)
- || (p_num==KP_A && cannot_pick_up<12) || (p_num==KP_B && cannot_pick_up>11))
- {
- // Keeper cannot pick ball up...
- // Player must be running or standing...
- if (teams[p_num-1].tm_trap>=0)
- {
- // Must control ball or may hit it first time...
- /***** TRAP AND CONTROL *****/
- if (can_strike&128)
- {
- if (z<PLAYER_HEIGHT/2)
- {
- // Feet level...
- rotate_offs(MC_TRAPL,cx,cy,cz,x_face,y_face);
- rotate_offs(MC_TRAPR,cx2,cy2,cz,x_face,y_face);
- cx=(cx+cx2)/2;
- cy=(cy+cy2)/2;
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_ttm);
- if (t>=0 && t<strike[1].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if ((user_controlled && uf2) || !user_controlled)
- {
- strike[1].t=i;
- strike[1].free=t;
- strike[1].atime=ft_ttm;
- strike[1].gt=gt;
- strike[1].x=x-cx;
- strike[1].y=y-cy;
- strike[1].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- else
- {
- if (z<(PLAYER_HEIGHT-2))
- {
- // Chest level...
- rotate_offs(MC_CHEST,cx,cy,cz,x_face,y_face);
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_ctm);
- if (t>=0 && t<strike[2].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if ((user_controlled && uf2) || !user_controlled)
- {
- strike[2].t=i;
- strike[2].free=t;
- strike[2].atime=ft_ctm;
- strike[2].gt=gt;
- strike[2].x=x-cx;
- strike[2].y=y-cy;
- strike[2].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- else
- {
- if (z<(PLAYER_HEIGHT+4))
- {
- // Head level...
- rotate_offs(MC_D_HEAD,cx,cy,cz,x_face,y_face);
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_utm);
- if (t>=0 && t<strike[3].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if ((user_controlled && uf2) || !user_controlled)
- {
- strike[3].t=i;
- strike[3].free=t;
- strike[3].atime=ft_utm;
- strike[3].gt=gt;
- strike[3].x=x-cx;
- strike[3].y=y-cy;
- strike[3].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- }
- }
- }
- }
- if (teams[p_num-1].tm_trap<=0)
- {
-
- // May hit it first time...
- /***** FIRST TIME STRIKE *****/
- if (z<PLAYER_HEIGHT/4)
- {
- if (can_strike&1)
- {
- // Feet level...
- rotate_offs(MC_SHOOTL,cx,cy,cz,x_face,y_face);
- rotate_offs(MC_SHOOTR,cx2,cy2,cz,x_face,y_face);
- cx=(cx+cx2)/2;
- cy=(cy+cy2)/2;
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_ktm);
- if (t>=0 && t<strike[8].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if ((user_controlled && uf1) || !user_controlled)
- {
- strike[8].t=i;
- strike[8].free=t;
- strike[8].atime=ft_ktm;
- strike[8].gt=gt;
- strike[8].x=x-cx;
- strike[8].y=y-cy;
- strike[8].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- if (can_strike&64)
- {
- // Feet level...
- rotate_offs(MC_CHIPL,cx,cy,cz,x_face,y_face);
- rotate_offs(MC_CHIPR,cx2,cy2,cz,x_face,y_face);
- cx=(cx+cx2)/2;
- cy=(cy+cy2)/2;
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_ctm);
- if (t>=0 && t<strike[10].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if ((user_controlled && uf1) || !user_controlled)
- {
- strike[10].t=i;
- strike[10].free=t;
- strike[10].ptype=pass_type;
- strike[10].pplr=receiver;
- strike[10].atime=ft_ctm;
- strike[10].gt=gt;
- strike[10].x=x-cx;
- strike[10].y=y-cy;
- strike[10].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- }
- else
- {
- if (z<PLAYER_HEIGHT*.5)
- {
- // volley level...
- if (can_strike&2)
- {
- rotate_offs(MC_VOLLEYL,cx,cy,cz,x_face,y_face);
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_vtm);
- if (t>=0 && t<strike[5].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if ((user_controlled && uf1) || !user_controlled)
- {
- strike[5].t=i;
- strike[5].free=t;
- strike[5].atime=ft_vtm;
- strike[5].gt=gt;
- strike[5].x=x-cx;
- strike[5].y=y-cy;
- strike[5].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- }
- else
- {
- if (z<PLAYER_HEIGHT*.67)
- {
- if (can_strike&4)
- {
- rotate_offs(MC_DV_HEAD,cx,cy,cz,x_face,y_face);
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_dtm);
- if (t>=0 && t<strike[6].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if ((user_controlled && uf1) || !user_controlled)
- {
- strike[6].t=i;
- strike[6].free=t;
- strike[6].atime=ft_dtm;
- strike[6].gt=gt;
- strike[6].x=x-cx;
- strike[6].y=y-cy;
- strike[6].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- }
- else
- {
- if (z<PLAYER_HEIGHT+2)
- {
- // head level...
- if (can_strike&32)
- {
- rotate_offs(MC_OVERHEAD,cx,cy,cz,x_face,y_face);
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_otm);
- if (t>=0 && t<strike[4].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if ((user_controlled && uf1) || !user_controlled)
- {
- strike[4].t=i;
- strike[4].free=t;
- strike[4].atime=ft_otm;
- strike[4].gt=gt;
- strike[4].x=x-cx;
- strike[4].y=y-cy;
- strike[4].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- if (can_strike&8)
- {
- // He has time...
- rotate_offs(MC_S_HEAD,cx,cy,cz,x_face,y_face);
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_stm);
- if (t>=0 && t<strike[9].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if ((user_controlled && uf1) || !user_controlled)
- {
- strike[9].t=i;
- strike[9].free=t;
- strike[9].ptype=pass_type;
- strike[9].pplr=receiver;
- strike[9].atime=ft_stm;
- strike[9].gt=gt;
- strike[9].x=x-cx;
- strike[9].y=y-cy;
- strike[9].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- }
- else
- {
- if (z<teams[p_num-1].tm_jump)
- {
- // Jump level...
- if (can_strike&16)
- {
- // He has time...
- rotate_offs(MC_J_HEAD,cx,cy,cz,x_face,y_face);
- gt=get_there_time(p_num,x-cx,y-cy);
- t=i-(gt+ft_jtm);
- if (ABS(cz+prat-z)<8 && t>=0 && t<strike[7].free && (teams[p_num-1].control || t<ff))
- {
- // He has time to animate...
- // Best so far!
- special_move=TRUE;
- if ((user_controlled && uf1) || !user_controlled)
- {
- strike[7].t=i;
- strike[7].free=t;
- strike[7].ptype=pass_type;
- strike[7].pplr=receiver;
- strike[7].atime=ft_jtm;
- strike[7].gt=gt;
- strike[7].x=x-cx;
- strike[7].y=y-cy;
- strike[7].stop=stop_and_face;
- do_it=TRUE;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- return(do_it);
- }
- #endif
- /*******************************************************************************
- *****************************************************************************/
- void clear_strike()
- {
- // Clear first time animation array...
- for (short i=0; i<11; i++)
- {
- strike[i].t=0; // Init start time.
- strike[i].free=1000; // Init wait time.
- strike[i].ptype=0;
- strike[i].pplr=0;
- }
- }
- /*******************************************************************************
- *****************************************************************************/
- void decide_on_face(match_player *p)
- {
- float gx,gy,x,y,d;
- if (p->tm_player<12)
- // Team A...
- gx=0; // His goal...
- else
- gx=pitch_len; // His goal...
- gy=cntspot_y;
- gx=gx-p->tm_x;
- gy=gy-p->tm_y;
- d=calc_dist(gx,gy);
- if (d<prat*30)
- {
- // In Defense...
- if (p->tm_player<12)
- must_face_x=1;
- else
- must_face_x=-1;
- must_face=TRUE;
- }
- else
- {
- // Not in defense...
- if (p->tm_player<12)
- gx=pitch_len;
- else
- gx=0;
-
- gx=gx-p->tm_x;
- d=calc_dist(gx,gy);
- if (d<(MIN_SHOOT_DIST+((float)p->tm_pow*3)))
- {
- // In Shooting Range...
- must_face_x=gx/d;
- must_face_y=gy/d;
- must_face=TRUE;
- }
- }
- }
- /*******************************************************************************
- *****************************************************************************/
- char go_to_path(int p_num)
- // Send player(p_num) to intersection with ball path.
- // If he cannot meet ball then best try!
- {
- float spd_up;
- special_move=FALSE;
- teams[p_num-1].tm_fpass_type=0;
- teams[p_num-1].tm_fpass_to=0;
- float x,y,z;
- float px=teams[p_num-1].tm_x;
- float py=teams[p_num-1].tm_y;
- short i;
- char do_it=FALSE;
- first_time_it=TRUE;
- clear_strike();
- /*** Capture Timings ***/
- /* Release Ball */
- if (user_controlled)
- // Allow user to animate faster for responsiveness...
- spd_up=1.3;
- else
- spd_up=1;
- // Kick time...
- ft_ktm=MCC_SHOOT/(MC_SHOOT_FS*spd_up*fstep_factor(teams[p_num-1].tm_flair));
- // Volley time...
- ft_vtm=MCC_VOLLEY/(MC_VOLLEY_FS*spd_up*fstep_factor(teams[p_num-1].tm_flair));
- // Diving time...
- ft_dtm=MCC_DV_HEAD/(MC_DV_HEAD_FS*spd_up*fstep_factor(teams[p_num-1].tm_flair));
- // Overhead time...
- ft_otm=MCC_OVERHEAD/(MC_OVERHEAD_FS*spd_up*fstep_factor(teams[p_num-1].tm_flair));
- // Standing time...
- ft_stm=MCC_S_HEAD/(MC_S_HEAD_FS*spd_up*fstep_factor(teams[p_num-1].tm_flair));
- // Jumping time...
- ft_jtm=MCC_J_HEAD/(MC_J_HEAD_FS*spd_up*fstep_factor(teams[p_num-1].tm_flair));
- // ft_jtm=MCC_J_HEAD/MC_J_HEAD_FS;
- /* Keep Ball */
- // Trapping time...
- ft_ttm=MCC_TRAP/(MC_TRAP_FS*spd_up*fstep_factor(teams[p_num-1].tm_cont));
- // Chesting time...
- ft_ctm=MCC_CHEST/(MC_CHEST_FS*spd_up*fstep_factor(teams[p_num-1].tm_cont));
- // Up head time...
- ft_utm=MCC_D_HEAD/(MC_D_HEAD_FS*spd_up*fstep_factor(teams[p_num-1].tm_cont));
- must_face=FALSE;
- auto_select=FALSE;
- if (user_controlled)
- {
- if (um && (uf1 || uf2))
- // User.. Directional control...
- {
- must_face=TRUE; // Forced to face in a particular dir...
- must_face_x=ux;
- must_face_y=uy;
- }
- else
- if (uf1 || uf2)
- {
- // User.. No directional control...
- decide_on_face(&teams[p_num-1]);
- }
- }
- else
- {
- if ((p_num<12 && !auto_users_a) || p_num==KP_A
- || (p_num>11 && !auto_users_b) || p_num==KP_B)
- {
- // Computer player will try to face goal or away from defense...
- auto_select=TRUE;
- if (p_num==receiver_a || p_num==receiver_b)
- {
- decide_on_face(&teams[p_num-1]);
- }
- }
- else
- {
- // Should be a user...
- auto_select=FALSE; // Don't allow computer to select a move!
- }
- }
- for (i=1; i<50; i+=2)
- {
- x=ball_pred_tab[i][0];
- y=ball_pred_tab[i][1];
- z=ball_pred_tab[i][2];
- ball_int_speed=ABS(x-ball_pred_tab[i-1][0])
- +ABS(y-ball_pred_tab[i-1][1])
- +(ABS(z-ball_pred_tab[i-1][2])*2);
- if ((x<0) || (x>=pitch_len) || (y<0) || (y>=pitch_wid))
- // Ball out of bounds
- {
- x=ball_pred_tab[i-1][0];
- y=ball_pred_tab[i-1][1];
- i=60;
- }
- else
- {
- do_it+=can_i_intercept(p_num,x,y,z,px,py,i);
- }
- }
- if (do_it)
- {
- /*
- if ((p_num<12 && auto_users_a && !teams[p_num-1].control)
- || (p_num>11 && auto_users_b && !teams[p_num-1].control))
- {
- reselect();
- user_conts(&teams[p_num-1]);
- user_controlled=teams[p_num-1].control;
- }
- */
- intercept(p_num);
- if (ball_poss)
- teams[p_num-1].ball_state=-ball_poss;
- else
- teams[p_num-1].ball_state=last_touch;
- }
- must_face=FALSE;
- first_time_it=FALSE;
- return(do_it);
- }
- /******************************************************************************
- *****************************************************************************/
- void ogo_to_path(int p_num,char header_only)
- // Send player(p_num) to intersection with ball path.
- // If he cannot meet ball then best try!
- {
- float x,y,z,d;
- float px=teams[p_num-1].tm_x;
- float py=teams[p_num-1].tm_y;
- float rate=actual_spd(&teams[p_num-1]);
- action="Intercept";
- reset_ideas(&teams[p_num-1]);
- if (p_num<12)
- interceptor_a=p_num;
- else
- interceptor_b=p_num;
- // His intention is to intercept ball.
- // Therefore his flair determines no. of turns before rethink!
- int ff=33-(teams[p_num-1].tm_flair/4);
- teams[p_num-1].int_move=I_INTERCEPT; // Intercept ball!
- teams[p_num-1].int_cnt=ff; // Flair factor.
- char feet_hit=FALSE;
- char body_hit=FALSE;
- char head_hit=FALSE;
- float feet_x,feet_y,body_x,body_y,head_x,head_y;
- for (int i=1; i<50; i++)
- {
- x=ball_pred_tab[i][0];
- y=ball_pred_tab[i][1];
- z=ball_pred_tab[i][2];
- if ((x<0) || (x>=pitch_len) || (y<0) || (y>=pitch_wid))
- // Ball out of bounds
- {
- x=ball_pred_tab[i-1][0];
- y=ball_pred_tab[i-1][1];
- i=60;
- }
- else
- {
- if (z<PLAYER_HEIGHT/2)
- {
- d=calc_dist(x-px,y-py);
- d=(int)(((float)d)/rate); //How many steps?
- if (d<=i)
- // He can get there in time!
- // At feet...
- {
- feet_x=x;
- feet_y=y;
- feet_hit=TRUE;
- i=60;
- }
- }
- else
- {
- if ((z<=PLAYER_HEIGHT-4) && (!body_hit))
- {
- d=calc_dist(x-px,y-py);
- d=(int)(((float)d)/rate); //How many steps?
- if (d<=i)
- // He can get there in time!
- // On body...
- {
- body_x=x;
- body_y=y;
- body_hit=TRUE;
- }
- // init_run_act(&teams[p_num-1],x,y,TRUE); //Go to path point!
- // i=60; // End For Loop!
- }
- else
- {
- if ((z>PLAYER_HEIGHT-4) && (z<=teams[p_num-1].tm_jump) && (!head_hit))
- {
- d=calc_dist(x-px,y-py);
- d=(int)(((float)d)/rate); //How many steps?
- if (d+(sqrt(z-PLAYER_HEIGHT+5)/gravity)<=i)
- // He can get there in time!
- // On head...
- {
- head_x=x;
- head_y=y;
- head_hit=TRUE;
- }
- // init_run_act(&teams[p_num-1],x,y,TRUE); //Go to path point!
- // i=60;
- }
- }
- }
- }
- }
-
- if ((!feet_hit) && (!head_hit) && (!body_hit))
- // He cant intersect!
- {
- init_run_act(&teams[p_num-1],x,y,TRUE); // run toward last.
- }
- else
- {
- if (header_only)
- {
- if (head_hit)
- {
- init_run_act(&teams[p_num-1],head_x,head_y,TRUE); //Go to path point!
- }
- }
- else
- {
- if (feet_hit)
- {
- init_run_act(&teams[p_num-1],feet_x,feet_y,TRUE); //pitch line point
- }
- else
- if (head_hit)
- {
- init_run_act(&teams[p_num-1],head_x,head_y,TRUE); //Go to path point!
- }
- else
- if (body_hit)
- {
- init_run_act(&teams[p_num-1],body_x,body_y,TRUE); //Go to path point!
- }
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void get_tack_path(match_player *player)
- // Find players intersection with ball path.
- // When tackling!
- {
- if (teams[ball_poss-1].tm_poss>4)
- {
- // Opponent has ball for a bit...
- flag=FALSE;
- float x,y,z;
- float d,s;
- float px=player->tm_x;
- float py=player->tm_y;
- float rate=player->tm_rate+player->tm_pow;
- float last_diff=2000;
- if (((ball_poss) && (teams[ball_poss-1].tm_act==STAND_ACT))
- || ((!ball_poss) && (ball_still)))
- // Ball is not moving!
- if (plr_facing(ballx,bally,player))
- init_tackle_act(player,ballx,bally); //Go to path point!
- else
- go_to_path(player->tm_player);
- else
- {
- for (int i=1; i<TACKLE_TURNS/2; i++)
- {
- x=ball_pred_tab[i][0];
- y=ball_pred_tab[i][1];
- z=ball_pred_tab[i][2];
- if ((x<0) || (x>=pitch_len) || (y<0) || (y>=pitch_wid))
- // Ball out of bounds (So don't tackle!)
- i=60;
- if (z<=PLAYER_HEIGHT/2)
- // Tackling player is half height.
- {
- d=calc_dist(x-px,y-py);
- // Now the tricky bit...
- // Using S=a(1-r^n)/(1-r) (S=tackle distance over time (n))
- // a=(rate/8), r=tackle_decel...
- s=(rate/20)*(1-pow(TACKLE_DECEL,i))/(1-TACKLE_DECEL); //How far in time (i)!
- if (d-s>last_diff)
- // Ball getting further away!
- i=60; // End For Loop!
- else
- last_diff=d-s;
- if (last_diff<=0)
- // He can get there in time!
- {
- // Take accuracy into account...
- float acc_xoff=(seed*(128-player->tm_ac)/4)/128;
- af_randomize();
- float acc_yoff=(seed*(128-player->tm_ac)/4)/128;
- if (seed&32)
- acc_xoff=-acc_xoff;
- if (seed&16)
- acc_yoff=-acc_yoff;
- if (player->tm_player!=KP_A && player->tm_player!=KP_B)
- // init_tackle_act(player,x+acc_xoff,y+acc_yoff); //Go to path point!
- init_tackle_act(player,x,y);
- else
- // Keeper more accurate to provide better defense...
- init_tackle_act(player,x,y);
- flag=TRUE;
- i=60; // End For Loop!
- }
- }
- }
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void set_there_flags(short taker)
- {
- #ifdef EURO96
- if ((teams[taker-1].tm_act==STAND_ACT && plr_facing(ballx-teams[taker-1].tm_x,bally-teams[taker-1].tm_y,&teams[taker-1]))
- && (teams[taker-1].tm_dist<BESIDE_BALL*3
- || ((match_mode==PEN_KICK_A || match_mode==PEN_KICK_B) && teams[taker-1].tm_dist<(PEN_RUNUP_DIST+4))))
- #else
- if ((teams[taker-1].tm_act==STAND_ACT && plr_facing(ballx-teams[taker-1].tm_x,bally-teams[taker-1].tm_y,&teams[taker-1]))
- && (teams[taker-1].tm_dist<BESIDE_BALL*3))
- #endif
- {
- if (!already_there)
- {
- reselection=TRUE;
- already_there=TRUE;
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void centre_pos(char flag,int pn,char &flag2,float &x,float &y)
- {
- // Taking centre!
- {
- if (((pn+1==centre_guy_1) && (flag==1))
- || ((pn+1==centre_guy_1-11) && (flag==2)))
- {
- x=cntspot_x;
- y=cntspot_y-10;
- flag2=TRUE;
- set_there_flags(centre_guy_1);
- }
- if (((pn+1==centre_guy_2) && (flag==1))
- || ((pn+1==centre_guy_2-11) && (flag==2)))
- {
- if (flag==1)
- x=cntspot_x+5;
- else
- x=cntspot_x-5; // Receiver stands over line...
- y=cntspot_y+10;
- flag2=TRUE;
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void gkick_pos(char flag,int pn,char &flag2,float &x,float &y,char &taker)
- {
- // Taking Goal kick!
- {
- if (((pn+1==gkick_taker) && (flag==1))
- || ((pn+1==gkick_taker-11) && (flag==2)))
- {
- x=taker_x;
- y=taker_y;
- taker=TRUE;
- flag2=TRUE;
- if (flag==2)
- {
- x=pitch_len-x;
- y=pitch_wid-y;
- }
- set_there_flags(gkick_taker);
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void corner_pos(char flag,int pn,char &flag2,float &x,float &y,char &taker)
- {
- // Taking Corner!
- {
- if (((pn+1==corner_taker) && (flag==1))
- || ((pn+1==corner_taker-11) && (flag==2)))
- {
- x=incident_x;
- y=incident_y;
- taker=TRUE;
- flag2=TRUE;
- if (flag==2)
- {
- x=pitch_len-x;
- y=pitch_wid-y;
- }
- set_there_flags(corner_taker);
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void throw_in_pos(char flag,int pn,char &flag2,float &x,float &y,char &taker)
- {
- // Taking throw!
- {
- if (flag==2)
- pn=pn+11;
- if (pn+1==throw_in_taker)
- {
- x=incident_x;
- y=incident_y+((incident_y<cntspot_y) ? -8:8);
- taker=TRUE;
- flag2=TRUE;
- if (flag==2)
- {
- x=pitch_len-x;
- y=pitch_wid-y;
- }
- set_there_flags(throw_in_taker);
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void dfkick_pos(char flag,int pn,char &flag2,float &x,float &y,char &taker)
- {
- // Taking F.K.!
- {
- if (flag==2)
- pn=pn+11;
- if (pn+1==fkick_taker)
- {
- x=taker_x;
- y=taker_y;
- taker=TRUE;
- flag2=TRUE;
- if (flag==2)
- {
- x=pitch_len-x;
- y=pitch_wid-y;
- }
- set_there_flags(fkick_taker);
- }
- else
- {
- if (teams[pn].tm_wall)
- {
- for (int i=0; i<men_in_wall; i++)
- {
- if (wguys[i].guy==pn+1)
- {
- x=wguys[i].x;
- y=wguys[i].y;
- flag2=TRUE;
- i=men_in_wall;
- if (flag==2)
- {
- x=pitch_len-x;
- y=pitch_wid-y;
- }
- }
- }
- }
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void fkick_pos(char flag,int pn,char &flag2,float &x,float &y,char &taker)
- {
- // Taking F.K.!
- {
- if (flag==2)
- pn=pn+11;
- if (pn+1==fkick_taker)
- {
- x=taker_x;
- y=taker_y;
- taker=TRUE;
- flag2=TRUE;
- if (flag==2)
- {
- x=pitch_len-x;
- y=pitch_wid-y;
- }
- set_there_flags(fkick_taker);
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void penalty_pos(char flag,int pn,char &flag2,float &x,float &y,char &taker)
- {
- // Taking F.K.!
- {
- if (flag==2)
- pn=pn+11;
- if (pn+1==penalty_taker)
- {
- x=taker_x;
- y=taker_y;
- taker=TRUE;
- flag2=TRUE;
- if (flag==2)
- {
- x=pitch_len-x;
- y=pitch_wid-y;
- }
- set_there_flags(penalty_taker);
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void tunnel_pos(char flag,int pn,float &x,float &y)
- {
- float tx=stadlist[setup.stadium].tunlx;
- float ty=-stadlist[setup.stadium].tunlz;
- float tz=stadlist[setup.stadium].tunly;
- float d=GO_TO_POS_DIST;
- if (flag==2)
- {
- // Team B...
- pn+=11;
- if (ABS(teams[pn].go_ty-ty)<prat ||
- (teams[pn].tm_x>=(tx+prat-d) && teams[pn].tm_x<=(tx+prat+d)))
- {
- // In line with tunnel...
- x=pitch_len-(tx+prat);
- y=pitch_wid-(ty);
- if (ABS(teams[pn].tm_y-(pitch_wid-y))<prat*2)
- {
- // At end of tunnel...(don't draw him!)
- teams[pn].draw_me=FALSE;
- }
- }
- else
- {
- x=pitch_len-(tx+prat);
- if (ty>cntspot_y)
- // Which goal-line...
- y=0;
- else
- y=pitch_wid;
- }
- }
- else
- {
- // Team A...
- if (ABS(teams[pn].go_ty-ty)<prat ||
- (teams[pn].tm_x>=(tx-prat-d) && teams[pn].tm_x<=(tx-prat+d)))
- {
- // In line with tunnel...
- x=tx-prat;
- y=ty;
- if (ABS(teams[pn].tm_y-y)<prat*2)
- {
- // At end of tunnel...(don't draw him!)
- teams[pn].draw_me=FALSE;
- }
- }
- else
- {
- x=tx-prat;
- if (ty>cntspot_y)
- // Which goal-line...
- y=pitch_wid;
- else
- y=0;
- }
- }
- set_there_flags(pn+1);
- }
-
- /******************************************************************************
- *****************************************************************************/
- int get_tac(int *t)
- {
- // (*t)++;
- // (*t)--;
- return(*t);
- }
- /******************************************************************************
- *****************************************************************************/
- void get_target(char flag,int bz,int zx,int zy,int pn,float &x,float &y,int tac[(32*2)+6][10][2])
- {
- float ox,oy;
- char flag2=FALSE;
- char taker=FALSE;
- if (dead_ball_cnt)
- {
- if (match_mode==SWAP_ENDS)
- // Into tunnel...
- {
- tunnel_pos(flag,pn,x,y);
- flag2=TRUE;
- }
- if (((match_mode==CENTRE_A) && (flag==1))
- || ((match_mode==CENTRE_B) && (flag==2)))
- // Centre takers...
-
- centre_pos(flag,pn,flag2,x,y);
- if (((match_mode==GOAL_KICK_TL) || (match_mode==GOAL_KICK_BL) && (flag==1))
- || ((match_mode==GOAL_KICK_TR) || (match_mode==GOAL_KICK_BR) && (flag==2)))
- // Goal kick takers...
- gkick_pos(flag,pn,flag2,x,y,taker);
- if (((match_mode==CORNER_TL) || (match_mode==CORNER_BL) && (flag==2))
- || ((match_mode==CORNER_TR) || (match_mode==CORNER_BR) && (flag==1)))
- // Corner takers...
- corner_pos(flag,pn,flag2,x,y,taker);
- if ((match_mode==THROW_IN_A) || (match_mode==THROW_IN_B))
- // Throw-in taker...
- throw_in_pos(flag,pn,flag2,x,y,taker);
- if ((match_mode==DF_KICK_A) || (match_mode==DF_KICK_B))
- // Direct F.K....
- dfkick_pos(flag,pn,flag2,x,y,taker);
- if ((match_mode==IF_KICK_A) || (match_mode==IF_KICK_B))
- // In-direct F.K....
- fkick_pos(flag,pn,flag2,x,y,taker);
- if ((match_mode==PEN_KICK_A) || (match_mode==PEN_KICK_B))
- // Penalty Kick....
- penalty_pos(flag,pn,flag2,x,y,taker);
- }
- if (!flag2)
- /**************************/
- // Normal match play!
- {
- if ((man2man_b) && (flag==2) && (teams[pn+11].tm_mark))
- {
- // Team B defends man-to-man...
- x=pitch_len-man2man[pn-1][0];
- y=pitch_wid-man2man[pn-1][1];
- }
- else
- {
- if ((man2man_a) && (flag==1) && (teams[pn].tm_mark))
- {
- // Team A defends man-to-man...
- x=man2man[pn-1][0];
- y=man2man[pn-1][1];
- }
- else
- {
- // Normal Zonal Position...
- x=get_tac(&tac[bz][pn-1][0]);
- y=get_tac(&tac[bz][pn-1][1]);
- if (flag==1 && bz==68 && pn==centre_guy_2-1)
- {
- x=cntspot_x+80;
- y=cntspot_y+10;
- flag=0;
- }
- if (flag==2 && bz==69 && pn==centre_guy_2-12)
- {
- x=cntspot_x-80;
- y=cntspot_y+10;
- flag=0;
- }
- if (flag)
- {
- float bx=LIMIT(ballx,0,pitch_len);
- float by=LIMIT(bally,0,pitch_wid);
- if ((analogue) && (!ball_out_of_play) &&
- ((!dead_ball_cnt) || (match_mode<CORNER_TL) || (match_mode>THROW_IN_B)))
- {
- if (flag==1)
- {
- ox=bx-zx; // offset from centre of zone!
- oy=by-zy;
- }
- else
- {
- ox=(pitch_len-bx)-zx; // offset from centre of zone!
- oy=(pitch_wid-by)-zy;
- }
- float xa,xb,xc,ya,yb,yc;
- if (ox<=0)
- {
- int b=bz-1;
- if (b<0)
- b=0;
- xa=get_tac(&tac[b][pn-1][0]); //left zone
- ya=get_tac(&tac[b][pn-1][1]); //left zone
- if (oy<=0)
- {
- b=bz-8-1;
- if (b<0)
- b=0;
- xb=get_tac(&tac[b][pn-1][0]); //top left zone
- yb=get_tac(&tac[b][pn-1][1]); //top left zone
- xc=get_tac(&tac[b+1][pn-1][0]); //top zone
- yc=get_tac(&tac[b+1][pn-1][1]); //top zone
- }
- else
- {
- b=bz+8;
- if (b>31)
- b=31;
- xb=get_tac(&tac[b-1][pn-1][0]); //bot left zone
- yb=get_tac(&tac[b-1][pn-1][1]); //bot left zone
- xc=get_tac(&tac[b][pn-1][0]); //bot zone
- yc=get_tac(&tac[b][pn-1][1]); //bot zone
- }
- }
- else
- {
- int b=bz+1;
- if (b>31)
- b=31;
- xa=get_tac(&tac[b][pn-1][0]); //right zone
- ya=get_tac(&tac[b][pn-1][1]); //right zone
- if (oy<=0)
- {
- b=bz-8;
- if (b<0)
- b=0;
- xb=get_tac(&tac[b+1][pn-1][0]); //top right zone
- yb=get_tac(&tac[b+1][pn-1][1]); //top right zone
- xc=get_tac(&tac[b][pn-1][0]); //top zone
- yc=get_tac(&tac[b][pn-1][1]); //top zone
- }
- else
- {
- b=bz+8+1;
- if (b>31)
- b=31;
- xb=get_tac(&tac[b][pn-1][0]); //bot right zone
- yb=get_tac(&tac[b][pn-1][1]); //bot right zone
- xc=get_tac(&tac[b-1][pn-1][0]); //bot zone
- yc=get_tac(&tac[b-1][pn-1][1]); //bot zone
- }
- }
- float xint_ab=xa+((xb-xa)*ABS(oy)/zone_hgt);
- float xint_hc=x+((xc-x)*ABS(oy)/zone_hgt);
- float yint_cb=yc+((yb-yc)*ABS(ox)/zone_wid);
- float yint_ha=y+((ya-y)*ABS(ox)/zone_wid);
- x=xint_hc+((xint_ab-xint_hc)*ABS(ox)/zone_wid);
- y=yint_ha+((yint_cb-yint_ha)*ABS(oy)/zone_hgt);
- }
- }
- }
- }
- float xoff,yoff;
- if (flag)
- {
- if (flag==1)
- {
- xoff=x-incident_x;
- yoff=y-incident_y;
- }
- else
- {
- xoff=(pitch_len-x)-incident_x;
- yoff=(pitch_wid-y)-incident_y;
- }
- }
- switch(game_action)
- {
- float dist;
- // Team A and B must be 10 yards away from ball!
- case(-1):
- case(1):
- dist=calc_dist(xoff,yoff);
- if (dist<prat*10)
- {
- if (flag==1)
- {
- x=incident_x+(xoff*(INCIDENT_DIST)/dist);
- y=incident_y+(yoff*(INCIDENT_DIST)/dist);
- }
- else
- {
- x=pitch_len-(incident_x+(xoff*(INCIDENT_DIST)/dist));
- y=pitch_wid-(incident_y+(yoff*(INCIDENT_DIST)/dist));
- }
- }
- break;
- // Team A and B must be 10 yards away from ball and outside penalty box!
- case(2):
- if (ballx<cntspot_x)
- if (flag==1)
- x=prat*19;
- else
- x=pitch_len-(prat*19);
- else
- if (flag==1)
- x=pitch_len-(prat*19); // On edge of 18 yard box!
- else
- x=prat*19;
- if (flag==1)
- {
- xoff=x-incident_x;
- yoff=y-incident_y;
- }
- else
- {
- xoff=(pitch_len-x)-incident_x;
- yoff=(pitch_wid-y)-incident_y;
- }
- dist=calc_dist(xoff,yoff);
- if (dist<prat*10)
- {
- if (flag==1)
- {
- x=incident_x+(xoff*(INCIDENT_DIST)/dist);
- y=incident_y+(yoff*(INCIDENT_DIST)/dist);
- }
- else
- {
- x=pitch_len-(incident_x+(xoff*(INCIDENT_DIST)/dist));
- y=pitch_wid-(incident_y+(yoff*(INCIDENT_DIST)/dist));
- }
- }
- break;
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void find_zonal_target(match_player *player,float px,float py)
- {
- if (!player->draw_me && player->tm_y>0 && player->tm_y<pitch_wid)
- player->draw_me=TRUE;
- int ball_zn;
- char f;
- float tx,ty,sx,sy;
- if ((player->tm_player==KP_A) || (player->tm_player==KP_B))
- {
- /****************
- ** Goal-Keeper **
- ****************/
- if (player->tm_player==KP_A)
- {
- if ((dead_ball_cnt) && (gkick_taker==KP_A) &&
- ((match_mode==GOAL_KICK_TL) || (match_mode==GOAL_KICK_BL)))
- {
- // Taking Goal Kick!
- tx=taker_x;
- ty=taker_y;
- set_there_flags(gkick_taker);
- }
- else
- {
- if (match_mode==DF_KICK_B && men_in_wall>2)
- {
- // Get keeper in position behind last man in wall...
- tx=keeper_pos_x;
- ty=keeper_pos_y;
- }
- else
- {
- if (match_mode==SWAP_ENDS)
- {
- get_target(1,ball_zn,zone1_x,zone1_y,(player->tm_player)-1,tx,ty,match_tactics1);
- }
- else
- {
- if (ball_poss>=12 && match_mode!=PEN_KICK_B && !penalty_shot)
- {
- // Opponent_has ball...
- float d=calc_dist(ballx,bally-cntspot_y); // distance of centre of goal to ball!
- if ((keeper_a_in_box) && (d<CLOSE_ANG_DIST+(prat*player->tm_vis)/8))
- // Shut the door...
- close_angle(player,d,tx,ty); // Close down the angle of shot.
- else
- {
- tx=KP_OFFLINE;
- ty=cntspot_y-1;
- }
- }
- else
- {
- if (match_mode==PEN_KICK_B)
- tx=0;
- else
- if (shot_pending && penalty_shot)
- tx=0;
- else
- tx=KP_OFFLINE;
- ty=cntspot_y-1;
- }
- }
- }
- }
- }
- else
- {
- if ((dead_ball_cnt) && (gkick_taker==KP_B) &&
- ((match_mode==GOAL_KICK_TR) || (match_mode==GOAL_KICK_BR)))
- {
- // Taking Goal Kick!
- tx=taker_x;
- ty=taker_y;
- set_there_flags(gkick_taker);
- }
- else
- {
- if (match_mode==DF_KICK_A && men_in_wall>2)
- {
- // Get keeper in position behind last man in wall...
- tx=keeper_pos_x;
- ty=keeper_pos_y;
- }
- else
- {
- if (match_mode==SWAP_ENDS)
- {
- get_target(2,ball_zn,zone2_x,zone2_y,(player->tm_player)-12,tx,ty,match_tactics2);
- tx=pitch_len-tx;
- ty=pitch_wid-ty;
- }
- else
- {
- if (ball_poss && ball_poss<12 && match_mode!=PEN_KICK_A && !penalty_shot)
- {
- // Opponent_has ball...
- float d=calc_dist(pitch_len-ballx,bally-cntspot_y); // distance of centre of goal to ball!
- if ((keeper_b_in_box) && (d<CLOSE_ANG_DIST+(prat*player->tm_vis)/8))
- // Shut the door...
- close_angle(player,d,tx,ty); // Close down the angle of shot.
- else
- {
- tx=pitch_len-KP_OFFLINE;
- ty=cntspot_y-1;
- }
- }
- else
- {
- if (match_mode==PEN_KICK_A)
- tx=pitch_len-1;
- else
- if (shot_pending && penalty_shot)
- tx=pitch_len-1;
- else
- tx=pitch_len-KP_OFFLINE;
- ty=cntspot_y-1;
- }
- }
- }
- }
- }
- tx=tx-px;
- ty=ty-py;
- char s;
- float d=calc_dist(tx,ty);
- if ((player->face_dir!=get_dir(tx,ty)) &&
- (((player->go_step) && (d<STEP_RANGE*2))
- || ((!player->go_step) && (d<STEP_RANGE))))
- // Calculate single move.
- {
- s=TRUE;
- if (player->tm_rate>=d*32)
- {
- sx=tx;
- sy=ty;
- }
- else
- {
- sx=(player->tm_rate/(d*32))*tx;
- sy=(player->tm_rate/(d*32))*ty;
- }
- }
- else
- {
- // Calculate single move.
- if (player->tm_rate>=d*16)
- {
- sx=tx;
- sy=ty;
- }
- else
- {
- sx=(player->tm_rate/(d*16))*tx;
- sy=(player->tm_rate/(d*16))*ty;
- }
- }
- init_run_act(player,tx+px,ty+py,TRUE);
- if (player->tm_act==RUN_ACT)
- {
- go_forward(player);
- player->go_cnt=0;
- }
- }
- else
- {
- /***********
- ** PLAYER **
- ***********/
- if (!player->int_cnt)
- {
- if (player->tm_player<12) // Team A?
- {
- if ((ball_zone1<32) && (last_touch<12) && (last_touch!=0)) // Team A. in possession?
- ball_zn=32;
- else
- ball_zn=0;
- ball_zn+=ball_zone1;
- get_target(1,ball_zn,zone1_x,zone1_y,(player->tm_player)-1,tx,ty,match_tactics1);
- tx=tx-px;
- ty=ty-py;
- float d=calc_dist(tx,ty);
- if ((player->tm_act==RUN_ACT) ||
- (d>GO_TO_POS_DIST && player->tm_act!=RUN_ACT))
- {
- char s;
- float d=calc_dist(tx,ty);
- if ((player->face_dir!=get_dir(tx,ty)) &&
- (((player->go_step) && (d<STEP_RANGE*2))
- || ((!player->go_step) && (d<STEP_RANGE))))
- {
- s=TRUE;
- }
- else
- {
- s=FALSE;
- }
- init_run_act(player,tx+px,ty+py,TRUE);
- if (player->tm_act==RUN_ACT)
- {
- go_forward(player);
- player->go_cnt=0;
- }
- }
- else
- {
- // There already!
- if (player->int_move==I_THROW)
- {
- player->int_cnt=1;
- reset_ideas(player);
- }
- }
- }
- else
- {
- if ((ball_zone2<32) && last_touch>11) // Team B. in possession?
- ball_zn=32;
- else
- ball_zn=0;
- ball_zn+=ball_zone2;
- get_target(2,ball_zn,zone2_x,zone2_y,(player->tm_player)-12,tx,ty,match_tactics2);
- tx=(pitch_len-tx)-px;
- ty=(pitch_wid-ty)-py;
- float d=calc_dist(tx,ty);
- if ((player->tm_act==RUN_ACT) ||
- (d>GO_TO_POS_DIST && player->tm_act!=RUN_ACT))
- {
- char s;
- float d=calc_dist(tx,ty);
- if ((player->face_dir!=get_dir(tx,ty)) &&
- ((player->go_step) && (d<STEP_RANGE*2))
- || ((!player->go_step) && (d<STEP_RANGE)))
- // Calculate single move.
- {
- s=TRUE;
- }
- else
- {
- s=FALSE;
- }
- init_run_act(player,tx+px,ty+py,TRUE);
- if (player->tm_act==RUN_ACT)
- {
- go_forward(player);
- player->go_cnt=0;
- }
- }
- else
- {
- // There already!
- if (player->int_move==I_THROW)
- {
- player->int_cnt=1;
- reset_ideas(player);
- }
- }
- }
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- // Return closest guy to the predicted path of ball who is not busy!
- // p_num = first player in team.
- int get_near_path(int p_num,int not_busy)
- {
- int near_guy=0, closest=10000;
- int t=0;
- // Get average position of ball...
- float x1=ball_pred_tab[t][0];
- float y1=ball_pred_tab[t][1];
- float z1=ball_pred_tab[t][2];
- float px,py;
- short points=0;
- float x=-1000;
- float y=0;
- float z=0;
- float d;
- for (int b=1; b<40; b++)
- {
- if (x<-999 && ball_pred_tab[b][2]<PLAYER_HEIGHT+4)
- {
- x=ball_pred_tab[b][0]-x1;
- y=ball_pred_tab[b][1]-y1;
- }
- else
- {
- if (x>-999)
- {
- x+=ball_pred_tab[b][0]-x1;
- y+=ball_pred_tab[b][1]-y1;
- points++;
- }
- }
- }
- if (points)
- {
- x=x/points;
- y=y/points;
- x+=x1;
- y+=y1;
- }
- else
- {
- x=ball_pred_tab[40][0];
- y=ball_pred_tab[40][1];
- }
- for (int i=p_num+10; i>=p_num; i--)
- {
- if (teams[i].tm_notme)
- teams[i].tm_notme--; // he can't get there!
- else
- {
- if ((teams[i].tm_act<=TURN_ACT || (teams[i].tm_act==TACKLE_ACT && teams[i].control))
- && ball_poss!=p_num+1) //player is not busy!
- {
- if ((!(teams[i].int_cnt)) || (not_busy))
- {
- px=teams[i].tm_x;
- py=teams[i].tm_y;
- d=calc_dist(px-x,py-y);
- if (i==(KP_A-1) || i==(KP_B-1))
- {
- // Keeper only intercept if half as close as defender!
- if (d*2<closest && closest>prat*2)
- {
- near_guy=i+1; //This guy is closer!
- closest=d;
- }
- }
- else
- {
- if (d<closest)
- {
- near_guy=i+1; //This guy is closer!
- closest=d;
- }
- }
- }
- }
- }
- }
- return(near_guy);
- }
- /******************************************************************************
- *****************************************************************************/
- // Return closest guy to the predicted path of ball who is not busy!
- // p_num = first player in team.
- int oget_near_path(int p_num,int not_busy)
- {
- int near_guy=0, closest=10000;
- int t=first_bounce;
- if (t<0)
- t=0;
- // Get average position of ball...
- float x1=ball_pred_tab[t][0];
- float y1=ball_pred_tab[t][1];
- float z1=ball_pred_tab[t][2];
- float px,py;
- short points=0;
- float x=0;
- float y=0;
- float z=0;
- float d;
- for (int b=t+1; b<40; b++)
- {
- if (ball_pred_tab[b][2]<PLAYER_HEIGHT+4)
- {
- x+=ball_pred_tab[b][0]-x1;
- y+=ball_pred_tab[b][1]-y1;
- points++;
- }
- }
- if (points)
- {
- x=x/points;
- y=y/points;
- x+=x1;
- y+=y1;
- }
- else
- {
- x=ball_pred_tab[40][0];
- y=ball_pred_tab[40][1];
- }
- for (int i=p_num+10; i>=p_num; i--)
- {
- if (teams[i].tm_notme)
- teams[i].tm_notme--; // he can't get there!
- else
- {
- if (teams[i].tm_act<=TURN_ACT && ball_poss!=p_num+1) //player is not busy!
- {
- if ((!(teams[i].int_cnt)) || (not_busy))
- {
- px=teams[i].tm_x;
- py=teams[i].tm_y;
- d=calc_dist(px-x,py-y);
- if (i==(KP_A-1) || i==(KP_B-1))
- {
- // Keeper only intercept if half as close as defender!
- if (d*2<closest && closest>prat*2)
- {
- near_guy=i+1; //This guy is closer!
- closest=d;
- }
- }
- else
- {
- if (d<closest)
- {
- near_guy=i+1; //This guy is closer!
- closest=d;
- }
- }
- }
- }
- }
- }
- return(near_guy);
- }
- /******************************************************************************
- *****************************************************************************/
- void forward_joystick(match_player *p,float &x,float &y)
- {
- x=p->go_txdis;
- y=p->go_tydis;
- if (ux)
- {
- // Turn!
- float ta=(PI/12)*ux;
- float nx=x*cos(ta)-y*sin(ta);
- float ny=y*cos(ta)+x*sin(ta);
- x=nx;
- y=ny;
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void get_face_xy(int d,float &x,float &y)
- {
- switch(d)
- {
- case(0):
- x=-UNIT;
- y=0;
- break;
-
- case(1):
- x=-DIAG;
- y=DIAG;
- break;
- case(2):
- x=0;
- y=UNIT;
- break;
-
- case(3):
- x=DIAG;
- y=DIAG;
- break;
- case(4):
- x=UNIT;
- y=0;
- break;
-
- case(5):
- x=DIAG;
- y=-DIAG;
- break;
- case(6):
- x=0;
- y=-UNIT;
- break;
-
- case(7):
- x=-DIAG;
- y=-DIAG;
- break;
- }
- }
- /******************************************************************************
- *****************************************************************************/
- int get_dir(float x,float y)
- {
- int d=0;
- if (y>=0)
- {
- if (x>=0)
- {
- if (x>y)
- {
- if (x>(y*2))
- d=4;
- else
- d=3;
- }
- else
- {
- if (y>(x*2))
- d=2;
- else
- d=3;
- }
- }
- else
- {
- if (-x>y)
- {
- if (-x>(y*2))
- d=0;
- else
- d=1;
- }
- else
- {
- if (y>(-x*2))
- d=2;
- else
- d=1;
- }
- }
- }
- else
- {
- if (x>=0)
- {
- if (x>-y)
- {
- if (x>(-y*2))
- d=4;
- else
- d=5;
- }
- else
- {
- if (-y>(x*2))
- d=6;
- else
- d=5;
- }
- }
- else
- {
- if (-x>-y)
- {
- if (-x>(-y*2))
- d=0;
- else
- d=7;
- }
- else
- {
- if (-y>(-x*2))
- d=6;
- else
- d=7;
- }
- }
- }
- return(d);
- }
- /******************************************************************************
- *****************************************************************************/
- int angle_of_vis(match_player *player,int x,int y,float d,char cross=FALSE)
- {
- float a;
- float xd=player->tm_xdis;
- float yd=player->tm_ydis;
- float d2=calc_dist(xd,yd);
- xd=xd/d2;
- yd=yd/d2;
- if (cross)
- {
- if (player->tm_player<12)
- // Team A...
- {
- if ((d/2>(MIN_PASS_DIST+(float)player->tm_pow/3.6)) && (x+player->tm_x>pitch_len-(prat*18)))
- return(TRUE);
- else
- return(FALSE);
- }
- else
- // Team B...
- {
- if ((d/2>(MIN_PASS_DIST+(float)player->tm_pow/3.6)) && (x+player->tm_x<(prat*18)))
- return(TRUE);
- else
- return(FALSE);
- }
- }
- if (set_piece_on)
- a=((x*setp_kick_x)+(y*setp_kick_y))/d; // Joystick dir.
- else
- a=((x*xd)+(y*yd))/d; // facing...
- if (a>=DIAG)
- return(TRUE);
- else
- return(FALSE);
- }
- /******************************************************************************
- *****************************************************************************/
- // Creates table of opponents round player within DRIB_DANGER_AREA.
- void get_opp_dir_tab(int pnum)
- {
- float dist=DRIB_DANGER_AREA+(prat*(((128-teams[pnum-1].tm_flair)/12)-5));
- drib_opps=0;
- int op=1;
- if (pnum<12)
- op=12;
- float x,y,d,dif;
- for (int p=op; p<op+11; p++)
- {
- // Vectors for opp. to ball...
- x=(teams[p-1].tm_x-ballx)/teams[p-1].tm_dist;
- y=(teams[p-1].tm_y-bally)/teams[p-1].tm_dist;
-
- // Calculate difference range of 2(ahead) to 0(behind)...
- dif=1+((teams[pnum-1].tm_xdis*x)+(teams[pnum-1].tm_ydis*y));
- d=dist/4+(dist*dif*3/8);
- if (teams[p-1].guy_on && teams[p-1].tm_dist<=d && teams[p-1].tm_act<TURN_ACT)
- {
- // if (!(teams[p-1].tm_act==TACKLE_ACT && ((teams[p-1].go_txdis*teams[p-1].go_tydis)<4)))
- {
- opp_dir_tab[drib_opps][0]=teams[p-1].tm_x;
- opp_dir_tab[drib_opps][1]=teams[p-1].tm_y;
- opp_dir_tab[drib_opps][2]=1-(teams[pnum-1].tm_dist/d); // Attack potential
- drib_opps++;
- }
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- // Count the number of opponents around player (pnum)!
- int opp_around(int x,int y,int pnum)
- {
- int op=1;
- int d;
- int opponents=0;
- if (pnum<12)
- op=12;
- for (int p=op; p<op+11; p++)
- {
- if (teams[p-1].guy_on)
- {
- d=calc_dist(teams[p-1].tm_x-x,teams[p-1].tm_y-y);
- if (ball_poss==KP_A || ball_poss==KP_B)
- {
- if (d<=(DANGER_AREA*1.6))
- opponents++;
- }
- else
- {
- if (d<=DANGER_AREA)
- opponents++;
- }
- }
- }
- return(opponents);
- }
- /******************************************************************************
- *****************************************************************************/
- // Count the number of opponents around player (pnum)!
- // This function specific to keeper passing out...
- int kopp_around(int x,int y,int pnum)
- {
- int op=1;
- int d;
- int opponents=0;
- if (pnum<12)
- op=12;
- for (int p=op; p<op+11; p++)
- {
- if (teams[p-1].guy_on)
- {
- d=calc_dist(teams[p-1].tm_x-x,teams[p-1].tm_y-y);
- if (d<=(DANGER_AREA*2))
- opponents++;
- }
- }
- return(opponents);
- }
- /******************************************************************************
- *****************************************************************************/
- float facing_opp(match_player *player,short opp)
- {
- float xd=player->tm_xdis;
- float yd=player->tm_ydis;
- float xo=teams[opp-1].tm_xdis;
- float yo=teams[opp-1].tm_ydis;
- float a=((xo*xd)+(yo*yd));
- return(a);
- }
- /******************************************************************************
- *****************************************************************************/
- void player_ints(match_player *player)
- {
- if (((player->tm_act==TACKLE_ACT && player->go_cnt>EFFECTIVE_TACK)
- || (player->tm_act==STEAL_ACT && player->tm_frm>0.4 && player->tm_frm<0.6))
- && (!dead_ball_cnt) && (!just_scored))
- {
- float x,y,z;
- float dir;
- short chance;
- for (int i=1; i<=players; i++)
- {
- if (teams[i-1].tm_act<=TURN_ACT)
- {
- x=player->tm_x-teams[i-1].tm_x;
- y=player->tm_y-teams[i-1].tm_y;
- z=player->tm_y-teams[i-1].tm_y;
- if ((calc_dist(x,y)<=PLAYER_SIZE) && (z<PLAYER_HEIGHT/3))
- {
- // If the tackling player comes in from behind or the side
- // then he has a greater chance of bringing the opponent down!
- dir=facing_opp(player,i);
- chance=seed/(dir+2);
- if (chance<(42+((player->tm_pow-teams[i-1].tm_pow)/3)))
- {
- // Crunching tackle...
- init_fall(&teams[i-1]);
- // if ((!player->go_step) && ((player_num<12 && i>11) || (player_num>11 && i<12)))
- if (((player_num<12 && i>11) || (player_num>11 && i<12)))
- {
- // He is in opposing team!
- // He hasn't made contact with ball...
- // Therefore a foul has been commited...
- man_down=calc_dist(player->go_txdis,
- player->go_tydis);
- init_foul(player->tm_player,TRUE); // pass no. of fouler.
- // Man appeals for f.k...
- init_speech(i,SAY_REF,REAL_SPEED);
- }
- }
- else
- // Ride over tackle...
- if (player->tm_act!=STEAL_ACT)
- init_jump_act(&teams[i-1],TRUE,TRUE);
- }
- }
- }
- }
- }
- /*****************************************************************************
- *****************************************************************************/
- char cross_angle(float xd,float yd,float x,float y)
- {
- float a=angle_to_xy(xd,yd,x,y);
- if (a>-0.174 && a<0.707)
- // In 55 degree threshold (100 -> 45)...
- {
- if ((xd*y)>(yd*x))
- return(1);
- else
- return(2);
- }
- else
- return(0);
- }
- /*****************************************************************************
- *****************************************************************************/
- void new_interceptor(int p)
- {
- if (p<12)
- {
- // Team A...
- if (interceptor_a)
- {
- reset_ideas(&teams[interceptor_a-1]);
- }
- receiver_a=p;
- near_path_a=p; // Fake passee as nearest!
- }
- else
- {
- // Team B...
- if (interceptor_b)
- {
- reset_ideas(&teams[interceptor_b-1]);
- }
- receiver_b=p;
- near_path_b=p; // Fake passee as nearest!
- }
- #ifdef EURO96 // 1-2 Pass.
- if (uf1)
- // Force receiver to return ball again to complete 1-2!
- {
- return_12=p;
- }
- else
- {
- return_12=FALSE;
- reselect(); // Can control receiver.
- }
- #else
- reselect();
- #endif
- }
- /*****************************************************************************
- *****************************************************************************/
- int pass_ahead(int ps,float &x,float &y,float &pass_speed,float &end_speed,char cross)
- {
- int i=0;
- int t;
- float a,b,s;
- a=x;
- b=y;
- float xd,yd,dd;
- int extra;
- if (ball_limbo_on)
- extra=((ball_limbo_c-teams[ball_limbo_p-1].tm_frm)/teams[ball_limbo_p-1].tm_fstep)-1;
- else
- extra=0;
- // Get Targets movement...
- xd=teams[ps-1].go_txdis;
- yd=teams[ps-1].go_tydis;
- for (i=1; i<40; i++)
- {
- a+=xd;
- b+=yd; // Inc running time
- dd=calc_dist(a,b);
- if (cross || dd>LOW_PASS_DIST || chip_pass)
- {
- // In air...
- pass_speed=end_speed+4+(dd*(1-AIR_FRICTION));
- t=(log((end_speed+4)/pass_speed))/(log(AIR_FRICTION));
- }
- else
- {
- // On grnd...
- pass_speed=end_speed+(dd*(1-GRND_FRICTION));
- t=(log(end_speed/pass_speed))/(log(GRND_FRICTION));
- }
- if (t<=(i-extra))
- i=1000; // Intersection with run here...
- }
- if (i>=1000)
- {
- // successfull intersection....
- x=a+xd;
- y=b+yd; // new offsets...
- if ((x+ballx)<0)
- x=prat-ballx;
- if ((x+ballx)>pitch_len)
- x=(pitch_len-prat)-ballx;
- if ((y+bally)<0)
- y=prat-bally;
- if ((y+bally)>pitch_wid)
- y=(pitch_wid-prat)-bally;
- if (dd>LOW_PASS_DIST)
- ball_inair=TRUE;
- }
- return(t);
- }
- /*****************************************************************************
- *****************************************************************************/
- void choose_pass(int ps,float &x,float &y,float &pass_speed,float &end_speed,char cross)
- {
- float tx,ty,d;
- if (cross)
- {
- // Cross it ahead of him towards opponents goal...
- if (ps<12)
- // Team B's Goal!
- {
- tx=pitch_len-teams[ps-1].tm_x;
- ty=cntspot_y-teams[ps-1].tm_y;
- }
- else
- // Team A's Goal!
- {
- tx=-teams[ps-1].tm_x;
- ty=cntspot_y-teams[ps-1].tm_y;
- }
- if ((tx<=prat && ps<12) || (tx>-prat && ps>11))
- {
- // Close to goal-line (straight to him instead!)...
- init_stand_act(&teams[ps-1]);
- int t=pass_ahead(ps,x,y,pass_speed,end_speed,cross); // Obviously he isn't moving so it will go straight to him!
- }
- else
- {
- // Target aimed ahead of player towards goal...
- d=calc_dist(tx,ty);
- x+=tx*prat/d;
- y+=ty*prat/d;
- init_stand_act(&teams[ps-1]);
- pass_ahead(ps,x,y,pass_speed,end_speed,cross);
- }
- }
- else
- {
- if (((((ps<12 && teams[ps-1].go_txdis>0) || (ps>11 && teams[ps-1].go_txdis<0))
- && teams[ps-1].tm_act==RUN_ACT)))
- {
- // Pass ahead...
- pass_ahead(ps,x,y,pass_speed,end_speed,cross);
- }
- else
- {
- init_stand_act(&teams[ps-1]);
- int t=pass_ahead(ps,x,y,pass_speed,end_speed,cross); // Obviously he isn't moving so it will go straight to him!
- }
- }
- }
- /*****************************************************************************
- *****************************************************************************/
- void pass_ball(int ps,char cross)
- {
- inc_pass(ball_poss);
- receiver_a=FALSE;
- receiver_b=FALSE;
- float x,y;
- float d;
- int t;
- // Speed of ball at target!
-
- float end_speed;
- float pass_speed;
- if (cross)
- {
- new_shot(ball_poss); // Treat crosses as shots at goal!
- // Hit it harder to cross it in...
- end_speed=7;
- }
- else
- end_speed=5;
- if (ps<=0)
- {
- comm_pass=0; // Default short pass...
- // Must pass but no-one to pass to!
- if (teams[ball_poss-1].tm_act==THROW_ACT)
- {
- x=teams[ball_poss-1].tm_xdis*140; // Far forward!
- y=teams[ball_poss-1].tm_ydis*140;
- }
- else
- {
- if (!user_controlled)
- {
- switch(must_pass)
- {
- case(NORMAL_PLAY):
- x=teams[ball_poss-1].tm_xdis*10; // Tap forward!
- y=teams[ball_poss-1].tm_ydis*10;
- end_speed=(actual_spd(&teams[ball_poss-1]))+0.8;
- break;
- case(CORNER_TR):
- case(CORNER_BR):
- x=pitch_len-(prat*15)-ballx;
- y=cntspot_y-bally;
- break;
- case(CORNER_TL):
- case(CORNER_BL):
- x=(prat*15)-ballx;
- y=cntspot_y-bally;
- break;
- case(CENTRE_A):
- case(CENTRE_B):
- x=cntspot_x-ballx;
- y=cntspot_y-bally;
- break;
- case(IF_KICK_A):
- case(IF_KICK_B):
- case(DF_KICK_A):
- case(DF_KICK_B):
- x=setp_kick_x*160; // Pass forward!
- y=setp_kick_y*160;
- break;
- }
- }
- else
- {
- if (spec_kick_type==SPACT_HPASS || spec_kick_type==SPACT_DPASS
- || spec_kick_type==SPACT_FPASS || spec_kick_type==SPACT_TEE_UP)
- {
- // User set-piece actions which should have been for team-mates...
- if (chip_pass)
- {
- x=setp_kick_x*(prat*16);
- y=setp_kick_y*(prat*16);
- }
- else
- {
- x=setp_kick_x*(prat*14);
- y=setp_kick_y*(prat*14);
- }
- d=calc_dist(x,y);
- }
- if (spec_kick_type==SPACT_GRND)
- {
- x=setp_kick_x*(f2_down*prat);
- y=setp_kick_y*(f2_down*prat);
- d=calc_dist(x,y);
- }
- }
- }
- d=calc_dist(x,y);
- }
- if (ps>0)
- {
- x=teams[ps-1].tm_x-ballx;
- y=teams[ps-1].tm_y-bally;
- d=calc_dist(x,y);
- comm_pass=(int)(d/(LONG_PASS_DIST));
- if (want_pass==ps)
- {
- // team-mate cannot stop!
- pass_ahead(ps,x,y,pass_speed,end_speed,cross);
- }
- else
- {
- choose_pass(ps,x,y,pass_speed,end_speed,cross);
- }
- d=calc_dist(x,y);
- }
- // Get acuracy offsets!
- float ac1,ac2;
- af_randomize();
- if ((ps>0) && (ps!=KP_A) && (ps!=KP_B) && want_pass!=ps)
- // He is passing to an on-the-field player...
- {
- // ac1=Direction offset!
- ac1=((rand_range(128-teams[ball_poss-1].tm_ac))*PASS_ACC_ARC)*D2RAD;
- // ac2=Power offset!
- ac2=((float)(rand_range(128-teams[ball_poss-1].tm_ac)))/32;
- if (seed&64)
- ac1=-ac1;
- }
- else
- {
- ac1=0;
- ac2=0;
- }
- if (!match_info.GameType)
- {
- // Arcade Mode...(Passing is always accurate!)
- ac1=0;
- ac2=0;
- }
- float nx,ny,ox,oy;
-
- ox=x/d;
- oy=y/d;
- nx=(ox*cos(ac1))-(oy*sin(ac1));
- ny=(oy*cos(ac1))+(ox*sin(ac1));
- // New Target (x,y)!
- x=nx*d;
- y=ny*d;
- end_speed-=ac2;
- ball_zspin=0;
- ball_xyspin=0;
- full_xyspin=0;
- swerve=FALSE;
- if ((pass_type!=9) && ((ball_in_hands) || (heading_ball)))
- {
- // need to throw ball!
- heading_ball=FALSE;
- ball_inair=TRUE;
- pass_speed=end_speed+2+(d*(1-AIR_FRICTION));
- ballxdis=pass_speed*x/d;
- ballydis=pass_speed*y/d;
- t=(log((end_speed+2)/pass_speed))/(log(AIR_FRICTION));
- if (!t)
- t=1;
- if (chip_pass)
- // Aim for head...
- ballzdis=((PLAYER_HEIGHT-ballz)/t)+(t/2)*gravity;
- else
- ballzdis=(t/2)*gravity-(ballz/t);
- ball_in_hands=FALSE;
- // Stop run!
- if (teams[ball_poss-1].tm_act==RUN_ACT)
- teams[ball_poss-1].go_cnt=0;
- launch_ball(1); // Set up spin vector.
- cannot_pick_up=-ball_poss;
- }
- else
- {
- if (pass_type==-1 || pass_type==16 || pass_type==17 ||
- chip_pass)
- {
- // need to chip ball!
- ball_inair=TRUE;
- if ((ps<=0) && (chip_pass))
- // Forced chip forward...
- {
- if (spec_kick_type==SPACT_CHIP)
- {
- // Use user power setting...
- ballxdis=setp_bxd;
- ballydis=setp_byd;
- ballzdis=setp_bzd;
- }
- else
- {
- ballxdis=4*x/d;
- ballydis=4*y/d;
- ballzdis=6;
- }
- cannot_pick_up=ball_poss;
- }
- else
- {
- // In air to team-mate...
- pass_speed=end_speed+4+(d*(1-AIR_FRICTION));
- t=(log((end_speed+4)/pass_speed))/(log(AIR_FRICTION));
- ballxdis=pass_speed*x/d;
- ballydis=pass_speed*y/d;
- if (t<0.1)
- t=1;
- cannot_pick_up=ball_poss;
- if (chip_pass)
- // Aim for head...
- ballzdis=((PLAYER_HEIGHT-ballz)/t)+(t/2)*gravity;
- else
- ballzdis=(t/2)*gravity-(ballz/t);
- if (cross)
- {
- ballzdis=((PLAYER_HEIGHT-6-ballz)/t)+(t/2)*gravity;
- }
- if (ballzdis>14)
- ballzdis=14;
- }
- char angle=0;
- launch_ball(seed&1 ? -1:1); // Set up spin vector.
- }
- else
- {
- ball_inair=FALSE;
- pass_speed=end_speed+(d*(1-GRND_FRICTION));
- ballxdis=pass_speed*x/d;
- ballydis=pass_speed*y/d;
- cannot_pick_up=ball_poss;
- ballzdis=0;
- ballz=ball_diam/2;
- ball_xyspin=0;
- ball_zspin=0;
- }
- }
- holder_lose_ball();
- must_pass=FALSE;
- if (ps>0)
- new_interceptor(ps);
- }
- /******************************************************************************
- *****************************************************************************/
- void make_pass(match_player *player,int p,char cross=FALSE)
- {
- kick_type=KT_PASS;
- float sx,sy,sz;
- cross_now=cross;
- receiver=p;
- comm_pass_type=0;
- switch(pass_type)
- {
- // Player kick along ground, ball tweens to contact point and is then released...
- case(3):
- init_kick_act(&teams[ball_poss-1],MC_SIDEPASSL,MCC_SIDEPASS);
- break;
- case(2):
- init_kick_act(&teams[ball_poss-1],MC_DIAGBACKL,MCC_DIAGBACK);
- comm_pass_type=1;
- break;
- case(1):
- init_kick_act(&teams[ball_poss-1],MC_BACKHEELL,MCC_BACKHEEL);
- comm_pass_type=1;
- break;
- case(8):
- init_kick_act(&teams[ball_poss-1],MC_DIAGBACKR,MCC_DIAGBACK);
- comm_pass_type=1;
- break;
- case(7):
- init_kick_act(&teams[ball_poss-1],MC_SIDEPASSR,MCC_SIDEPASS);
- break;
- case(6):
- init_kick_act(&teams[ball_poss-1],MC_DIAGPASSR,MCC_DIAGPASS);
- break;
- case(5):
- init_kick_act(&teams[ball_poss-1],MC_PASSL,MCC_PASS);
- break;
- case(4):
- init_kick_act(&teams[ball_poss-1],MC_DIAGPASSL,MCC_DIAGPASS);
- break;
- case(-1):
- init_kick_act(&teams[ball_poss-1],MC_CHIPL,MCC_CHIP);
- comm_pass_type=2;
- break;
- case(16):
- init_kick_act(&teams[ball_poss-1],MC_CROSSL,MCC_CROSS);
- comm_pass_type=2;
- break;
- case(17):
- init_kick_act(&teams[ball_poss-1],MC_CROSSR,MCC_CROSS);
- comm_pass_type=2;
- break;
- /*
- case(12):
- init_kick_act(&teams[ball_poss-1],MC_THROWL,MCC_THROWL);
- comm_pass_type=2;
- break;
- case(13):
- init_kick_act(&teams[ball_poss-1],MC_THROWS,MCC_THROWS);
- break;
- */
- // Keeper new animation start, ball in limbo until contact...
- case(11):
- init_anim(&teams[ball_poss-1],MC_HALFVOLL);
- // Point at which ball leaves hand!
- // Calculate current mcap offsets for given direction (newdx,newdy)!
- rotate_offs(MC_HALFVOLL,sx,sy,sz,teams[ball_poss-1].tm_xdis,teams[ball_poss-1].tm_ydis);
- ballx=teams[ball_poss-1].tm_x+sx;
- bally=teams[ball_poss-1].tm_y+sy;
- ballz=teams[ball_poss-1].tm_z+sz;
- ball_limbo(teams[ball_poss-1].tm_player,MCC_HALFVOLL);
- teams[ball_poss-1].tm_limbo=1/MC_HALFVOLL_FS;
- pass_ball(receiver,FALSE);
- comm_pass_type=2;
- break;
- case(10):
- init_anim(&teams[ball_poss-1],MC_THROW);
- // Point at which ball leaves hand!
- // Calculate current mcap offsets for given direction (newdx,newdy)!
- rotate_offs(MC_THROW,sx,sy,sz,teams[ball_poss-1].tm_xdis,teams[ball_poss-1].tm_ydis);
- ballx=teams[ball_poss-1].tm_x+sx;
- bally=teams[ball_poss-1].tm_y+sy;
- ballz=teams[ball_poss-1].tm_z+sz;
- ball_limbo(teams[ball_poss-1].tm_player,MCC_THROW);
- teams[ball_poss-1].tm_limbo=1/MC_THROW_FS;
- pass_ball(receiver,FALSE);
- break;
- case(9):
- init_anim(&teams[ball_poss-1],MC_ROLL);
- // Point at which ball leaves hand!
- // Calculate current mcap offsets for given direction (newdx,newdy)!
- rotate_offs(MC_ROLL,sx,sy,sz,teams[ball_poss-1].tm_xdis,teams[ball_poss-1].tm_ydis);
- ballx=teams[ball_poss-1].tm_x+sx;
- bally=teams[ball_poss-1].tm_y+sy;
- ballz=teams[ball_poss-1].tm_z+sz;
- ball_limbo(teams[ball_poss-1].tm_player,MCC_ROLL);
- teams[ball_poss-1].tm_limbo=1/MC_ROLL_FS;
- pass_ball(receiver,FALSE);
- break;
- case(12):
- init_anim(&teams[ball_poss-1],MC_THROWS);
- // Point at which ball leaves hand!
- // Calculate current mcap offsets for given direction (newdx,newdy)!
- rotate_offs(MC_THROWS,sx,sy,sz,teams[ball_poss-1].tm_xdis,teams[ball_poss-1].tm_ydis);
- ballx=teams[ball_poss-1].tm_x+sx;
- bally=teams[ball_poss-1].tm_y+sy;
- ballz=teams[ball_poss-1].tm_z+sz;
- ball_limbo(teams[ball_poss-1].tm_player,MCC_THROWS);
- teams[ball_poss-1].tm_limbo=1/MC_THROWS_FS;
- pass_ball(receiver,FALSE);
- break;
- case(13):
- init_anim(&teams[ball_poss-1],MC_THROWL);
- // Point at which ball leaves hand!
- // Calculate current mcap offsets for given direction (newdx,newdy)!
- rotate_offs(MC_THROWL,sx,sy,sz,teams[ball_poss-1].tm_xdis,teams[ball_poss-1].tm_ydis);
- ballx=teams[ball_poss-1].tm_x+sx;
- bally=teams[ball_poss-1].tm_y+sy;
- ballz=teams[ball_poss-1].tm_z+sz;
- ball_limbo(teams[ball_poss-1].tm_player,MCC_THROWL);
- teams[ball_poss-1].tm_limbo=1/MC_THROWL_FS;
- pass_ball(receiver,FALSE);
- break;
- // Already in appropriate animation...
- case(15):
- // Header!
- fire_ball_off();
- PlayCommentaryMessage(CP_HEAD);
- break;
- case(14):
- // Volley!
- fire_ball_off();
- break;
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void dribble_dir(match_player *player,float &xd,float &yd)
- {
- float x,y,d;
- float rate=actual_spd(player);
- int i;
- char go_that_way=FALSE;
- char a=((seed<64) ? TRUE:FALSE);
- float sina=sin(0.174); // approx. 10 degrees!
- float cosa=cos(0.174);
- float xd1=xd;
- float yd1=yd;
- float xd2=xd;
- float yd2=yd;
- float xo,yo,dif;
- int cnt=0;
- while((!go_that_way) && (drib_opps))
- {
- // Coords of future ball.
- x=ballx+(xd*DRIB_DANGER_AREA/4);
- y=bally+(yd*DRIB_DANGER_AREA/4);
- go_that_way=TRUE;
- for (i=0; i<drib_opps; i++)
- {
- xo=x-opp_dir_tab[i][0];
- yo=y-opp_dir_tab[i][1]; // offset to future ball!
- d=calc_dist(xo,yo);
- dif=(player->tm_xdis*xo/d)+(player->tm_ydis*yo/d);
- d=d*(2-dif);
- if (d<DRIB_DANGER_AREA/2)
- {
- go_that_way=FALSE;
- break;
- }
- }
- if ((x<16) || (x>pitch_len-16) || (y<16) || (y>pitch_wid-16) || (!go_that_way))
- {
- go_that_way=FALSE;
- if (a)
- {
- xd=(xd1*cosa)-(yd1*sina);
- yd=(yd1*cosa)+(xd1*sina);
- xd1=xd;
- yd1=yd;
- a=!a;
- }
- else
- {
- xd=(xd2*cosa)+(yd2*sina);
- yd=(yd2*cosa)-(xd2*sina);
- xd2=xd;
- yd2=yd;
- a=!a;
- }
- if (cnt++==36)
- {
- // No-where to go, so go toward centre!
- xd=cntspot_x-ballx;
- yd=cntspot_y-bally;
- d=calc_dist(xd,yd);
- xd=xd/d;
- yd=yd/d;
- must_pass=TRUE;
- break;
- }
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- /*
- int omake_run_a(match_player *player)
- {
- if (player->tm_y>=cntspot_y)
- {
- // DIR 4
- if (ballx<pitch_len-32)
- {
- if ((opp_dir_tab[3]>=0) && (opp_dir_tab[5]>=0))
- {
- if (!opp_dir_tab[4])
- return(4);
- }
- }
- // DIR 5
- if ((ballx<pitch_len-32) && (bally>32))
- {
- if ((opp_dir_tab[6]>=0) && (opp_dir_tab[4]>=0))
- {
- if (!opp_dir_tab[5])
- return(5);
- }
- }
- // DIR 3
- if ((bally<pitch_wid-32) && (ballx<pitch_len-32))
- {
- if ((opp_dir_tab[2]>=0) && (opp_dir_tab[4]>=0))
- {
- if (!opp_dir_tab[3])
- return(3);
- }
- }
- // DIR 6
- if (bally>32)
- {
- if ((opp_dir_tab[7]>=0) && (opp_dir_tab[5]>=0))
- {
- if (!opp_dir_tab[6])
- return(6);
- }
- }
- // DIR 2
- if (bally<pitch_wid-32)
- {
- if ((opp_dir_tab[3]>=0) && (opp_dir_tab[1]>=0))
- {
- if (!opp_dir_tab[2])
- return(2);
- }
- }
- // DIR 7
- if ((bally>32) && (ballx>32))
- {
- if ((opp_dir_tab[0]>=0) && (opp_dir_tab[6]>=0))
- {
- if (!opp_dir_tab[7])
- return(7);
- }
- }
- // DIR 1
- if ((bally<pitch_wid-32) && (ballx>32))
- {
- if ((opp_dir_tab[2]>=0) && (opp_dir_tab[5]>=0))
- {
- if (!opp_dir_tab[1])
- return(1);
- }
- }
- // DIR 0
- if (ballx>32)
- {
- if ((opp_dir_tab[1]>=0) && (opp_dir_tab[7]>=0))
- {
- if (!opp_dir_tab[0])
- return(0);
- }
- }
- }
- else
- {
- // DIR 4
- if (ballx<pitch_len-32)
- {
- if ((opp_dir_tab[3]>=0) && (opp_dir_tab[5]>=0))
- {
- if (!opp_dir_tab[4])
- return(4);
- }
- }
- // DIR 3
- if ((bally<pitch_wid-32) && (ballx<pitch_len-32))
- {
- if ((opp_dir_tab[2]>=0) && (opp_dir_tab[4]>=0))
- {
- if (!opp_dir_tab[3])
- return(3);
- }
- }
- // DIR 5
- if ((ballx<pitch_len-32) && (bally>32))
- {
- if ((opp_dir_tab[6]>=0) && (opp_dir_tab[4]>=0))
- {
- if (!opp_dir_tab[5])
- return(5);
- }
- }
- // DIR 2
- if (bally<pitch_wid-32)
- {
- if ((opp_dir_tab[3]>=0) && (opp_dir_tab[1]>=0))
- {
- if (!opp_dir_tab[2])
- return(2);
- }
- }
- // DIR 6
- if (bally>32)
- {
- if ((opp_dir_tab[7]>=0) && (opp_dir_tab[5]>=0))
- {
- if (!opp_dir_tab[6])
- return(6);
- }
- }
- // DIR 1
- if ((bally<pitch_wid-32) && (ballx>32))
- {
- if ((opp_dir_tab[2]>=0) && (opp_dir_tab[5]>=0))
- {
- if (!opp_dir_tab[1])
- return(1);
- }
- }
- // DIR 7
- if ((bally>32) && (ballx>32))
- {
- if ((opp_dir_tab[0]>=0) && (opp_dir_tab[6]>=0))
- {
- if (!opp_dir_tab[7])
- return(7);
- }
- }
- // DIR 0
- if (ballx>32)
- {
- if ((opp_dir_tab[1]>=0) && (opp_dir_tab[7]>=0))
- {
- if (!opp_dir_tab[0])
- return(0);
- }
- }
- }
- // Go to right corners...
- int y;
- int x=(pitch_len-(prat*5))-ballx;
- if (bally>cntspot_y)
- y=(pitch_wid-(prat*5))-bally;
- else
- y=((prat*5))-bally;
- return(get_dir(x,y));
- }
- */
- /******************************************************************************
- *****************************************************************************/
- /*
- int make_run_b(match_player *player)
- {
- if (player->tm_y>=cntspot_y)
- {
- // DIR 0
- if (ballx>32)
- {
- if ((opp_dir_tab[1]>=0) && (opp_dir_tab[7]>=0))
- {
- if (!opp_dir_tab[0])
- return(0);
- }
- }
- // DIR 7
- if ((bally>32) && (ballx>32))
- {
- if ((opp_dir_tab[0]>=0) && (opp_dir_tab[6]>=0))
- {
- if (!opp_dir_tab[7])
- return(7);
- }
- }
- // DIR 1
- if ((bally<pitch_wid-32) && (ballx>32))
- {
- if ((opp_dir_tab[2]>=0) && (opp_dir_tab[5]>=0))
- {
- if (!opp_dir_tab[1])
- return(1);
- }
- }
- // DIR 6
- if (bally>32)
- {
- if ((opp_dir_tab[7]>=0) && (opp_dir_tab[5]>=0))
- {
- if (!opp_dir_tab[6])
- return(6);
- }
- }
- // DIR 2
- if (bally<pitch_wid-32)
- {
- if ((opp_dir_tab[3]>=0) && (opp_dir_tab[1]>=0))
- {
- if (!opp_dir_tab[2])
- return(2);
- }
- }
- // DIR 5
- if ((ballx<pitch_len-32) && (bally>32))
- {
- if ((opp_dir_tab[6]>=0) && (opp_dir_tab[4]>=0))
- {
- if (!opp_dir_tab[5])
- return(5);
- }
- }
- // DIR 3
- if ((bally<pitch_wid-32) && (ballx<pitch_len-32))
- {
- if ((opp_dir_tab[2]>=0) && (opp_dir_tab[4]>=0))
- {
- if (!opp_dir_tab[3])
- return(3);
- }
- }
- // DIR 4
- if (ballx<pitch_len-32)
- {
- if ((opp_dir_tab[3]>=0) && (opp_dir_tab[5]>=0))
- {
- if (!opp_dir_tab[4])
- return(4);
- }
- }
- }
- else
- {
- // DIR 0
- if (ballx>32)
- {
- if ((opp_dir_tab[1]>=0) && (opp_dir_tab[7]>=0))
- {
- if (!opp_dir_tab[0])
- return(0);
- }
- }
- // DIR 1
- if ((bally<pitch_wid-32) && (ballx>32))
- {
- if ((opp_dir_tab[2]>=0) && (opp_dir_tab[5]>=0))
- {
- if (!opp_dir_tab[1])
- return(1);
- }
- }
- // DIR 7
- if ((bally>32) && (ballx>32))
- {
- if ((opp_dir_tab[0]>=0) && (opp_dir_tab[6]>=0))
- {
- if (!opp_dir_tab[7])
- return(7);
- }
- }
- // DIR 2
- if (bally<pitch_wid-32)
- {
- if ((opp_dir_tab[3]>=0) && (opp_dir_tab[1]>=0))
- {
- if (!opp_dir_tab[2])
- return(2);
- }
- }
- // DIR 6
- if (bally>32)
- {
- if ((opp_dir_tab[7]>=0) && (opp_dir_tab[5]>=0))
- {
- if (!opp_dir_tab[6])
- return(6);
- }
- }
- // DIR 3
- if ((bally<pitch_wid-32) && (ballx<pitch_len-32))
- {
- if ((opp_dir_tab[2]>=0) && (opp_dir_tab[4]>=0))
- {
- if (!opp_dir_tab[3])
- return(3);
- }
- }
- // DIR 5
- if ((ballx<pitch_len-32) && (bally>32))
- {
- if ((opp_dir_tab[6]>=0) && (opp_dir_tab[4]>=0))
- {
- if (!opp_dir_tab[5])
- return(5);
- }
- }
- // DIR 4
- if (ballx<pitch_len-32)
- {
- if ((opp_dir_tab[3]>=0) && (opp_dir_tab[5]>=0))
- {
- if (!opp_dir_tab[4])
- return(4);
- }
- }
- }
- // Go to left corners...
- int y;
- int x=(prat*5)-ballx;
- if (bally>cntspot_y)
- y=(pitch_wid-(prat*5))-bally;
- else
- y=((prat*5))-bally;
- return(get_dir(x,y));
- }
- */
- /******************************************************************************
- *****************************************************************************/
- void avoid_boundary(match_player *player)
- {
- // Just run toward opponents goal...
- float x;
- float y=cntspot_y;
- if (player->tm_player<12)
- // Goal B...
- x=pitch_len;
- else
- // Goal A...
- x=0;
- init_run_act(player,x,y,TRUE);
- action="Dribble";
- }
- /******************************************************************************
- *****************************************************************************/
- void go_dribble(match_player *player,float x,float y)
- {
- x=player->tm_x+(x*500);
- y=player->tm_y+(y*500);
- // Make target (x,y) greater than intention range!
- init_run_act(player,x,y,TRUE);
- action="Dribble";
- }
- /******************************************************************************
- *****************************************************************************/
- void make_run(match_player *player)
- {
- float x,y,px;
- if (player->tm_player<12)
- // Team A
- {
- px=player->tm_x-(pitch_len-prat*10);
- if (px>0)
- {
- if (px<prat*10)
- x=cos(px*PI/(prat*20));
- else
- x=0;
- y=sqrt(1-(x*x));
- if (player->tm_y>cntspot_y)
- y=-y;
- }
- else
- {
- x=1;
- y=0;
- }
- get_opp_dir_tab(player->tm_player);
- dribble_dir(player,x,y);
- go_dribble(player,x,y);
- }
- else
- // Team B
- {
- px=(prat*10)-player->tm_x;
- if (px>0)
- {
- if (px<prat*10)
- x=-cos(px*PI/(prat*20));
- else
- x=0;
- y=sqrt(1-(x*x));
- if (player->tm_y>cntspot_y)
- y=-y;
- }
- else
- {
- x=-1;
- y=0;
- }
- get_opp_dir_tab(player->tm_player);
- dribble_dir(player,x,y);
- go_dribble(player,x,y);
- }
- reset_ideas(player);
- player->int_move=I_DRIBBLE;
- player->int_cnt=18-(player->tm_flair/8);
- player->go_cnt=19-(player->tm_flair/8);
-
- // Where will he be at end of run!
- x=player->tm_x+(player->go_txdis*player->go_cnt);
- y=player->tm_y+(player->go_tydis*player->go_cnt);
- if (x>pitch_len || x<0 || y<0 || y>pitch_wid)
- {
- // Running off pitch!!!
- avoid_boundary(player);
- }
- }
- /******************************************************************************
- *****************************************************************************/
- int run_decide(match_player *player)
- {
- int opps=(player->tm_flair)-(opponents_near_holder*16);
- if (opps<=0)
- opps=MIN_RUN_PROB;
- if (seed<opps)
- return(TRUE);
- else
- return(FALSE);
- }
- /******************************************************************************
- *****************************************************************************/
- void make_punt(match_player *player)
- {
- if (ball_in_hands && (player->tm_player==KP_A || player->tm_player==KP_B))
- {
- punt_ball(player);
- }
- else
- {
- kick_type=KT_PUNT;
- pass_type=100;
- init_kick_act(player,MC_SHOOTL,MCC_SHOOT);
- }
- }
- /*****************************************************************************
- *****************************************************************************/
- void punt_ball(match_player *player)
- {
- inc_pass(ball_poss);
- receiver_a=FALSE;
- receiver_b=FALSE;
- cannot_pick_up=ball_poss;
- must_punt=FALSE;
- char inh=ball_in_hands;
- ball_inair=TRUE;
- int r=rand_range(129-player->tm_ac);
- ballxdis=player->tm_xdis*(6+player->tm_pow/8);
- ballydis=player->tm_ydis*(6+player->tm_pow/8);
- if (heading_ball==2)
- ballzdis=4; // Diving Header!
- else
- if (heading_ball==1)
- ballzdis=6; // Standing or jumping header!
- else
- if (heading_ball==3)
- ballzdis=8;
- else
- {
- if (player->tm_player!=KP_A && player->tm_player!=KP_B)
- ballzdis=10; // Kick!
- else
- ballzdis=12; // Kick!
- }
- action="Punt";
- new_shot(player->tm_player); // Treat as shot just in case!
- if (inh && (player->tm_player==KP_A || player->tm_player==KP_B))
- {
- init_anim(player,MC_KICKOUT);
- // Kick out ball from hands!
- // Calculate current mcap offsets for given direction (newdx,newdy)!
- float sx,sy,sz;
- rotate_offs(MC_KICKOUT,sx,sy,sz,player->tm_xdis,player->tm_ydis);
- ballx=player->tm_x+sx;
- bally=player->tm_y+sy;
- ballz=player->tm_z+sz;
- ball_limbo(player->tm_player,MCC_KICKOUT);
- player->tm_limbo=1/MC_KICKOUT_FS;
- launch_ball(1); // Set up spin vector.
- }
- holder_lose_ball();
- }
- /******************************************************************************
- *****************************************************************************/
- int punt_decide(match_player *player)
- {
- float x,y,x_factor;
- int def;
- x=player->tm_xdis;
- y=player->tm_ydis;
- if (player->tm_player>11)
- {
- if (x<0 && (ballx<pitch_len && ballx>cntspot_x) && ((seed<-(x*128)) || must_punt))
- def=ballx-cntspot_x;
- else
- return(FALSE);
- }
- else
- {
- if (x>0 && (ballx>0 && ballx<cntspot_x) && ((seed<(x*128)) || must_punt))
- def=cntspot_x-ballx;
- else
- return(FALSE);
- }
- if (def>(cntspot_x-(10*prat)))
- def+=128;
- // if (((user_player1==player->tm_player) || (user_player2==player->tm_player)) && (def>prat*20))
- if (((player->control) && (def>prat*20)) || must_punt)
- def=128*4;
- // User must punt!
- if (def/3>seed || (first_time_it && (def*((float)player->tm_cont/64)>seed)))
- // His position is defensive.
- {
- int opps=(opponents_near_holder*40)-(player->tm_flair);
- if (opps<MIN_PUNT_PROB)
- opps=MIN_PUNT_PROB;
- if (user_controlled)
- // User must punt!
- opps=128;
- // Facing away from goal would help...
- if (player->tm_player<12)
- x_factor=(1+x)/2;
- else
- x_factor=-(x-1)/2;
- if (((seed<opps*x_factor) && (x_factor>0.5)) || must_punt)
- return(TRUE);
- }
- return(FALSE);
- }
- /******************************************************************************
- *****************************************************************************/
- int head_punt_decide(match_player *player)
- {
- float x,y;
- int def;
- x=player->tm_xdis;
- y=player->tm_ydis;
- if (player->tm_player>11)
- {
- if (x<0)
- def=ballx-cntspot_x;
- else
- return(FALSE);
- }
- else
- {
- if (x>0)
- def=cntspot_x-ballx;
- else
- return(FALSE);
- }
- if (def>(cntspot_x-(10*prat)))
- def+=128;
- if (def/4>seed)
- // His position is defensive.
- {
- cannot_pick_up=-player->tm_player;
- holder_lose_ball();
- ball_inair=TRUE;
- ballxdis=(((float)(player->tm_pow))/32.0)*x+(x*6);
- ballydis=0;
- ballzdis=10;
- action="Punt";
- init_anim(player,MC_S_HEAD);
- launch_ball(1); // Set up spin vector.
- play_fx(PS_HARDHEAD,ballx,bally);
- return(TRUE);
- }
- return(FALSE);
- }
- /******************************************************************************
- *****************************************************************************/
- float get_power()
- {
- return ((float)(setp_power+16)/2);
- }
- /******************************************************************************
- *****************************************************************************/
- float get_traj()
- {
- return ((float)setp_hgt/3);
- }
- /******************************************************************************
- *****************************************************************************/
- void aim_shot_at_goal(match_player *player,float &xoff,float &yoff,int rng)
- {
- float x,y,d;
- float gx,gy,area;
- int side;
- if (player->control && pass_type==-1)
- {
- // User selects direction!
- x=player->tm_xdis;
- y=player->tm_ydis;
- float d=calc_dist(x*128,y*128);
- xoff=(x*rng*128)/d;
- yoff=(y*rng*128)/d;
- }
- else
- {
- // Auto direction select based on (accuracy)!
- int keeper;
- if (player->tm_player<12)
- {
- keeper=12;
- gx=pitch_len;
- }
- else
- {
- keeper=1;
- gx=0;
- }
- // get offset to keeper (x,y)!
- x=teams[keeper-1].tm_x-ballx;
- y=teams[keeper-1].tm_y-bally;
- // get offset to goal line through keeper (gx,gy)!
- gx=gx-ballx;
- gy=y*gx/x;
- area=gy+bally-cntspot_y;
- if (area>0)
- // More area above keeper!
- {
- if ((player->tm_flair/2)+63>seed)
- // Aim above!
- {
- area=(cntspot_y+area)-top_post_y;
- side=-1;
- }
- else
- // Aim below!
- {
- area=0; // Doesn't aim for large gap!
- side=1;
- }
- }
- else
- // More area below keeper!
- {
- if ((player->tm_flair/2)+63>seed)
- // Aim below!
- {
- area=bot_post_y-(cntspot_y+area);
- side=1;
- }
- else
- // Aim above!
- {
- area=0; // Doesn't aim for large gap!
- side=-1;
- }
- }
- xoff=gx;
- // Calculate Accuracy offset!
- int acc_off=(seed*(8+(128-player->tm_ac)))/128;
- if (seed&4)
- acc_off=-(acc_off*rng/(20.0*prat));
- else
- acc_off=(acc_off*rng/(20.0*prat));
- // Now. Direct at chosen target.
- if (side>0)
- yoff=bot_post_y-bally-16+acc_off;
- else
- yoff=top_post_y-bally+16+acc_off;
- }
- // Shot Speed...
- int shot_var=seed;
- af_randomize();
- shot_var=(shot_var+seed)/2; // Favour 64.
- shot_speed=6+(4*rng/(prat*60))+(9.0*(player->tm_pow+shot_var)/150);
- if (pass_type>0 && pass_type<5 && pass_type>5)
- // Just a tap in...
- shot_speed/=2;
- // Initialise swerve on ball!
- af_randomize();
- ball_zspin=0;
- // full_zspin=(float)player->tm_ac/(rng-sqrt(rng*4));
- swerve=0;
- spin_ball=0;
- max_sw_factor=0;
- #ifdef EURO96
- if (rng>=10.0*prat && !user_controlled && !penalty_shot)
- #else
- if ((rng>=10.0*prat) && (!user_controlled))
- #endif
- {
- af_randomize();
- full_xyspin=(float)(seed)/128*MAX_XY_CSW*player->tm_flair/128;
- full_zspin=((float)(seed)/128*MAX_Z_CSW*player->tm_flair/128);
- spin_ball=0;
- float d=calc_dist(xoff,yoff);
-
- af_randomize();
- // Time to reach (xoff,yoff)...
- float t=(d/shot_speed*(1-AIR_FRICTION));
- if (t>=1)
- t=0.9998;
- t=(log(1.0-t))/(log(AIR_FRICTION)); // How long to go (d) dist!
- if (xoff<0)
- // Going Left
- {
- if (side<0)
- // Left top.
- {
- if (xoff<yoff)
- swerve=-1;
- else
- swerve=1;
- }
- // Left bot.
- else
- {
- if (xoff<yoff)
- swerve=1;
- else
- swerve=-1;
- }
- }
- else
- // Going Right
- {
- if (side<0)
- // Right top.
- {
- if (xoff>yoff)
- swerve=1;
- else
- swerve=-1;
- }
- // Right bot.
- else
- {
- if (xoff>yoff)
- swerve=-1;
- else
- swerve=1;
- }
- }
- // Calculate Offset swerve angle...
- float a=0;
- for (int n=1; n<=t; n++)
- {
- a+=full_xyspin*(SW_HOLD_FACTOR/(SW_HOLD_FACTOR+n));
- }
- a=(a/2.2)+(d/4800);
- x=xoff/d;
- y=yoff/d;
- if (swerve<0)
- {
- xoff=d*((x*cos(a))-(y*sin(a)));
- yoff=d*((y*cos(a))+(x*sin(a)));
- }
- else
- {
- xoff=d*((x*cos(a))+(y*sin(a)));
- yoff=d*((y*cos(a))-(x*sin(a)));
- }
- ballzdis=7.2+(rng/180)+(((float)seed/64)*(128-player->tm_ac)/128)
- +((float)(full_zspin)/2);
- spin_cnt=((ballzdis/gravity))+(ABS(full_zspin));
- }
- else
- {
- if (newk_shot)
- {
- shot_speed=get_power();
- ballzdis=get_traj();
- xoff=player->tm_xdis*10;
- yoff=player->tm_ydis*10;
- ballxdis=xoff;
- ballydis=yoff;
- }
- else
- {
- if (drive_shot)
- {
- shot_speed+=5;
- ballzdis=7-(shot_speed/10);
- }
- else
- {
- if ((area>prat*6) && (rng<prat*15))
- // Goal-keeper has left a large gap and attacker is close in!
- ballzdis=1.8+(rng/180)+(((float)seed/64)*(128-player->tm_ac)/128); // Place it low!
- else
- ballzdis=5.2+(rng/180)+(((float)seed/64)*(128-player->tm_ac)/128);
- }
- }
- }
- if (user_controlled)
- {
- if (drive_shot)
- after_touch_on=FALSE;
- else
- after_touch_on=user_controlled;
- full_xyspin=MAX_XY_USW*player->tm_flair/128;
- full_zspin=MAX_Z_USW*player->tm_flair/128;
- d=calc_dist(ballxdis,ballydis);
- shoot_x=ballxdis/d;
- shoot_y=ballydis/d; // Shoot direction vectors(for after-touch).
- }
- spin_cnt=0;
- }
- /******************************************************************************
- *****************************************************************************/
- void make_shoot(match_player *player)
- {
- kick_type=KT_SHOOT;
- switch(pass_type)
- {
- // Straight-forward shot!
- case(-1):
- init_kick_act(player,MC_SHOOTL,MCC_SHOOT);
- break;
- // Player kick along ground, ball tweens to contact point and is then released...
- case(3):
- init_kick_act(&teams[ball_poss-1],MC_SIDEPASSL,MCC_SIDEPASS);
- break;
- case(2):
- init_kick_act(&teams[ball_poss-1],MC_DIAGBACKL,MCC_DIAGBACK);
- break;
- case(1):
- init_kick_act(&teams[ball_poss-1],MC_BACKHEELL,MCC_BACKHEEL);
- break;
- case(8):
- init_kick_act(&teams[ball_poss-1],MC_DIAGBACKR,MCC_DIAGBACK);
- break;
- case(7):
- init_kick_act(&teams[ball_poss-1],MC_SIDEPASSR,MCC_SIDEPASS);
- break;
- case(6):
- init_kick_act(&teams[ball_poss-1],MC_DIAGPASSR,MCC_DIAGPASS);
- break;
- case(5):
- init_kick_act(&teams[ball_poss-1],MC_PASSL,MCC_PASS);
- break;
- case(4):
- init_kick_act(&teams[ball_poss-1],MC_DIAGPASSL,MCC_DIAGPASS);
- break;
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void shoot_ball(match_player *player)
- {
- receiver_a=FALSE;
- receiver_b=FALSE;
- if (say_names)
- {
- if (!ball_poss)
- PlayTeamSample(real_player(last_touch),2);
- else
- PlayTeamSample(real_player(ball_poss),2);
- }
- // Fire shot!
- float goal_x;
- if (ball_poss<=11)
- goal_x=pitch_len;
- else
- goal_x=0;
- float xoff=goal_x-ballx;
- float yoff=cntspot_y-bally;
- float range=calc_dist(xoff,yoff);
- if (range<1)
- range=1;
- holder_lose_ball();
- ball_inair=TRUE;
- new_shot(player->tm_player);
- real_shot=TRUE;
- af_randomize();
- aim_shot_at_goal(player,xoff,yoff,range);
- if (heading_ball==2)
- ballzdis=ballzdis*.5; // Diving Header!
- else
- if (heading_ball==3)
- ballzdis=1;
- if (ballzdis>0.6)
- ball_inair=TRUE;
- float d=calc_dist(xoff,yoff);
- ballxdis=shot_speed*xoff/d;
- ballydis=shot_speed*yoff/d;
- action="Shoot";
- cannot_pick_up=player->tm_player;
- drive_shot=FALSE;
- newk_shot=FALSE;
- launch_ball(0); // Set up spin vector.
- inc_shot(player->tm_player);
- user_scorer=player->control;
- }
- /******************************************************************************
- *****************************************************************************/
- int shoot_decide(match_player *player)
- {
- flag=FALSE;
- float goal_x;
- if (ball_poss<=11)
- goal_x=pitch_len;
- else
- goal_x=0;
- float xoff=goal_x-ballx;
- float yoff=cntspot_y-bally;
- int range=calc_dist(xoff,yoff);
- if (range<1)
- range=1;
- if (player->tm_srng)
- {
- if (user_controlled)
- {
- // Big shot!
- flag=TRUE; // in shooting range!
- pass_type=-1;
- }
- else
- {
- if (plr_facing_goal(xoff,yoff,player))
- {
- // Big shot!
- flag=TRUE; // in shooting range!
- pass_type=-1;
- }
- else
- {
- pass_type=in_kicking_range(player,xoff,yoff);
- if (user_controlled && pass_type==5)
- pass_type=-1;
- if (!pass_type)
- flag=FALSE;
- else
- flag=TRUE; // any dir shot.
- }
- }
- }
- if (flag)
- {
- // He's in range!
- if ((!user_controlled) && (!must_shoot))
- {
- int opps=(10000/range)+(opponents_near_holder*(16+((128-player->tm_flair)/4)))-(16+(player->tm_flair/3));
- if (opps<MIN_SHOOT_PROB)
- opps=MIN_SHOOT_PROB;
- if (seed>opps && !first_time_it)
- return(FALSE);
- }
- return(TRUE);
- }
- if (player->tm_leave) // He cannot touch ball again!
- must_pass=TRUE;
- return(FALSE);
- }
- /******************************************************************************
- *****************************************************************************/
- int head_shoot_decide(match_player *player)
- {
- flag=FALSE;
- float goal_x;
- if (player->tm_player<=11)
- goal_x=pitch_len;
- else
- goal_x=0;
- float xoff=goal_x-ballx;
- float yoff=cntspot_y-bally;
- int range=calc_dist(xoff,yoff);
- if (range<1)
- range=1;
- if (in_header_rng)
- {
- // He's in range!
- int opps=(5000/range)+(opponents_near_holder*32);
- if (opps<MIN_SHOOT_PROB)
- opps=MIN_SHOOT_PROB;
- if (seed>opps)
- return(FALSE);
- // Fire shot!
- cannot_pick_up=-ball_poss;
- holder_lose_ball();
- ball_inair=TRUE;
- new_shot(player->tm_player);
- aim_shot_at_goal(player,xoff,yoff,range);
- float d=calc_dist(xoff,yoff);
- stop_ball_spin();
- ballzdis=ballzdis-1.4;
- ballxdis=(xoff*(12+(player->tm_pow)/4))/(d*3.4);
- ballydis=(yoff*(12+(player->tm_pow)/4))/(d*3.4);
- init_anim(player,MC_S_HEAD);
- launch_ball(0); // Set up spin vector.
- play_fx(PS_HARDHEAD,ballx,bally);
- return(TRUE);
- }
- return(FALSE);
- }
- /******************************************************************************
- *****************************************************************************/
- int sort_less_than(const void *op1, const void *op2)
- {
- const int p1=*(const int *)op1;
- const int p2=*(const int *)op2;
- return(p1-p2);
- }
- /******************************************************************************
- *****************************************************************************/
- int sort_greater_than(const void *op1, const void *op2)
- {
- const int p1=*(const int *)op1;
- const int p2=*(const int *)op2;
- return(p2-p1);
- }
- /******************************************************************************
- *****************************************************************************/
- int sort_soonest(const void *op1, const void *op2)
- {
- const short p1=*(const short *)op1;
- const short p2=*(const short *)op2;
- return(p1-p2);
- }
- /******************************************************************************
- *****************************************************************************/
- float kicking_dist(match_player *player,float x,float y,float d)
- {
- // Calculate back-heel distance...
- float dist=MIN_PASS_DIST+(float)player->tm_pow/3.6;
- // Calculate difference range of 2(ahead) to 1(behind)...
- float dif=(player->tm_xdis*x/d)+(player->tm_ydis*y/d);
- float kd=dist*(2.0+dif)/2;
- return(kd);
- }
- /******************************************************************************
- *****************************************************************************/
- int in_kicking_range(match_player *player,float x,float y)
- {
- float d=calc_dist(x,y);
- x=x/d;
- y=y/d;
- // Calculate back-heel distance...
- float dist=MIN_PASS_DIST+(float)player->tm_pow/3.6;
- // Calculate difference range of 2(ahead) to 1(behind)...
- float dif=(player->tm_xdis*x)+(player->tm_ydis*y);
- float kd=dist*(1.5+(dif/2));
- if (dif>KICK_AHEAD_ANG)
- {
- // Straight ahead...
- if (d>dist*4)
- return(0);
- else
- if (d>dist*2)
- return(-1);
- else
- return(5);
- }
- else
- {
- // Different dir...
- if (d>kd)
- return(FALSE);
- else
- {
- float nx=(x*player->tm_xdis)+(y*player->tm_ydis);
- float ny=(y*player->tm_xdis)-(x*player->tm_ydis);
- return(1+get_dir(nx,ny));
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- int can_i_pass(match_player *player)
- {
- int p=pass_type;
- if (p>6 && p<9)
- p=p-6;
- else
- if (p>0 && p<4)
- p=4-p;
- else
- return(pass_type); // Forward or diagonal pass requires no special ability!
- if (player->tm_flair>(p*seed*0.5))
- return(pass_type); // Skillfull enough to see move!
- else
- return(FALSE);
- }
- /******************************************************************************
- *****************************************************************************/
- int pass_decide(match_player *player,char cross=FALSE)
- {
- char angle;
- int passee_tab[10][3];
- int passees=0;
- int vm;
- if ((!player->tm_act==THROW_ACT) && (ball_inair))
- vm=VISION_MULT*2/3;
- else
- vm=VISION_MULT;
- int x,y,d,t;
- if (player->tm_player>11)
- t=22-1; //team B
- else
- t=11-1; //team A
- /************/
- if (want_pass)
- {
- // Try guy shouting for pass...
- int i=want_pass-1;
- if ((ball_poss!=KP_A && ball_poss!=KP_B)
- || !kopp_around(teams[want_pass-1].tm_x,teams[want_pass-1].tm_y,want_pass))
- {
- if ((teams[i].control)
- || (plr_facing(teams[i].tm_x-ballx,teams[i].tm_y-bally,player))
- || (set_piece_on && player->tm_act!=THROW_ACT))
- {
- x=teams[i].tm_x-ballx;
- y=teams[i].tm_y-bally;
- d=calc_dist(x,y);
- if ((ball_in_hands) && (d<30.0*prat))
- // In throwing range!
- {
- passee_tab[passees][1]=i+1;
- passee_tab[passees++][2]=pass_type;
- // Add prospective passee!
- }
- else
- {
- pass_type=in_kicking_range(player,x,y);
- pass_type=can_i_pass(player);
- if ((pass_type) && (!ball_in_hands))
- // Can kick that distance...
- {
- passee_tab[passees][1]=i+1;
- passee_tab[passees++][2]=pass_type;
- // Add prospective passee!
- }
- else
- {
- if (cross && !ball_in_hands &&
- d<=(player->tm_vis*vm*1.4) && d>(prat*8))
- {
- if ((ball_poss<12 && (teams[i].tm_x)>pitch_len-(prat*18))
- || (ball_poss>11 && (teams[i].tm_x)<prat*18))
- {
- // In eighteen yard box!
- angle=cross_angle(teams[ball_poss-1].tm_xdis,
- teams[ball_poss-1].tm_ydis,x,y);
-
- if (angle==1)
- // Kicking at 90 degrees left...
- {
- pass_type=16;
- passee_tab[passees][1]=i+1;
- passee_tab[passees++][2]=pass_type;
- }
- else
- {
- if (angle==2)
- // Kicking at 90 degrees right...
- {
- pass_type=17;
- passee_tab[passees][1]=i+1;
- passee_tab[passees++][2]=pass_type;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- /************/
- for (int i=t; i>t-11; i--)
- {
- if (player->tm_player!=i+1)
- // Not man on ball!
- {
- if ((ball_poss!=KP_A && ball_poss!=KP_B)
- || !kopp_around(teams[i].tm_x,teams[i].tm_y,i))
- {
- if ((teams[i].tm_act<=TURN_ACT) && (teams[i].guy_on>0) && (want_pass-1!=i))
- // Not Busy!
- {
- x=teams[i].tm_x-ballx;
- y=teams[i].tm_y-bally;
- d=calc_dist(x,y);
- pass_type=in_kicking_range(player,x,y);
- pass_type=can_i_pass(player);
- if ((pass_type && !ball_in_hands) || ((ball_in_hands) && (d<20.0*prat)))
- // Can kick reach him...
- {
- if (d<=(player->tm_vis*vm))
- // In visible range!
- {
- if ((d/2<(MIN_PASS_DIST+(float)player->tm_pow/3.6) && !ball_in_hands) || angle_of_vis(player,x,y,teams[i].tm_dist,cross))
- // Within angle of vision 90!
- {
- if (!(((i==KP_A-1) || (i==KP_B-1)) && (teams[i].tm_dist<KP_MIN_PASS_DIST)))
- {
- passee_tab[passees][1]=i+1;
- passee_tab[passees++][2]=pass_type;
- }
- // Add prospective passee!
- }
- }
- }
- else
- {
- if (cross && !ball_in_hands &&
- d<=(player->tm_vis*vm*1.4) && d>(prat*8))
- {
- if ((ball_poss<12 && (teams[i].tm_x)>pitch_len-(prat*18))
- || (ball_poss>11 && (teams[i].tm_x)<prat*18))
- {
- angle=cross_angle(teams[ball_poss-1].tm_xdis,
- teams[ball_poss-1].tm_ydis,x,y);
- if (angle==1)
- // Kicking at 90 degrees left...
- {
- pass_type=16;
- passee_tab[passees][1]=i+1;
- passee_tab[passees++][2]=pass_type;
- }
- else
- {
- if (angle==2)
- // Kicking at 90 degrees right...
- {
- pass_type=17;
- passee_tab[passees][1]=i+1;
- passee_tab[passees++][2]=pass_type;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- //********************************//
- // Passee table has been created. //
- //********************************//
- // Give preference values to each candidate...
- // Low being best!
- int pas=0;
- if (passees)
- {
- int team_mate;
- if (!user_controlled)
- {
- // Computer decision only...
- int opps;
- float tmx;
- float px=player->tm_x;
-
- for (int p=0; p<passees; p++)
- {
- team_mate=passee_tab[p][1]-1;
- // Get opponents near team-mate...
- opps=opp_around((int)teams[team_mate].tm_x,
- (int)teams[team_mate].tm_y,team_mate);
- // Passer takes this into consideration...
- opps=64+(opps*(64+(player->tm_flair/2)));
- // Optimum passing distance is around 10 yards...
- // Anything below should start to lessen likelyhood of passing...
- if (teams[team_mate].tm_dist<OPTIMUM_PASS)
- opps+=(OPTIMUM_PASS-teams[team_mate].tm_dist);
-
- // But, am I under threat and have to get rid of ball???
- if (!set_piece_on && match_mode>GOAL_KICK_BR && match_mode<GOAL_KICK_TL)
- opps-=opponents_near_holder*(32+(player->tm_flair/2));
- else
- opps-=64;
- // Is he making run???
- if (want_pass==(team_mate+1))
- opps-=teams[team_mate].tm_flair;
-
- // If in shooting range then less chance of passing...(greed factor)!
- if (player->tm_srng)
- opps+=GREED_FACTOR;
- tmx=teams[team_mate].tm_x;
- if (team_mate>11)
- // Team B...
- if (tmx>px)
- // Passing back...
- opps+=(tmx-px)*player->tm_flair/128;
- else
- // Passing forward, less difference...
- opps+=((tmx-px)/5)*player->tm_flair/128;
- else
- // Team A...
- if (tmx<px)
- // Passing back...
- opps+=(px-tmx)*player->tm_flair/128;
- else
- // Passing forward, less difference...
- opps+=((px-tmx)/5)*player->tm_flair/128;
- // The more flair less likelyhood of passing especially if opps near passee!
- int op_p;
- if (team_mate<11)
- op_p=11;
- else
- op_p=0;
-
- // Get vectors for pass!
- float tx=teams[team_mate].tm_x-ballx;
- float ty=teams[team_mate].tm_y-bally;
- float td=teams[team_mate].tm_dist;
- float ang=0;
- float ox,oy,od,a;
- tx=tx/td;
- ty=ty/td;
- // Any opponents in path off prospective passed ball?
- for (int o=op_p; o<op_p+11; o++)
- {
- if ((teams[o].guy_on) && (teams[o].tm_dist<td*1.25)) // Inside pass range!
- {
- ox=teams[o].tm_x-ballx;
- oy=teams[o].tm_y-bally;
- od=teams[o].tm_dist;
- ox=ox/od;
- oy=oy/od;
- a=((tx*ox)+(ty*oy));
- if (a>0)
- {
- a=a*a*(96+(player->tm_flair/2))*td/od;
- // ang+=a*(player->tm_flair/64);
- ang+=a*(player->tm_flair/32);
- }
- }
- }
-
- if (passee_tab[p][2]==16 || passee_tab[p][2]==17)
- // Crossing over opps...
- {
- opps+=ang/5;
- opps=opps/4;
- }
- else
- opps+=ang;
-
- passee_tab[p][0]=opps; // Set preference level!
-
- af_randomize();
- // If straight ahead pass and need to chip...
- {
- if (passee_tab[p][2]==5 && (ang>seed/2 || (user_controlled && chip_pass)))
- // Chip over...
- passee_tab[p][2]=-1;
-
- }
- }
- }
- else
- {
- // User preference is for distance in facing direction only...
- float tx,ty,dif;
- float px=player->tm_x;
- float py=player->tm_y;
- float xf=player->tm_xdis;
- float yf=player->tm_ydis;
- float min_d=2000;
- short pr=-1;
- for (int p=0; p<passees; p++)
- {
- passee_tab[p][0]=100;
- team_mate=passee_tab[p][1]-1;
- tx=teams[team_mate].tm_x-px;
- ty=teams[team_mate].tm_y-py;
- if (plr_facing(tx,ty,player))
- {
- // Facing towards team-mate...
- d=calc_dist(tx,ty);
- if (d<min_d)
- {
- // Closest...
- min_d=d;
- pr=p;
- }
- }
- }
- if (pr>=0)
- passee_tab[pr][0]=0;
- }
- // Sort passee table in order of preference...
- qsort(passee_tab,passees,sizeof(int)*3,sort_less_than);
- if (user_controlled)
- {
- // Take first team-mate on table...
- pas=passee_tab[0][1];
- pass_type=passee_tab[0][2];
- }
- else
- {
- // Random selection weighted towards first in table...
- int chance;
- pas=0;
- for (int p=0; p<passees; p++)
- {
- af_randomize();
- chance=passee_tab[p][0];
-
- if (chance<MAX_PASS_PROB)
- chance=MAX_PASS_PROB;
- else
- if (chance>MIN_PASS_PROB)
- chance=MIN_PASS_PROB;
-
- if (set_piece_on)
- chance=chance/2;
-
- if (seed>chance)
- {
- // Choose this guy to pass to!
- pas=passee_tab[p][1];
- pass_type=passee_tab[p][2];
- p=passees+1;
- }
- }
- }
- if (!pas && (must_pass || user_controlled))
- // Must choose!
- {
- pas=passee_tab[0][1];
- pass_type=passee_tab[0][2];
- }
- }
- else
- // Absolutely no one to pass to...
- {
- if ((must_pass) || (user_controlled))
- pas=0;
- }
- must_pass=FALSE;
- if (pas>0)
- {
- // He is passing to someone...
- d=calc_dist(teams[pas-1].tm_x-ballx,teams[pas-1].tm_y-bally);
-
- if (ball_in_hands && (player->tm_player==KP_A || player->tm_player==KP_B))
- {
- if (opp_around(teams[pas-1].tm_x,teams[pas-1].tm_y,pas))
- // Don't pass it out... (opponents around!)
- pas=0;
- else
- // Keeper must throw or something...
- if (d<prat*10)
- pass_type=9; // Roll it.
- else
- if (d<prat*20)
- pass_type=10; // Throw it.
- else
- pass_type=11; // Halfvoll it.
- }
- else
- {
- if ((ball_in_hands) && (teams[ball_poss-1].tm_act==THROW_ACT))
- {
- // Player must throw...
- if (d<prat*15)
- pass_type=12; // Throw short.
- else
- pass_type=13; // Throw Long.
- }
- else
- {
- if (heading_ball)
- pass_type=15;
- }
- }
- }
- return(pas);
- }
- /******************************************************************************
- *****************************************************************************/
- void process_comments()
- {
- if (want_pass_stat!=last_touch)
- {
- // His team_mate does not have ball anymore...
- if (want_pass)
- {
- teams[want_pass-1].tm_comm=0;
- teams[want_pass-1].tm_ccnt=0;
- reset_ideas(&teams[want_pass-1]);
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void init_speech(int p,int comm,int t)
- {
- speech_tab[p-1].say=comm;
- if (t)
- speech_tab[p-1].cnt=t;
- else
- speech_tab[p-1].cnt=SPEECH_SECS*game_speed;
- }
- /******************************************************************************
- *****************************************************************************/
- void process_speech()
- {
- for (int i=1; i<players+3; i++)
- {
- if (speech_tab[i-1].cnt)
- {
- speech_tab[i-1].cnt--;
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void player_comment(match_player *player)
- {
- if (player->tm_comm)
- {
- if ((!(--player->tm_ccnt)) || (player->tm_act>TURN_ACT))
- {
- player->tm_comm=0;
- if (want_pass==player->tm_player)
- want_pass=0;
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void tackle_decide(match_player *player)
- {
- }
- /******************************************************************************
- *****************************************************************************/
- void steal_decide(match_player *player)
- {
- }
- /******************************************************************************
- *****************************************************************************/
- void block_decide(match_player *player)
- {
- }
- /******************************************************************************
- *****************************************************************************/
- void user_free_ball(match_player *player)
- {
- player->tm_stopped=FALSE;
- }
- /******************************************************************************
- *****************************************************************************/
- void other_interceptor(match_player *player)
- {
- if (receiver_a==player->tm_player)
- receiver_a=FALSE;
- if (receiver_b==player->tm_player)
- receiver_b=FALSE;
- player->tm_notme=1+player->tm_flair/16;
- }
- /******************************************************************************
- *****************************************************************************/
- void free_ball(match_player *player)
- {
- player->tm_stopped=FALSE;
- if ((!dead_ball_cnt) && (!player->tm_leave))
- {
- if (!ball_out_of_play)
- {
- if ((player->tm_player==KP_A) || (player->tm_player==KP_B))
- {
- // Goal Keeper...
-
- if ((player->tm_player==KP_A && keeper_a_in_box)
- || (player->tm_player==KP_B && keeper_b_in_box))
- if (shot_pending>0 && !shot_acknowledged && player->tm_dist<prat*50)
- {
- if (cannot_pick_up<=0 || ((player->tm_player<12 && cannot_pick_up>11)
- || (player->tm_player>11 && cannot_pick_up<12)))
- #ifdef EURO96
- // This looks silly but leave for time being...
- if (penalty_shot && user_controlled)
- {
- if (uf1 || uf2)
- go_to_save_path(player);
- }
- else
- go_to_save_path(player);
- #else
- go_to_save_path(player);
- #endif
- }
- else
- {
- if (player->tm_dist<80 && ball_inair)
- {
- // Ball is quite close...
- go_to_save_path(player);
- }
- }
- }
- if ((!penalty_game) && (player->tm_act!=SAVE_ACT) && (player->int_move!=I_SAVE_WAIT))
- {
- if ((thinking(player)) && (player->tm_act<=TURN_ACT))
- {
- if (player->tm_off)
- // In offside position, must get out...
- {
- run_back(player);
- }
- }
- if (!interceptor_a)
- {
- if (near_path_a==player->tm_player)
- {
- if (go_to_path(near_path_a))
- // other_interceptor(player);
- // else
- {
- if (auto_users_a && !player->control)
- {
- {
- reselect_a();
- user_conts(player);
- }
- }
- }
- }
- }
- if (!interceptor_b)
- {
- if (near_path_b==player->tm_player)
- {
- if (go_to_path(near_path_b))
- // other_interceptor(player);
- // else
- {
- if (auto_users_b && !player->control)
- {
- {
- reselect_b();
- user_conts(player);
- }
- }
- }
- }
- }
- }
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void out_of_vis(match_player *player)
- {
- }
- /******************************************************************************
- *****************************************************************************/
- void range_flags(match_player *player)
- {
- float x=player->tm_x;
- float y=player->tm_y;
- float d;
- if (player->tm_player>11)
- // B
- {
- d=calc_dist(x,cntspot_y-y);
- }
- else
- // A
- {
- d=calc_dist(pitch_len-x,cntspot_y-y);
- }
- if (d<MIN_HEADER_RNG+(prat*player->tm_pow/8))
- in_header_rng=TRUE;
- else
- in_header_rng=FALSE;
- if (d<(MIN_SHOOT_DIST+((float)player->tm_pow*3)))
- in_shot_rng=TRUE;
- else
- in_shot_rng=FALSE;
- }
-
- /******************************************************************************
- *****************************************************************************/
- // Is guy with ball in "crossing area".
- // Which is a diagonal line from goal post to nearest sideline.
- void cross_pos(match_player *player)
- {
- in_cross_area=FALSE;
- if (bally>bot_post_y)
- {
- if (player->tm_player>11)
- {
- if (ballx<(bally-bot_post_y))
- // Within diagonal from bot. left post to sideline!
-
- in_cross_area=TRUE;
- }
- else
- {
- if ((pitch_len-ballx)<(bally-bot_post_y))
- // Within diagonal from bot. right post to sideline!
-
- in_cross_area=TRUE;
- }
- }
- else
- {
- if (bally<top_post_y)
- {
- if (player->tm_player>11)
- {
- if (ballx<(top_post_y-bally))
- // Within diagonal from top left post to sideline!
-
- in_cross_area=TRUE;
- }
- else
- {
- if ((pitch_len-ballx)<(top_post_y-bally))
-
- // Within diagonal from top right post to sideline!
-
- in_cross_area=TRUE;
- }
- }
- }
- }
-
- /******************************************************************************
- *****************************************************************************/
- void set_pos_flags(match_player *player)
- {
- cross_pos(player);
- range_flags(player);
- }
- /******************************************************************************
- *****************************************************************************/
- void user_got_ball(match_player *player)
- {
- int p=0;
- set_pos_flags(player);
- if (player->tm_act==STAND_ACT)
- user_spec_kick(player);
- else
- {
- if (uf2 && um)
- // Pass in dir!
- {
- int p=(pass_decide(player,in_cross_area));
- if (pass_type==16 || pass_type==17)
- make_pass(player,p,TRUE);
- else
- {
- if (!p)
- pass_type=5; // Forward tap...
- spec_kick_type=SPACT_FPASS;
- setp_kick_x=player->tm_xdis;
- setp_kick_y=player->tm_ydis;
- make_pass(player,p,FALSE);
- }
- }
- else
- {
- if (uf1 && um)
- // Try shooting...
- {
- if (shoot_decide(player))
- make_shoot(player);
- else
- // Try punt...
- {
- if (punt_decide(player))
- make_punt(player);
- else
- // Try high pass to head...
- {
- chip_pass=TRUE;
- int p=(pass_decide(player,FALSE));
- if (p && (pass_type==16 || pass_type==17 || pass_type==-1))
- make_pass(player,p,TRUE);
- else
- {
- p=0;
- chip_pass=FALSE;
- pass_type=-1; // Forward tap...
- spec_kick_type=SPACT_FPASS;
- setp_kick_x=player->tm_xdis;
- setp_kick_y=player->tm_ydis;
- make_pass(player,p,FALSE);
- }
- }
- }
- }
- }
- }
- /*
- else
- {
- if (must_punt)
- if (punt_decide(player))
- make_punt(player);
- else
- {
- if (uf1)
- {
- // He has pressed front fire button (1)!
- // PUNT!
- if (punt_decide(player))
- make_punt(player);
- else
- {
- // SHOOT!
- if (player->tm_srng)
- {
- shoot_decide(player);
- make_shoot(player);
- }
- else
- {
- must_pass=TRUE;
- chip_pass=TRUE;
- int p=pass_decide(player,FALSE);
- make_pass(player,p,FALSE);
- }
- }
- }
- else
- {
- if (uf2)
- {
- // He has pressed top fire button (2)!
- must_pass=TRUE;
- // CROSS!
- if (in_cross_area)
- {
- p=(pass_decide(player,TRUE));
- if (p)
- make_pass(player,p,TRUE);
- }
- if (!p)
- {
- // PASS!
- p=(pass_decide(player,FALSE));
- if (p)
- make_pass(player,p,FALSE);
- }
- }
- }
- }
- }
- }
- */
- set_piece_on=FALSE;
- }
- /******************************************************************************
- *****************************************************************************/
- void got_ball(match_player *player)
- {
- int p=0;
- if ((player->tm_player==KP_A) || (player->tm_player==KP_B))
- {
- /****************
- ** Goal-Keeper **
- ****************/
- // PUNT!
- if (punt_decide(player))
- make_punt(player);
- else
- {
- // PASS!
- int p=(pass_decide(player));
- if (p)
- make_pass(player,p);
- else
- {
- if ((player->tm_player==KP_A && keeper_a_in_box)
- || (player->tm_player==KP_B && keeper_b_in_box))
- {
- // Can pick ball up...
- if (!ball_in_hands)
- {
- if ((cannot_pick_up<=0)
- || (cannot_pick_up<12 && ball_poss>11 && keeper_b_in_box)
- || (cannot_pick_up>11 && ball_poss<12 && keeper_a_in_box))
- {
- if (opp_around(ballx,bally,player->tm_player))
- {
- holder_lose_ball();
- keep_dive=TRUE;
- go_to_save_path(player,TRUE);
- }
- else
- init_pickup_act(player);
- }
- else
- {
- if (player->tm_poss)
- must_punt=TRUE;
- if (punt_decide(player))
- make_punt(player);
- else
- // RUN!
- make_run(player);
- }
- }
- }
- else
- {
- // Can't touch ball with hands...
- must_punt=TRUE;
- }
- }
- }
- }
- else
- {
- /***********
- ** PLAYER **
- ***********/
- // Not taking throw!
- set_pos_flags(player);
- // SHOOT!
- if (shoot_decide(player))
- make_shoot(player);
- else
- {
- // CROSS!
- if (in_cross_area)
- {
- p=(pass_decide(player,TRUE));
- if (p)
- if (pass_type==16 || pass_type==17)
- make_pass(player,p,TRUE);
- else
- make_pass(player,p,FALSE);
- }
- if (!p)
- {
- // PASS!
- p=(pass_decide(player));
- if (p)
- make_pass(player,p);
- else
- {
- // PUNT!
- if (punt_decide(player))
- make_punt(player);
- else
- {
- // RUN!
- make_run(player);
- }
- }
- }
- }
- }
- set_piece_on=FALSE;
- }
- /******************************************************************************
- *****************************************************************************/
- int help_chance(match_player *player)
- {
- int f=64+(player->tm_flair/2);
- float r,xd;
- // Less calculated range if pass is to be made up-field...
- if (player->tm_player>11)
- // Team B...
- {
- xd=player->tm_x-ballx;
- if (xd>0)
- xd=xd*2;
- }
- else
- // Team A...
- {
- xd=player->tm_x-ballx;
- if (xd<0)
- xd=xd*2;
- }
- r=calc_dist(xd,bally-player->tm_y)/(prat*2);
- int help;
- if (support_me)
- help=512-(r*r);
- else
- help=32+(opponents_near_holder*80*f/128)
- -(opp_around(player->tm_x,player->tm_y,player->tm_player)*64*f/128)
- -(r*r);
- // Dead ball situation...
- return(help);
- }
- /******************************************************************************
- *****************************************************************************/
- void we_have_ball(match_player *player)
- {
- if (player->tm_player!=KP_A && player->tm_player!=KP_B && !player->tm_stopped
- && match_mode!=PEN_KICK_A && match_mode!=PEN_KICK_B)
- {
- if ((thinking(player)) && (player->tm_act<=TURN_ACT))
- {
- if (player->tm_off)
- // In offside position, must get out...
- {
- run_back(player);
- }
- else
- {
- if (!want_pass)
- {
- int help=help_chance(player);
- if (help<MIN_HELP_CHANCE)
- help=MIN_HELP_CHANCE;
- if (seed<=help)
- // Ask for Pass!
- {
- if (player->tm_dist<CALL_DIST)
- // if (angle_of_vis(player,ballx-player->tm_x,bally-player->tm_y,player->tm_dist,FALSE))
- {
- want_pass=player->tm_player;
- want_pass_stat=ball_poss;
- player->tm_ccnt=40;
- player->tm_comm=-SAY_PASS;
- reset_ideas(player);
- player->int_move=I_RUN_ON;
- player->int_cnt=40;
- if (in_cross_area)
- {
- float x=player->tm_x;
- float y=player->tm_y;
- int i=player->tm_player;
- if ((i<12) && (x>(pitch_len-(prat*15))) && (y>(cntspot_y-(prat*18)))
- && (y<(cntspot_y+(prat*18)))
- && (teams[i].tm_dist>(prat*20)))
- player->tm_comm=-SAY_CROSS;
- if ((i>11) && (x<(prat*15)) && (y>(cntspot_y-(prat*18)))
- && (y<(cntspot_y+(prat*18)))
- && (teams[i].tm_dist>(prat*20)))
- player->tm_comm=-SAY_CROSS;
- }
- // Run towards opponents penalty spot...
- float x,y,d;
- if (player->tm_player<12)
- x=pitch_len-ballx;
- else
- x=-ballx;
- y=cntspot_y-bally;
-
- d=calc_dist(x,y);
- // How far is half way to goal...
- float kd=kicking_dist(&teams[ball_poss-1],x,y,d)-(prat*2);
- if (d/2<kd)
- init_run_act(player,ballx+x/2,bally+y/2,FALSE);
- else
- init_run_act(player,ballx+(x/d*kd),bally+(y/d*kd),FALSE);
- player->int_cnt=player->go_cnt;
- player->tm_ccnt=player->go_cnt;
- }
- else
- {
- if (!support_me)
- {
- player->tm_ccnt=40;
- player->tm_comm=-SAY_GIVE;
- }
- }
- }
- }
- }
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- int in_close(match_player *player)
- {
- if (player->tm_dist<DRIB_DANGER_AREA)
- return(TRUE);
- else
- return(FALSE);
- }
- /*****************************************************************************
- *****************************************************************************/
- int can_close_down(match_player *player)
- {
- int p=player->tm_player;
- if ((nearest_a==p) || (nearest_b==p))
- return(TRUE);
- else
- return(FALSE);
- }
- /*****************************************************************************
- *****************************************************************************/
- void close_him_down(match_player *player)
- {
- player->int_move=I_CLOSE_DOWN;
- player->int_cnt=(player->tm_flair/4);
- if (!go_to_path(player->tm_player))
- other_interceptor(player);
- action="Close Down";
- }
- /*****************************************************************************
- *****************************************************************************/
- void force_error(match_player *player)
- {
- if ((player->tm_player<12 && !auto_users_a)
- || (player->tm_player>11 && !auto_users_b))
- {
- // No team users so computer must control this guy...
- if (player->tm_dist<STEAL_DIST || teams[ball_poss-1].tm_act==TACKLE_ACT)
- {
- if (!go_to_path(player->tm_player))
- other_interceptor(player);
- // else
- // player->int_move=I_STEAL;
- }
- else
- {
- int chance=32;
- if (player->tm_player<12)
- // The further up the park, the more chance of direct tackling!
- chance-=((pitch_len-player->tm_x)/48);
- else
- chance-=(player->tm_x/48);
- if (chance<=seed && teams[ball_poss-1].tm_act!=TACKLE_ACT
- && teams[ball_poss-1].int_move!=I_GET_UP)
- get_tack_path(player);
- else
- go_to_between(player->tm_player); // get yourself between him and goal!
- }
- }
- }
- /*****************************************************************************
- *****************************************************************************/
- void forceful_retrieve(match_player *player)
- {
- if ((player->tm_player<12 && !auto_users_a)
- || (player->tm_player>11 && !auto_users_b))
- {
- // No team users so computer must control this guy...
- get_tack_path(player);
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void go_to_side(match_player *player)
- // Send player to the side off opponent with ball...
- {
- // His intention is to intercept ball.
- // Therefore his flair determines no. of turns before rethink!
- int ff=33-(player->tm_flair/4);
- player->int_move=I_INTERCEPT; // Intercept ball!
- player->int_cnt=ff; // Flair factor.
- float dx=teams[ball_poss-1].tm_xdis;
- float dy=teams[ball_poss-1].tm_ydis;
- float x=(ballx-player->tm_x)/player->tm_dist; // vector to ball...
- float y=(bally-player->tm_y)/player->tm_dist;
- // Which side to go to...???
- if ((x*dy)>(y*dx))
- {
- x=-dy; // 90 degrees clockwise...
- y=dx;
- }
- else
- {
- x=dy; // 90 degrees anti-clockwise...
- y=-dx;
- }
- x=ballx+(x*prat);
- y=bally+(y*prat);
- init_run_act(player,x,y,TRUE); //Go to path point!
- }
- /******************************************************************************
- *****************************************************************************/
- void go_to_between(int p_num)
- // Send player(p_num) to intersection point between ball path and goal centre.
- // If he cannot meet ball then best try!
- {
- int x,y,z,d;
- float px=teams[p_num-1].tm_x;
- float py=teams[p_num-1].tm_y;
- float goal_x;
- int rate=actual_spd(&teams[p_num-1]);
- action="Between";
- if (p_num<12)
- goal_x=0;
- else
- goal_x=pitch_len;
- // His intention is to intercept ball.
- // Therefore his flair determines no. of turns before rethink!
- int ff=33-(teams[p_num-1].tm_flair/4);
- teams[p_num-1].int_move=I_INTERCEPT; // Intercept ball!
- teams[p_num-1].int_cnt=ff; // Flair factor.
- for (int i=1; i<50; i++)
- {
- x=ball_pred_tab[i][0];
- y=ball_pred_tab[i][1];
- z=ball_pred_tab[i][2];
- d=calc_dist(goal_x-x,cntspot_y-y);
- if (d<1)
- d=1;
-
- x=x+(((goal_x-x)*BETWEEN_DIST)/d);
- y=y+(((cntspot_y-y)*BETWEEN_DIST)/d);
- if (z<=PLAYER_HEIGHT)
- {
- d=calc_dist(x-px,y-py);
- // d=(int)(((float)d)/rate); //How many steps?
- d=get_there_time(p_num,x,y); //How many steps?
- if (d<=i)
- // He can get there in time!
- {
- init_run_act(&teams[p_num-1],x,y,TRUE); //Go to path point!
- i=60; // End For Loop!
- }
- }
- }
- if (i<60)
- // He cant intersect!
- init_run_act(&teams[p_num-1],x,y,FALSE); // run toward last.
- }
- /******************************************************************************
- *****************************************************************************/
- void user_opp_has_ball(match_player *player)
- {
- if (uf1)
- // Tackle opp.
- {
- user_init_tackle(player);
- }
- else
- {
- if (uf2)
- // Steal from opp.
- {
- if (player->tm_dist<(STEAL_DIST/4))
- {
- init_steal_act(player);
- }
- #ifdef EURO96
- else
- // Burst_of_speed...
- {
- if (!burst_timer[user_controlled-1]--)
- burst_timer[user_controlled-1]=REAL_SPEED;
- else
- if (!burst_timer[user_controlled-1])
- burst_timer[user_controlled-1]=-1;
- }
- #endif
- }
- else
- burst_timer[user_controlled-1]=0;
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void opp_has_ball(match_player *player)
- {
- if ((player->tm_player==KP_A) || (player->tm_player==KP_B))
- {
- /****************
- ** Goal-Keeper **
- ****************/
- if (player->tm_player<12)
- // KP_A...
- {
- if ((keeper_a_in_box) && (player->tm_dist<DIVE_FEET_DIST) && (seed>player->tm_flair))
- // Can dive for ball...
- {
- keep_dive=TRUE;
- go_to_save_path(player,TRUE);
- }
- }
- else
- // KP_B...
- {
- if ((keeper_b_in_box) && (player->tm_dist<DIVE_FEET_DIST) && (seed>player->tm_flair))
- // Can dive for ball...
- {
- keep_dive=TRUE;
- go_to_save_path(player,TRUE);
- }
- }
- }
- {
- /***********
- ** PLAYER **
- ***********/
- if ((ball_in_hands) || (ball_out_of_play))
- // Don't tackle keeper directly!
- {
- }
- else
- {
- if ((player->tm_pos) && (player->tm_pos<=close_in_number)
- && ((player->tm_player!=KP_A) && (player->tm_player!=KP_B))
- || (player->tm_pos==1))
- {
- // There's not too many guys going for opponent with ball!
- if (in_close(player))
- // I am close enough to hassle!
- {
- short d=get_facing_opp_dir(player);
- if (d==-1)
- {
- // He has his back to me!
- if ((ball_speed<1) && ((seed&4)
- || (player->tm_player>11 && ballx<cntspot_x)
- || (player->tm_player<12 && ballx>cntspot_x)))
- // Try and go round a bit...
- go_to_side(player);
- else
- if ((teams[ball_poss-1].tm_act==TACKLE_ACT && teams[ball_poss-1].go_cnt>EFFECTIVE_TACK)
- || teams[ball_poss-1].int_move==I_GET_UP)
- force_error(player);
- else
- go_to_between(player->tm_player); // get yourself between him and goal!
- }
- else
- // He is not shielding ball!
- {
- if (d==1)
- {
- // He has his side to me!
- if (seed&8 && (teams[ball_poss-1].tm_act==TACKLE_ACT || teams[ball_poss-1].int_move==I_GET_UP))
- // Opponent is not able to turn and avoid... (So go directly to ball!)
- force_error(player);
- else
- if ((player->tm_player!=KP_A) && (player->tm_player!=KP_B))
- // Not the keeper!
- forceful_retrieve(player); // Tackle directly!
- else
- force_error(player);
- }
- else
- // He is facing towards me!
- force_error(player); // More patient style of attack!
- }
- }
- else
- // Not in close enough!
- {
- if (can_close_down(player))
- // I can close him down!
- close_him_down(player);
- }
- }
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void user_intelligence(match_player *player)
- {
- if (match_mode || !ball_poss)
- intelligence(player);
- else
- {
- char busy=0;
- if (player->int_cnt) //Is he busy?
- {
- if (--(player->int_cnt))
- busy=1;
- else
- {
- player->int_cnt=-1;
- reset_ideas(player);
- }
- }
- if (player->tm_act<=TURN_ACT) // Player is standing or running or turning!
- {
- if (!busy)
- {
- if (!ball_poss)
- user_free_ball(player);
- else
- {
- if (ball_poss==player->tm_player)
- user_got_ball(player);
- else
- {
- if (((ball_poss<12) && (player->tm_player>11))
- || ((ball_poss>11) && (player->tm_player<12)))
- user_opp_has_ball(player);
- }
- }
- }
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void offside_rule(match_player *player)
- {
- if (player->tm_player<12)
- // Team A...
- {
- if ((!match_mode) && (!ball_poss && ball_released>0) && (last_touch<12)
- && (last_touch!=player->tm_player) && (player->tm_off) && (!just_scored)
- && (ballx<player->tm_x))
- // && (ballx<player->tm_x) && receiver_a==player->tm_player)
- // His team-mate has released ball and he is in an offside pos...
- init_offside(player); // Does Linesman see it!
- else
- if ((ball_poss<12) && (player->tm_x>cntspot_x)
- && (can_be_offside) && (player->tm_x>(defense_b+prat)) && (!just_scored))
- // Player is in opponents half, his opponent doesn't have ball and
- // in normal play, and no defenders behind.
- {
- if (!player->tm_off)
- player->tm_off=-1; // Potential Offside (get back).
- }
- else
- player->tm_off=FALSE; // Not offside.
- }
- else
- // Team B...
- {
- if ((!match_mode) && (!ball_poss && ball_released<0) && (last_touch>11)
- && (last_touch!=player->tm_player) && (player->tm_off) && (!just_scored)
- && (ballx>=player->tm_x))
- // && (ballx>=player->tm_x) && receiver_b==player->tm_player)
- // His team-mate has released ball and he is in an offside pos...
- init_offside(player); // Does Linesman see it!
- else
- if ((ball_poss>11 || !ball_poss) && (player->tm_x<cntspot_x)
- && (can_be_offside) && (player->tm_x<(defense_a-prat)) && (!just_scored))
- // Player is in opponents half, his team mate has the ball
- // in normal play, and no defenders behind.
- {
- if (!player->tm_off)
- player->tm_off=-1; // Potential Offside (get back).
- }
- else
- player->tm_off=FALSE; // Not offside.
- }
- if ((player->tm_off==TRUE) && (!match_mode) && (!just_scored))
- // Linesman has indicated offside...
- {
- // Is he interfering with play...
- if (player->tm_dist<ref_strictness*1.1)
- {
- offside_now=TRUE;
- init_foul(player->tm_player,FALSE,TRUE); // Indirect F.K. for offside!
- player->tm_off=FALSE;
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void override(match_player *player)
- {
- if (offside_on)
- offside_rule(player);
- }
- /******************************************************************************
- *****************************************************************************/
- void remove_player(match_player *player)
- {
- player->guy_on=FALSE;
- if (!player_being_subbed)
- {
- hold_up_play=4*REAL_SPEED;
- camera=sub_camera;
- player_on_off=FALSE;
- ref_wait=(160-ref_strictness)*REAL_SPEED/8;
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void init_off_int(match_player *player)
- {
- allow_replay=FALSE;
- float tx=stadlist[setup.stadium].tunlx;
- float ty=-stadlist[setup.stadium].tunlz;
- float tly;
- if (ty>cntspot_y)
- ty+=60;
- else
- ty-=60;
- if (player_on_off>0 && calc_dist(tx-player->tm_x,ty-player->tm_y)<prat*2)
- {
- // In tunnel! (get off)!
- remove_player(player);
- player->tm_trap=0;
- }
- else
- {
- player->draw_me=TRUE;
- player->int_cnt=600;
- player->int_move=I_OFF;
- if (ty>cntspot_y)
- tly=pitch_wid;
- else
- tly=0;
- if (player->tm_trap || calc_dist(tx-player->tm_x,tly-player->tm_y)<prat*2)
- // At touch-line...(send him into tunnel)!
- {
- if (player_on_off<0)
- {
- // Coming on...
- player->int_move=0;
- reset_ideas(player);
- player_on_off=FALSE;
- camera=sub_camera;
- allow_replay=TRUE;
- }
- else
- {
- player->tm_trap=TRUE;
- init_run_act(player,tx,ty,0);
- }
- }
- else
- // send him to touch-line...
- init_run_act(player,tx,tly,0);
- }
- }
- /******************************************************************************
- *****************************************************************************/
- void intelligence(match_player *player)
- {
- if ((player->control) && (!match_mode) && (ball_poss))
- {
- // Player has just collected ball and been auto selected...
- user_controlled=player->control;
- user_intelligence(player);
- }
- else
- {
- char busy=0;
- int pnum=player->tm_player;
- if ((player->tm_leave) && (last_touch!=player->tm_player))
- player->tm_leave=FALSE; // he can touch ball again!
- if (player->int_cnt) //Is he busy?
- {
- if (--(player->int_cnt))
- {
- if (((pnum==KP_A) || (pnum==KP_B)) && (player->int_move==I_INTERCEPT)
- && (shot_pending>0))
- busy=0;
- else
- {
- busy=1;
- /*
- if (player->int_move==I_INTERCEPT && user_controlled && player->tm_strike>0)
- // User player is interecpting ball but hasn't chosen special move...
- go_to_path(player->tm_player);
- */
- if (player->int_move==I_OFF)
- {
- // He is going off!
- if (player->tm_act==STAND_ACT)
- init_off_int(player);
- }
- else
- {
- if (player->int_move==I_RUN_ON)
- // Calling for pass ahead...
- {
- if (plr_facing(player->go_xoff,player->go_yoff,player))
- {
- if (player->tm_comm<0)
- player->tm_comm=-player->tm_comm;
- }
- else
- {
- if (player->tm_comm>0)
- {
- player->tm_comm=FALSE;
- player->tm_ccnt=0;
- reset_ideas(player);
- }
- }
- }
- else
- {
- if (player->int_move==I_STEAL)
- {
- if (player->tm_dist<STEAL_BODY_DIST)
- {
- reset_ideas(player);
- init_steal_act(player);
- }
- }
- }
- }
- }
- }
- else
- {
- player->int_cnt=-1;
- if (player->int_move==I_SAVE_WAIT)
- {
- if (player->tm_act==RUN_ACT)
- player->int_cnt=player->go_cnt+2;
-
- if (player->int_cnt>0)
- {
- player->int_move=I_INTERCEPT;
- busy=1;
- }
- else
- reset_ideas(player);
- }
- else
- reset_ideas(player);
- }
- }
- if (player->tm_act<=TURN_ACT) // Player is standing or running or turning!
- {
- if (!busy && !just_scored)
- {
- if (player->guy_on<0)
- {
- // He has to be sent off!
- init_off_int(player);
- }
- if (dead_ball_cnt==0)
- // Are we in normal play...
- {
- if (!ball_poss)
- free_ball(player);
- else
- {
- if (ball_poss==pnum)
- got_ball(player);
- else
- {
- if ((pnum<12) && (ball_poss<12))
- // My team A has ball!
- we_have_ball(player);
- else
- {
- if ((pnum>11) && (ball_poss>11))
- // My team B has ball!
- we_have_ball(player);
- else
- opp_has_ball(player);
- }
- }
- }
- }
- else
- {
- // Is ball holder looking for support...
- if (ball_poss!=pnum && support_me)
- {
- if ((pnum<12) && (ball_poss<12))
- // My team A has ball!
- we_have_ball(player);
- else
- if ((pnum>11) && (ball_poss>11))
- // My team B has ball!
- we_have_ball(player);
- }
- }
- }
- }
- }
- }
- /******************************************************************************
- *****************************************************************************/
- /*
- void cant_block_opp(match_player *player,match_player *oplayer)
- {
- int vx=(int)(ballx+(oplayer->go_txdis*8)); //look 8 turns ahead
- int vy=(int)(bally+(oplayer->go_tydis*8));
- vx-=player->tm_x;
- vy-=player->tm_y;
- if (calc_dist(vx,vy)<=tackle_range)
- // In tackling range!
- {
- tackle_decide(player);
- if (flag)
- go_tackle(player,oplayer);
- else
- cant_tack_opp(player);
- }
- else
- cant_tack_opp(player);
- }
- */
|