1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167 |
- #ifdef PRECOMPILEDHEADERS
- #include "Tactical All.h"
- #else
- #include "items.h"
- #include "Action Items.h"
- #include "handle Items.h"
- #include "overhead.h"
- #include "weapons.h"
- #include "points.h"
- #include "tiledef.h"
- #include "worlddef.h"
- #include "worldman.h"
- #include "interface.h"
- #include "renderworld.h"
- #include "Animation Control.h"
- #include "font control.h"
- #include "render dirty.h"
- #include "World items.h"
- #include "text.h"
- #include "Timer Control.h"
- #include "wcheck.h"
- #include "interface items.h"
- #include "physics.h"
- #include "soldier profile.h"
- #include "interface dialogue.h"
- #include "quests.h"
- #include "message.h"
- #include "isometric utils.h"
- #include "los.h"
- #include "dialogue control.h"
- #include "ai.h"
- #include "soldier macros.h"
- #include "interface panels.h"
- #include "Strategic Town Loyalty.h"
- #include "soldier functions.h"
- #include "Map Screen Helicopter.h"
- #include "pathai.h"
- #include "fov.h"
- #include "MessageBoxScreen.h"
- #include "explosion control.h"
- #include "SkillCheck.h"
- #include "Campaign.h"
- #include "Random.h"
- #include "structure wrap.h"
- #include "interactive tiles.h"
- #include "SaveLoadMap.h"
- #include "ShopKeeper Interface.h"
- #include "Arms Dealer Init.h"
- #include "soldier add.h"
- #include "sound control.h"
- #include "squads.h"
- #include "rotting corpses.h"
- #include "soldier ani.h"
- #include "Opplist.h"
- #include "qarray.h"
- #include "render fun.h"
- #include "environment.h"
- #endif
- #define NUM_ITEMS_LISTED 8
- #define NUM_ITEM_FLASH_SLOTS 50
- #define MIN_LOB_RANGE 6
- ITEM_POOL_LOCATOR FlashItemSlots[ NUM_ITEM_FLASH_SLOTS ];
- UINT32 guiNumFlashItemSlots = 0;
- LEVELNODE *AddItemGraphicToWorld( INVTYPE *pItem, INT16 sGridNo, UINT8 ubLevel );
- INT8 GetListMouseHotSpot( INT16 sLargestLineWidth, INT8 bNumItemsListed, INT16 sFontX, INT16 sFontY, INT8 bCurStart );
- void RemoveItemGraphicFromWorld( INVTYPE *pItem, INT16 sGridNo, UINT8 ubLevel, LEVELNODE *pLevelNode );
- ITEM_POOL * GetItemPoolForIndex( INT16 sGridNo, INT32 iItemIndex, UINT8 ubLevel );
- INT32 GetFreeFlashItemSlot(void);
- void RecountFlashItemSlots(void);
- INT32 AddFlashItemSlot( ITEM_POOL *pItemPool, ITEM_POOL_LOCATOR_HOOK Callback, UINT8 ubFlags );
- BOOLEAN RemoveFlashItemSlot( ITEM_POOL *pItemPool );
- // Disgusting hacks: have to keep track of these values for accesses in callbacks
- static SOLDIERTYPE * gpTempSoldier;
- static INT16 gsTempGridno;
- static INT8 bTempFrequency;
- void BombMessageBoxCallBack( UINT8 ubExitValue );
- void BoobyTrapMessageBoxCallBack( UINT8 ubExitValue );
- void SwitchMessageBoxCallBack( UINT8 ubExitValue );
- void BoobyTrapDialogueCallBack( void );
- void MineSpottedDialogueCallBack( void );
- void MineSpottedLocatorCallback( void );
- void RemoveBlueFlagDialogueCallBack( UINT8 ubExitValue );
- void MineSpottedMessageBoxCallBack( UINT8 ubExitValue );
- void CheckForPickedOwnership( void );
- void BoobyTrapInMapScreenMessageBoxCallBack( UINT8 ubExitValue );
- BOOLEAN ContinuePastBoobyTrap( SOLDIERTYPE * pSoldier, INT16 sGridNo, INT8 bLevel, INT32 iItemIndex, BOOLEAN fInStrategic, BOOLEAN *pfSaidQuote );
- extern BOOLEAN ItemIsCool( OBJECTTYPE * pObj );
- extern INT8 gbItemPointerSrcSlot;
- extern void MAPEndItemPointer( );
- extern BOOLEAN gfResetUIMovementOptimization;
- BOOLEAN ItemPoolOKForPickup( SOLDIERTYPE * pSoldier, ITEM_POOL *pItemPool, INT8 bZLevel );
- SOLDIERTYPE * gpBoobyTrapSoldier;
- ITEM_POOL * gpBoobyTrapItemPool;
- INT16 gsBoobyTrapGridNo;
- INT8 gbBoobyTrapLevel;
- BOOLEAN gfDisarmingBuriedBomb;
- extern BOOLEAN gfDontChargeAPsToPickup;
- INT8 gbTrapDifficulty;
- BOOLEAN gfJustFoundBoobyTrap = FALSE;
- void StartBombMessageBox( SOLDIERTYPE * pSoldier, INT16 sGridNo );
- BOOLEAN HandleCheckForBadChangeToGetThrough( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pTargetSoldier, INT16 sTargetGridNo , INT8 bLevel )
- {
- BOOLEAN fBadChangeToGetThrough = FALSE;
- if ( pTargetSoldier != NULL )
- {
- if ( SoldierToSoldierBodyPartChanceToGetThrough( pSoldier, pTargetSoldier, pSoldier->bAimShotLocation ) < OK_CHANCE_TO_GET_THROUGH )
- {
- fBadChangeToGetThrough = TRUE;
- }
- }
- else
- {
- if ( SoldierToLocationChanceToGetThrough( pSoldier, sTargetGridNo, (INT8) bLevel, 0, NOBODY ) < OK_CHANCE_TO_GET_THROUGH )
- {
- fBadChangeToGetThrough = TRUE;
- }
- }
- if ( fBadChangeToGetThrough )
- {
- if ( gTacticalStatus.sCantGetThroughSoldierGridNo != pSoldier->sGridNo || gTacticalStatus.sCantGetThroughGridNo != sTargetGridNo || gTacticalStatus.ubCantGetThroughID != pSoldier->ubID )
- {
- gTacticalStatus.fCantGetThrough = FALSE;
- }
- // Have we done this once already?
- if ( !gTacticalStatus.fCantGetThrough )
- {
- gTacticalStatus.fCantGetThrough = TRUE;
- gTacticalStatus.sCantGetThroughGridNo = sTargetGridNo;
- gTacticalStatus.ubCantGetThroughID = pSoldier->ubID;
- gTacticalStatus.sCantGetThroughSoldierGridNo = pSoldier->sGridNo;
- // PLay quote
- TacticalCharacterDialogue( pSoldier, QUOTE_NO_LINE_OF_FIRE );
- return( FALSE );
- }
- else
- {
- // Is this a different case?
- if ( gTacticalStatus.sCantGetThroughGridNo != sTargetGridNo || gTacticalStatus.ubCantGetThroughID != pSoldier->ubID || gTacticalStatus.sCantGetThroughSoldierGridNo != pSoldier->sGridNo )
- {
- // PLay quote
- gTacticalStatus.sCantGetThroughGridNo = sTargetGridNo;
- gTacticalStatus.ubCantGetThroughID = pSoldier->ubID;
- TacticalCharacterDialogue( pSoldier, QUOTE_NO_LINE_OF_FIRE );
- return( FALSE );
- }
- }
- }
- else
- {
- gTacticalStatus.fCantGetThrough = FALSE;
- }
- return( TRUE );
- }
- INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 usHandItem, BOOLEAN fFromUI )
- {
- SOLDIERTYPE *pTargetSoldier = NULL;
- UINT16 usSoldierIndex;
- INT16 sTargetGridNo;
- INT16 sAPCost;
- INT16 sActionGridNo;
- UINT8 ubDirection;
- INT16 sAdjustedGridNo;
- BOOLEAN fDropBomb = FALSE;
- BOOLEAN fAddingTurningCost = FALSE;
- BOOLEAN fAddingRaiseGunCost = FALSE;
- LEVELNODE *pIntNode;
- STRUCTURE *pStructure;
- INT16 sGridNo;
- // Remove any previous actions
- pSoldier->ubPendingAction = NO_PENDING_ACTION;
- // here is where we would set a different value if the weapon mode is on
- // "attached weapon"
- pSoldier->usAttackingWeapon = usHandItem;
- // Find soldier flags depend on if it's our own merc firing or a NPC
- //if ( FindSoldier( usGridNo, &usSoldierIndex, &uiMercFlags, FIND_SOLDIER_GRIDNO ) )
- if ( ( usSoldierIndex = WhoIsThere2( usGridNo, bLevel ) ) != NO_SOLDIER )
- {
- pTargetSoldier = MercPtrs[ usSoldierIndex ];
- if ( fFromUI )
- {
- // ATE: Check if we are targeting an interactive tile, and adjust gridno accordingly...
- pIntNode = GetCurInteractiveTileGridNoAndStructure( &sGridNo, &pStructure );
- if ( pIntNode != NULL && pTargetSoldier == pSoldier )
- {
- // Truncate target sioldier
- pTargetSoldier = NULL;
- }
- }
- }
- // ATE: If in realtime, set attacker count to 0...
- if ( !(gTacticalStatus.uiFlags & INCOMBAT) )
- {
- DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Setting attack busy count to 0 due to no combat" ) );
- gTacticalStatus.ubAttackBusyCount = 0;
- }
- if ( pTargetSoldier )
- {
- pTargetSoldier->bBeingAttackedCount = 0;
- }
- // Check our soldier's life for unconscious!
- if ( pSoldier->bLife < OKLIFE )
- {
- return( ITEM_HANDLE_UNCONSCIOUS );
- }
- if (HandItemWorks( pSoldier, HANDPOS ) == FALSE )
- {
- return( ITEM_HANDLE_BROKEN );
- }
- if ( fFromUI && pSoldier->bTeam == gbPlayerNum && pTargetSoldier && (pTargetSoldier->bTeam == gbPlayerNum || pTargetSoldier->bNeutral) && pTargetSoldier->ubBodyType != CROW && Item[ usHandItem ].usItemClass != IC_MEDKIT )
- {
- if ( pSoldier->ubProfile != NO_PROFILE )
- {
- // nice mercs won't shoot other nice guys or neutral civilians
- if ( (gMercProfiles[ pSoldier->ubProfile ].ubMiscFlags3 & PROFILE_MISC_FLAG3_GOODGUY) && ( (pTargetSoldier->ubProfile == NO_PROFILE && pTargetSoldier->bNeutral) || gMercProfiles[ pTargetSoldier->ubProfile ].ubMiscFlags3 & PROFILE_MISC_FLAG3_GOODGUY) )
- {
- TacticalCharacterDialogue( pSoldier, QUOTE_REFUSING_ORDER );
- return( ITEM_HANDLE_REFUSAL );
- }
- if ( pTargetSoldier->ubProfile != NO_PROFILE )
- {
- // buddies won't shoot each other
- if ( WhichBuddy( pSoldier->ubProfile, pTargetSoldier->ubProfile ) != -1 )
- {
- TacticalCharacterDialogue( pSoldier, QUOTE_REFUSING_ORDER );
- return( ITEM_HANDLE_REFUSAL );
- }
- }
- // any recruited rebel will refuse to fire on another rebel or neutral nameless civ
- if ( pSoldier->ubCivilianGroup == REBEL_CIV_GROUP && (pTargetSoldier->ubCivilianGroup == REBEL_CIV_GROUP || ( pTargetSoldier->bNeutral && pTargetSoldier->ubProfile == NO_PROFILE && pTargetSoldier->ubCivilianGroup == NON_CIV_GROUP && pTargetSoldier->ubBodyType != CROW ) ) )
- {
- TacticalCharacterDialogue( pSoldier, QUOTE_REFUSING_ORDER );
- return( ITEM_HANDLE_REFUSAL );
- }
- }
- }
- // Check HAND ITEM
- if ( Item[ usHandItem ].usItemClass == IC_GUN || Item[ usHandItem ].usItemClass == IC_THROWING_KNIFE )
- {
- // WEAPONS
- if ( usHandItem == ROCKET_RIFLE || usHandItem == AUTO_ROCKET_RIFLE )
- {
- // check imprint ID
- // NB not-imprinted value is NO_PROFILE
- // imprinted value is profile for mercs & NPCs and NO_PROFILE + 1 for generic dudes
- if (pSoldier->ubProfile != NO_PROFILE)
- {
- if ( pSoldier->inv[ pSoldier->ubAttackingHand ].ubImprintID != pSoldier->ubProfile )
- {
- if ( pSoldier->inv[ pSoldier->ubAttackingHand ].ubImprintID == NO_PROFILE )
- {
- // first shot using "virgin" gun... set imprint ID
- pSoldier->inv[ pSoldier->ubAttackingHand ].ubImprintID = pSoldier->ubProfile;
- // this could be an NPC (Krott)
- if (pSoldier->bTeam == gbPlayerNum)
- {
- PlayJA2Sample( RG_ID_IMPRINTED, RATE_11025, HIGHVOLUME, 1, MIDDLE );
-
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"\"%s\"", TacticalStr[ GUN_GOT_FINGERPRINT ] );
- return( ITEM_HANDLE_BROKEN );
- }
- }
- else
- {
- // access denied!
- if (pSoldier->bTeam == gbPlayerNum)
- {
- PlayJA2Sample( RG_ID_INVALID, RATE_11025, HIGHVOLUME, 1, MIDDLE );
- //if (Random( 100 ) < (UINT32) pSoldier->bWisdom)
- //{
- // DoMercBattleSound( pSoldier, BATTLE_SOUND_CURSE1 );
- //}
- //else
- //{
- // TacticalCharacterDialogue( pSoldier, QUOTE_USELESS_ITEM );
- //}
- }
- return( ITEM_HANDLE_BROKEN );
- }
- }
- }
- else
- {
- // guaranteed not to be controlled by the player, so no feedback required
- if ( pSoldier->inv[ pSoldier->ubAttackingHand ].ubImprintID != (NO_PROFILE + 1) )
- {
- if ( pSoldier->inv[ pSoldier->ubAttackingHand ].ubImprintID == NO_PROFILE )
- {
- pSoldier->inv[ pSoldier->ubAttackingHand ].ubImprintID = (NO_PROFILE + 1);
- }
- else
- {
- return( ITEM_HANDLE_BROKEN );
- }
- }
- }
- }
- // IF we are not a throwing knife, check for ammo, reloading...
- if ( Item[ usHandItem ].usItemClass != IC_THROWING_KNIFE )
- {
- // CHECK FOR AMMO!
- if ( !EnoughAmmo( pSoldier, fFromUI, HANDPOS ) )
- {
- //ATE: Reflect that we need to reset for bursting
- pSoldier->fDoSpread = FALSE;
- return( ITEM_HANDLE_NOAMMO );
- }
- // Check if we are reloading
- if ( (gTacticalStatus.uiFlags & REALTIME) || !(gTacticalStatus.uiFlags & INCOMBAT) )
- {
- if ( pSoldier->fReloading )
- {
- return( ITEM_HANDLE_RELOADING );
- }
- }
- }
- // Get gridno - either soldier's position or the gridno
- if ( pTargetSoldier != NULL )
- {
- sTargetGridNo = pTargetSoldier->sGridNo;
- }
- else
- {
- sTargetGridNo = usGridNo;
- }
- // If it's a player guy, check ChanceToGetThrough to play quote
- if ( fFromUI && (gTacticalStatus.uiFlags & TURNBASED ) && (gTacticalStatus.uiFlags & INCOMBAT) )
- {
- // Don't do if no spread!
- if ( !pSoldier->fDoSpread )
- {
- if ( !HandleCheckForBadChangeToGetThrough( pSoldier, pTargetSoldier, sTargetGridNo , bLevel ) )
- {
- return( ITEM_HANDLE_OK );
- }
- }
- }
- // Get AP COSTS
- // ATE: OK something funny going on here - AI seems to NEED FALSE here,
- // Our guys NEED TRUE. We shoulkd at some time make sure the AI and
- // our guys are deducting/checking in the same manner to avoid
- // these differences.
- sAPCost = CalcTotalAPsToAttack( pSoldier, sTargetGridNo, TRUE, pSoldier->bAimTime );
- GetAPChargeForShootOrStabWRTGunRaises( pSoldier, sTargetGridNo, TRUE, &fAddingTurningCost, &fAddingRaiseGunCost );
- // If we are standing and are asked to turn AND raise gun, ignore raise gun...
- if ( gAnimControl[ pSoldier->usAnimState ].ubHeight == ANIM_STAND )
- {
- if ( fAddingRaiseGunCost )
- {
- pSoldier->fDontChargeTurningAPs = TRUE;
- }
- }
- else
- {
- // If raising gun, don't charge turning!
- if ( fAddingTurningCost )
- {
- pSoldier->fDontChargeReadyAPs = TRUE;
- }
- }
-
- // If this is a player guy, show message about no APS
- if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) )
- {
- if ( (pSoldier->ubProfile != NO_PROFILE) && (gMercProfiles[ pSoldier->ubProfile ].bPersonalityTrait == PSYCHO) )
- {
- // psychos might possibly switch to burst if they can
- if ( !pSoldier->bDoBurst && IsGunBurstCapable( pSoldier, HANDPOS, FALSE ) )
- {
- // chance of firing burst if we have points... chance decreasing when ordered to do aimed shot
- // temporarily set burst to true to calculate action points
- pSoldier->bDoBurst = TRUE;
- sAPCost = CalcTotalAPsToAttack( pSoldier, sTargetGridNo, TRUE, 0 );
- // reset burst mode to false (which is what it was at originally)
- pSoldier->bDoBurst = FALSE;
- if ( EnoughPoints( pSoldier, sAPCost, 0, FALSE ) )
- {
- // we have enough points to do this burst, roll the dice and see if we want to change
- if ( Random( 3 + pSoldier->bAimTime ) == 0 )
- {
- DoMercBattleSound( pSoldier, BATTLE_SOUND_LAUGH1 );
- pSoldier->bDoBurst = TRUE;
- pSoldier->bWeaponMode = WM_BURST;
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[ 26 ], pSoldier->name );
- }
- }
- }
- }
- // Deduct points if our target is different!
- // if attacking a new target (or if the specific target is uncertain)
-
- // DEF: Made into an event
- // EVENT_FireSoldierWeapon( pSoldier, sTargetGridNo );
- if (fFromUI)
- {
- // set the target level; if the AI calls this it will have set the level already...
- pSoldier->bTargetLevel = (INT8) gsInterfaceLevel;
- }
- if ( Item[ usHandItem ].usItemClass != IC_THROWING_KNIFE )
- {
- // If doing spread, set down the first gridno.....
- if ( pSoldier->fDoSpread )
- {
- if ( pSoldier->sSpreadLocations[ 0 ] != 0 )
- {
- SendBeginFireWeaponEvent( pSoldier, pSoldier->sSpreadLocations[ 0 ] );
- }
- else
- {
- SendBeginFireWeaponEvent( pSoldier, sTargetGridNo );
- }
- }
- else
- {
- SendBeginFireWeaponEvent( pSoldier, sTargetGridNo );
- }
- // ATE: Here to make cursor go back to move after LAW shot...
- if ( fFromUI && usHandItem == ROCKET_LAUNCHER )
- {
- guiPendingOverrideEvent = A_CHANGE_TO_MOVE;
- }
- }
- else
- {
- UINT8 ubDirection;
- // Start knife throw attack
- // Get direction
- ubDirection = (UINT8)GetDirectionFromGridNo( sTargetGridNo, pSoldier );
- EVENT_SoldierBeginKnifeThrowAttack( pSoldier, sTargetGridNo, ubDirection );
- }
- if (fFromUI)
- {
- // Descrease aim by two if in real time
- if ( (gTacticalStatus.uiFlags & REALTIME ) || !(gTacticalStatus.uiFlags & INCOMBAT) )
- {
- //pSoldier->bShownAimTime -= 2;
- //if ( pSoldier->bShownAimTime < REFINE_AIM_1 )
- //{
- // pSoldier->bShownAimTime = REFINE_AIM_1;
- //}
- //pSoldier->fPauseAim = TRUE;
- }
- // If in turn based - refresh aim to first level
- if ( gTacticalStatus.uiFlags & TURNBASED && (gTacticalStatus.uiFlags & INCOMBAT) )
- {
- pSoldier->bShownAimTime = REFINE_AIM_1;
- // Locate to soldier if he's about to shoot!
- if ( pSoldier->bTeam != gbPlayerNum )
- {
- ShowRadioLocator( pSoldier->ubID, SHOW_LOCATOR_NORMAL );
- }
- }
- }
- // OK, set UI
- SetUIBusy( pSoldier->ubID );
- }
- else
- {
- return( ITEM_HANDLE_NOAPS );
- }
- return( ITEM_HANDLE_OK );
- }
- //TRY PUNCHING
- if ( Item[ usHandItem ].usItemClass == IC_PUNCH )
- {
- INT16 sCnt;
- INT16 sSpot;
- UINT8 ubGuyThere;
- INT16 sGotLocation = NOWHERE;
- BOOLEAN fGotAdjacent = FALSE;
- for ( sCnt = 0; sCnt < NUM_WORLD_DIRECTIONS; sCnt++ )
- {
- sSpot = NewGridNo( pSoldier->sGridNo, DirectionInc( sCnt ) );
- // Make sure movement costs are OK....
- if ( gubWorldMovementCosts[ sSpot ][ sCnt ][ bLevel ] >= TRAVELCOST_BLOCKED )
- {
- continue;
- }
- // Check for who is there...
- ubGuyThere = WhoIsThere2( sSpot, pSoldier->bLevel );
- if ( pTargetSoldier != NULL && ubGuyThere == pTargetSoldier->ubID )
- {
- // We've got a guy here....
- // Who is the one we want......
- sGotLocation = sSpot;
- sAdjustedGridNo = pTargetSoldier->sGridNo;
- ubDirection = ( UINT8 )sCnt;
- break;
- }
- }
- if ( sGotLocation == NOWHERE )
- {
- // See if we can get there to punch
- sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE );
- if ( sActionGridNo != -1 )
- {
- // OK, we've got somebody...
- sGotLocation = sActionGridNo;
- fGotAdjacent = TRUE;
- }
- }
-
- // Did we get a loaction?
- if ( sGotLocation != NOWHERE )
- {
- pSoldier->sTargetGridNo = usGridNo;
- pSoldier->usActionData = usGridNo;
- // CHECK IF WE ARE AT THIS GRIDNO NOW
- if ( pSoldier->sGridNo != sGotLocation && fGotAdjacent )
- {
- // SEND PENDING ACTION
- pSoldier->ubPendingAction = MERC_PUNCH;
- pSoldier->sPendingActionData2 = sAdjustedGridNo;
- pSoldier->bPendingActionData3 = ubDirection;
- pSoldier->ubPendingActionAnimCount = 0;
- // WALK UP TO DEST FIRST
- EVENT_InternalGetNewSoldierPath( pSoldier, sGotLocation, pSoldier->usUIMovementMode, FALSE, TRUE );
- }
- else
- {
- pSoldier->bAction = AI_ACTION_KNIFE_STAB;
- EVENT_SoldierBeginPunchAttack( pSoldier, sAdjustedGridNo, ubDirection );
- }
- // OK, set UI
- SetUIBusy( pSoldier->ubID );
- gfResetUIMovementOptimization = TRUE;
- return( ITEM_HANDLE_OK );
- }
- else
- {
- return( ITEM_HANDLE_CANNOT_GETTO_LOCATION );
- }
- }
- //USING THE MEDKIT
- if ( Item[ usHandItem ].usItemClass == IC_MEDKIT )
- {
- // ATE: AI CANNOT GO THROUGH HERE!
- UINT16 usMapPos;
- BOOLEAN fHadToUseCursorPos = FALSE;
- if (gTacticalStatus.fAutoBandageMode)
- {
- usMapPos = usGridNo;
- }
- else
- {
- GetMouseMapPos( &usMapPos );
- }
- // See if we can get there to stab
- sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE );
- if ( sActionGridNo == -1 )
- {
- // Try another location...
- sActionGridNo = FindAdjacentGridEx( pSoldier, usMapPos, &ubDirection, &sAdjustedGridNo, TRUE, FALSE );
- if ( sActionGridNo == -1 )
- {
- return( ITEM_HANDLE_CANNOT_GETTO_LOCATION );
- }
- if ( !gTacticalStatus.fAutoBandageMode )
- {
- fHadToUseCursorPos = TRUE;
- }
- }
- // Calculate AP costs...
- sAPCost = GetAPsToBeginFirstAid( pSoldier );
- sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints);
- if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) )
- {
- // OK, set UI
- SetUIBusy( pSoldier->ubID );
- // CHECK IF WE ARE AT THIS GRIDNO NOW
- if ( pSoldier->sGridNo != sActionGridNo )
- {
- // SEND PENDING ACTION
- pSoldier->ubPendingAction = MERC_GIVEAID;
- if ( fHadToUseCursorPos )
- {
- pSoldier->sPendingActionData2 = usMapPos;
- }
- else
- {
- if ( pTargetSoldier != NULL )
- {
- pSoldier->sPendingActionData2 = pTargetSoldier->sGridNo;
- }
- else
- {
- pSoldier->sPendingActionData2 = usGridNo;
- }
- }
- pSoldier->bPendingActionData3 = ubDirection;
- pSoldier->ubPendingActionAnimCount = 0;
- // WALK UP TO DEST FIRST
- EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE );
- }
- else
- {
- EVENT_SoldierBeginFirstAid( pSoldier, sAdjustedGridNo, ubDirection );
- }
- if ( fFromUI )
- {
- guiPendingOverrideEvent = A_CHANGE_TO_MOVE;
- }
- return( ITEM_HANDLE_OK );
- }
- else
- {
- return( ITEM_HANDLE_NOAPS );
- }
- }
- if ( usHandItem == WIRECUTTERS )
- {
- // See if we can get there to stab
- sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE );
- if ( sActionGridNo != -1 )
- {
- // Calculate AP costs...
- sAPCost = GetAPsToCutFence( pSoldier );
- sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints);
- if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) )
- {
- // CHECK IF WE ARE AT THIS GRIDNO NOW
- if ( pSoldier->sGridNo != sActionGridNo )
- {
- // SEND PENDING ACTION
- pSoldier->ubPendingAction = MERC_CUTFFENCE;
- pSoldier->sPendingActionData2 = sAdjustedGridNo;
- pSoldier->bPendingActionData3 = ubDirection;
- pSoldier->ubPendingActionAnimCount = 0;
- // WALK UP TO DEST FIRST
- EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode , FALSE, TRUE );
- }
- else
- {
- EVENT_SoldierBeginCutFence( pSoldier, sAdjustedGridNo, ubDirection );
- }
- // OK, set UI
- SetUIBusy( pSoldier->ubID );
- if ( fFromUI )
- {
- guiPendingOverrideEvent = A_CHANGE_TO_MOVE;
- }
- return( ITEM_HANDLE_OK );
- }
- else
- {
- return( ITEM_HANDLE_NOAPS );
- }
- }
- else
- {
- return( ITEM_HANDLE_CANNOT_GETTO_LOCATION );
- }
- }
- if ( usHandItem == TOOLKIT )
- {
- UINT8 ubMercID;
- BOOLEAN fVehicle = FALSE;
- INT16 sVehicleGridNo=-1;
- // For repair, check if we are over a vehicle, then get gridnot to edge of that vehicle!
- if ( IsRepairableStructAtGridNo( usGridNo, &ubMercID ) == 2 )
- {
- INT16 sNewGridNo;
- UINT8 ubDirection;
- sNewGridNo = FindGridNoFromSweetSpotWithStructDataFromSoldier( pSoldier, pSoldier->usUIMovementMode, 5, &ubDirection, 0, MercPtrs[ ubMercID ] );
- if ( sNewGridNo != NOWHERE )
- {
- usGridNo = sNewGridNo;
- sVehicleGridNo = MercPtrs[ ubMercID ]->sGridNo;
- fVehicle = TRUE;
- }
- }
- // See if we can get there to stab
- sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE );
- if ( sActionGridNo != -1 )
- {
- // Calculate AP costs...
- sAPCost = GetAPsToBeginRepair( pSoldier );
- sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints);
- if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) )
- {
- // CHECK IF WE ARE AT THIS GRIDNO NOW
- if ( pSoldier->sGridNo != sActionGridNo )
- {
- // SEND PENDING ACTION
- pSoldier->ubPendingAction = MERC_REPAIR;
- pSoldier->sPendingActionData2 = sAdjustedGridNo;
- if ( fVehicle )
- {
- pSoldier->sPendingActionData2 = sVehicleGridNo;
- }
- pSoldier->bPendingActionData3 = ubDirection;
- pSoldier->ubPendingActionAnimCount = 0;
- // WALK UP TO DEST FIRST
- EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE );
- }
- else
- {
- EVENT_SoldierBeginRepair( pSoldier, sAdjustedGridNo, ubDirection );
- }
- // OK, set UI
- SetUIBusy( pSoldier->ubID );
- if ( fFromUI )
- {
- guiPendingOverrideEvent = A_CHANGE_TO_MOVE;
- }
- return( ITEM_HANDLE_OK );
- }
- else
- {
- return( ITEM_HANDLE_NOAPS );
- }
- }
- else
- {
- return( ITEM_HANDLE_CANNOT_GETTO_LOCATION );
- }
- }
- if ( usHandItem == GAS_CAN )
- {
- UINT8 ubMercID;
- INT16 sVehicleGridNo=-1;
- // For repair, check if we are over a vehicle, then get gridnot to edge of that vehicle!
- if ( IsRefuelableStructAtGridNo( usGridNo, &ubMercID ) )
- {
- INT16 sNewGridNo;
- UINT8 ubDirection;
- sNewGridNo = FindGridNoFromSweetSpotWithStructDataFromSoldier( pSoldier, pSoldier->usUIMovementMode, 5, &ubDirection, 0, MercPtrs[ ubMercID ] );
- if ( sNewGridNo != NOWHERE )
- {
- usGridNo = sNewGridNo;
- sVehicleGridNo = MercPtrs[ ubMercID ]->sGridNo;
- }
- }
- // See if we can get there to stab
- sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE );
- if ( sActionGridNo != -1 )
- {
- // Calculate AP costs...
- sAPCost = GetAPsToRefuelVehicle( pSoldier );
- sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints);
- if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) )
- {
- // CHECK IF WE ARE AT THIS GRIDNO NOW
- if ( pSoldier->sGridNo != sActionGridNo )
- {
- // SEND PENDING ACTION
- pSoldier->ubPendingAction = MERC_FUEL_VEHICLE;
- pSoldier->sPendingActionData2 = sAdjustedGridNo;
- pSoldier->sPendingActionData2 = sVehicleGridNo;
- pSoldier->bPendingActionData3 = ubDirection;
- pSoldier->ubPendingActionAnimCount = 0;
- // WALK UP TO DEST FIRST
- EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE );
- }
- else
- {
- EVENT_SoldierBeginRefuel( pSoldier, sAdjustedGridNo, ubDirection );
- }
- // OK, set UI
- SetUIBusy( pSoldier->ubID );
- if ( fFromUI )
- {
- guiPendingOverrideEvent = A_CHANGE_TO_MOVE;
- }
- return( ITEM_HANDLE_OK );
- }
- else
- {
- return( ITEM_HANDLE_NOAPS );
- }
- }
- else
- {
- return( ITEM_HANDLE_CANNOT_GETTO_LOCATION );
- }
- }
- if ( usHandItem == JAR )
- {
- sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE );
- if ( sActionGridNo != -1 )
- {
- // Calculate AP costs...
- sAPCost = GetAPsToUseJar( pSoldier, sActionGridNo );
- sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints);
- if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) )
- {
- // CHECK IF WE ARE AT THIS GRIDNO NOW
- if ( pSoldier->sGridNo != sActionGridNo )
- {
- // SEND PENDING ACTION
- pSoldier->ubPendingAction = MERC_TAKEBLOOD;
- pSoldier->sPendingActionData2 = sAdjustedGridNo;
- pSoldier->bPendingActionData3 = ubDirection;
- pSoldier->ubPendingActionAnimCount = 0;
- // WALK UP TO DEST FIRST
- EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE );
- }
- else
- {
- EVENT_SoldierBeginTakeBlood( pSoldier, sAdjustedGridNo, ubDirection );
- }
- // OK, set UI
- SetUIBusy( pSoldier->ubID );
- if ( fFromUI )
- {
- guiPendingOverrideEvent = A_CHANGE_TO_MOVE;
- }
- return( ITEM_HANDLE_OK );
- }
- else
- {
- return( ITEM_HANDLE_NOAPS );
- }
- }
- else
- {
- return( ITEM_HANDLE_CANNOT_GETTO_LOCATION );
- }
- }
- if ( usHandItem == STRING_TIED_TO_TIN_CAN )
- {
- STRUCTURE *pStructure;
- LEVELNODE *pIntTile;
- // Get structure info for in tile!
- pIntTile = GetCurInteractiveTileGridNoAndStructure( &usGridNo, &pStructure );
- // We should not have null here if we are given this flag...
- if ( pIntTile != NULL )
- {
- sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, FALSE, TRUE );
- if ( sActionGridNo != -1 )
- {
- // Calculate AP costs...
- sAPCost = AP_ATTACH_CAN;
- sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints);
- if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) )
- {
- // CHECK IF WE ARE AT THIS GRIDNO NOW
- if ( pSoldier->sGridNo != sActionGridNo )
- {
- // SEND PENDING ACTION
- pSoldier->ubPendingAction = MERC_ATTACH_CAN;
- pSoldier->sPendingActionData2 = usGridNo;
- pSoldier->bPendingActionData3 = ubDirection;
- pSoldier->ubPendingActionAnimCount = 0;
- // WALK UP TO DEST FIRST
- EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE );
- }
- else
- {
- EVENT_SoldierBeginTakeBlood( pSoldier, usGridNo, ubDirection );
- }
- // OK, set UI
- SetUIBusy( pSoldier->ubID );
- if ( fFromUI )
- {
- guiPendingOverrideEvent = A_CHANGE_TO_MOVE;
- }
- return( ITEM_HANDLE_OK );
- }
- else
- {
- return( ITEM_HANDLE_NOAPS );
- }
- }
- else
- {
- return( ITEM_HANDLE_CANNOT_GETTO_LOCATION );
- }
- }
- else
- {
- return( ITEM_HANDLE_CANNOT_GETTO_LOCATION );
- }
- }
- // Check for remote detonator cursor....
- if ( Item[ usHandItem ].ubCursor == REMOTECURS )
- {
- sAPCost = AP_USE_REMOTE;
- if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) )
- {
- DeductPoints( pSoldier, sAPCost, 0 );
- if ( usHandItem == XRAY_DEVICE )
- {
- PlayJA2Sample( USE_X_RAY_MACHINE, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
- ActivateXRayDevice( pSoldier );
- return( ITEM_HANDLE_OK );
- }
- else // detonator
- {
- // Save gridno....
- pSoldier->sPendingActionData2 = usGridNo;
- EVENT_SoldierBeginUseDetonator( pSoldier );
- if ( fFromUI )
- {
- guiPendingOverrideEvent = A_CHANGE_TO_MOVE;
- }
- // Now start anim....
- return( ITEM_HANDLE_OK );
- }
- }
- else
- {
- return( ITEM_HANDLE_NOAPS );
- }
- }
- // Check for mine.. anything without a detonator.....
- if ( Item[ usHandItem ].ubCursor == BOMBCURS )
- {
- fDropBomb = TRUE;
- }
- // Check for a bomb like a mine, that uses a pressure detonator
- if ( Item[ usHandItem ].ubCursor == INVALIDCURS )
- {
- // Found detonator...
- if ( FindAttachment( &(pSoldier->inv[ pSoldier->ubAttackingHand ] ), DETONATOR) != ITEM_NOT_FOUND || FindAttachment( &(pSoldier->inv[ pSoldier->ubAttackingHand ] ), REMDETONATOR ) != ITEM_NOT_FOUND )
- {
- fDropBomb = TRUE;
- }
- }
- if ( fDropBomb )
- {
- // Save gridno....
- pSoldier->sPendingActionData2 = usGridNo;
- if ( pSoldier->sGridNo != usGridNo )
- {
- // SEND PENDING ACTION
- pSoldier->ubPendingAction = MERC_DROPBOMB;
- pSoldier->ubPendingActionAnimCount = 0;
- // WALK UP TO DEST FIRST
- EVENT_InternalGetNewSoldierPath( pSoldier, usGridNo, pSoldier->usUIMovementMode, FALSE, TRUE );
- }
- else
- {
- EVENT_SoldierBeginDropBomb( pSoldier );
- }
- // OK, set UI
- SetUIBusy( pSoldier->ubID );
- if ( fFromUI )
- {
- guiPendingOverrideEvent = A_CHANGE_TO_MOVE;
- }
- return( ITEM_HANDLE_OK );
- }
-
- //USING THE BLADE
- if ( Item[ usHandItem ].usItemClass == IC_BLADE )
- {
- // See if we can get there to stab
- if ( pSoldier->ubBodyType == BLOODCAT )
- {
- sActionGridNo = FindNextToAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE );
- }
- else if ( CREATURE_OR_BLOODCAT( pSoldier ) && PythSpacesAway( pSoldier->sGridNo, usGridNo ) > 1 )
- {
- sActionGridNo = FindNextToAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE );
- if (sActionGridNo == -1)
- {
- sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE );
- }
- }
- else
- {
- sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE );
- }
-
- if ( sActionGridNo != -1 )
- {
- pSoldier->usActionData = sActionGridNo;
- // CHECK IF WE ARE AT THIS GRIDNO NOW
- if ( pSoldier->sGridNo != sActionGridNo )
- {
- // SEND PENDING ACTION
- pSoldier->ubPendingAction = MERC_KNIFEATTACK;
- pSoldier->sPendingActionData2 = sAdjustedGridNo;
- pSoldier->bPendingActionData3 = ubDirection;
- pSoldier->ubPendingActionAnimCount = 0;
- // WALK UP TO DEST FIRST
- EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE );
- }
- else
- {
- // for the benefit of the AI
- pSoldier->bAction = AI_ACTION_KNIFE_STAB;
- EVENT_SoldierBeginBladeAttack( pSoldier, sAdjustedGridNo, ubDirection );
- }
- // OK, set UI
- SetUIBusy( pSoldier->ubID );
- if ( fFromUI )
- {
- guiPendingOverrideEvent = A_CHANGE_TO_MOVE;
- gfResetUIMovementOptimization = TRUE;
- }
- return( ITEM_HANDLE_OK );
- }
- else
- {
- return( ITEM_HANDLE_CANNOT_GETTO_LOCATION );
- }
- }
- if ( Item[ usHandItem ].usItemClass == IC_TENTACLES )
- {
- // See if we can get there to stab
- //pSoldier->sTargetGridNo = sTargetGridNo;
- //pSoldier->sLastTarget = sTargetGridNo;
- //pSoldier->ubTargetID = WhoIsThere2( sTargetGridNo, pSoldier->bTargetLevel );
- gTacticalStatus.ubAttackBusyCount++;
- DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting swipe attack, incrementing a.b.c in HandleItems to %d", gTacticalStatus.ubAttackBusyCount) );
- sAPCost = CalcTotalAPsToAttack( pSoldier, sGridNo, FALSE, pSoldier->bAimTime );
- DeductPoints( pSoldier, sAPCost, 0 );
- EVENT_InitNewSoldierAnim( pSoldier, QUEEN_SWIPE, 0 , FALSE );
- //FireWeapon( pSoldier, sTargetGridNo );
- pSoldier->bAction = AI_ACTION_KNIFE_STAB;
- return( ITEM_HANDLE_OK );
- }
- // THIS IS IF WE WERE FROM THE UI
- if ( Item[ usHandItem ].usItemClass == IC_GRENADE || Item[ usHandItem ].usItemClass == IC_LAUNCHER || Item[ usHandItem ].usItemClass == IC_THROWN )
- {
- INT16 sCheckGridNo;
- // Get gridno - either soldier's position or the gridno
- if ( pTargetSoldier != NULL )
- {
- sTargetGridNo = pTargetSoldier->sGridNo;
- }
- else
- {
- sTargetGridNo = usGridNo;
- }
- sAPCost = MinAPsToAttack( pSoldier, sTargetGridNo, TRUE );
- // Check if these is room to place mortar!
- if ( usHandItem == MORTAR )
- {
- ubDirection = (UINT8)GetDirectionFromGridNo( sTargetGridNo, pSoldier );
- // Get new gridno!
- sCheckGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)DirectionInc( ubDirection ) );
- if ( !OKFallDirection( pSoldier, sCheckGridNo, pSoldier->bLevel, ubDirection , pSoldier->usAnimState ) )
- {
- return( ITEM_HANDLE_NOROOM );
- }
- pSoldier->fDontChargeAPsForStanceChange = TRUE;
- }
- else if ( usHandItem == GLAUNCHER || usHandItem == UNDER_GLAUNCHER )
- {
- GetAPChargeForShootOrStabWRTGunRaises( pSoldier, sTargetGridNo, TRUE, &fAddingTurningCost, &fAddingRaiseGunCost );
- // If we are standing and are asked to turn AND raise gun, ignore raise gun...
- if ( gAnimControl[ pSoldier->usAnimState ].ubHeight == ANIM_STAND )
- {
- if ( fAddingRaiseGunCost )
- {
- pSoldier->fDontChargeTurningAPs = TRUE;
- }
- }
- else
- {
- // If raising gun, don't charge turning!
- if ( fAddingTurningCost )
- {
- pSoldier->fDontChargeReadyAPs = TRUE;
- }
- }
- }
- // If this is a player guy, show message about no APS
- if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) )
- {
- pSoldier->ubAttackingHand = HANDPOS;
- pSoldier->usAttackingWeapon = usHandItem;
- pSoldier->bTargetLevel = bLevel;
- // Look at the cursor, if toss cursor...
- if ( Item[ usHandItem ].ubCursor == TOSSCURS )
- {
- pSoldier->sTargetGridNo = sTargetGridNo;
- // pSoldier->sLastTarget = sTargetGridNo;
- pSoldier->ubTargetID = WhoIsThere2( sTargetGridNo, pSoldier->bTargetLevel );
- // Increment attack counter...
- gTacticalStatus.ubAttackBusyCount++;
- // ATE: Don't charge turning...
- pSoldier->fDontChargeTurningAPs = TRUE;
- FireWeapon( pSoldier, sTargetGridNo );
- }
- else
- {
- SendBeginFireWeaponEvent( pSoldier, sTargetGridNo );
- }
- // OK, set UI
- SetUIBusy( pSoldier->ubID );
- return( ITEM_HANDLE_OK );
- }
- else
- {
- return( ITEM_HANDLE_NOAPS );
- }
- return( ITEM_HANDLE_OK );
- }
- // CHECK FOR BOMB....
- if ( Item[ usHandItem ].ubCursor == INVALIDCURS )
- {
- // Found detonator...
- if ( FindAttachment( &(pSoldier->inv[ usHandItem ] ), DETONATOR) != ITEM_NOT_FOUND || FindAttachment( &(pSoldier->inv[ usHandItem ] ), REMDETONATOR ) )
- {
- StartBombMessageBox( pSoldier, usGridNo );
- if ( fFromUI )
- {
- guiPendingOverrideEvent = A_CHANGE_TO_MOVE;
- }
- return( ITEM_HANDLE_OK );
- }
- }
- return( ITEM_HANDLE_OK );
- }
- void HandleSoldierDropBomb( SOLDIERTYPE *pSoldier, INT16 sGridNo )
- {
- // Does this have detonator that needs info?
- if ( FindAttachment( &(pSoldier->inv[ HANDPOS ] ), DETONATOR) != ITEM_NOT_FOUND || FindAttachment( &(pSoldier->inv[ HANDPOS ] ), REMDETONATOR ) != ITEM_NOT_FOUND )
- {
- StartBombMessageBox( pSoldier, sGridNo );
- }
- else
- {
- // We have something... all we do is place...
- if ( ArmBomb( &(pSoldier->inv[ HANDPOS ]), 0 ) )
- {
- // EXPLOSIVES GAIN (25): Place a bomb, or buried and armed a mine
- StatChange( pSoldier, EXPLODEAMT, 25, FALSE );
- pSoldier->inv[ HANDPOS ].bTrap = __min( 10, ( EffectiveExplosive( pSoldier ) / 20) + (EffectiveExpLevel( pSoldier ) / 3) );
- pSoldier->inv[ HANDPOS ].ubBombOwner = pSoldier->ubID + 2;
- // we now know there is something nasty here
- gpWorldLevelData[ sGridNo ].uiFlags |= MAPELEMENT_PLAYER_MINE_PRESENT;
- AddItemToPool( sGridNo, &(pSoldier->inv[ HANDPOS ] ), BURIED, pSoldier->bLevel, WORLD_ITEM_ARMED_BOMB, 0 );
- DeleteObj( &(pSoldier->inv[ HANDPOS ]) );
- }
- }
- }
- void HandleSoldierUseRemote( SOLDIERTYPE *pSoldier, INT16 sGridNo )
- {
- StartBombMessageBox( pSoldier, sGridNo );
- }
- void SoldierHandleDropItem( SOLDIERTYPE *pSoldier )
- {
- // LOOK IN PANDING DATA FOR ITEM TO DROP, AND LOCATION
- if ( pSoldier->pTempObject != NULL )
- {
- if ( pSoldier->bVisible != -1 )
- {
- PlayJA2Sample( THROW_IMPACT_2, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
- }
- AddItemToPool( pSoldier->sGridNo, pSoldier->pTempObject, 1, pSoldier->bLevel, 0 , -1 );
- NotifySoldiersToLookforItems( );
- MemFree( pSoldier->pTempObject );
- pSoldier->pTempObject = NULL;
- }
- }
- void HandleSoldierThrowItem( SOLDIERTYPE *pSoldier, INT16 sGridNo )
- {
- // Determine what to do
- UINT8 ubDirection;
- // Set attacker to NOBODY, since it's not a combat attack
- pSoldier->ubTargetID = NOBODY;
- // Alrighty, switch based on stance!
- switch( gAnimControl[ pSoldier->usAnimState ].ubHeight )
- {
- case ANIM_STAND:
- // CHECK IF WE ARE NOT ON THE SAME GRIDNO
- if ( sGridNo == pSoldier->sGridNo )
- {
- PickDropItemAnimation( pSoldier );
- }
- else
- {
- // CHANGE DIRECTION AT LEAST
- ubDirection = (UINT8)GetDirectionFromGridNo( sGridNo, pSoldier );
- SoldierGotoStationaryStance( pSoldier );
- EVENT_SetSoldierDesiredDirection( pSoldier, ubDirection );
- pSoldier->fTurningUntilDone = TRUE;
- // Draw item depending on distance from buddy
- if ( GetRangeFromGridNoDiff( sGridNo, pSoldier->sGridNo ) < MIN_LOB_RANGE )
- {
- pSoldier->usPendingAnimation = LOB_ITEM;
- }
- else
- {
- pSoldier->usPendingAnimation = THROW_ITEM;
- }
- }
- break;
- case ANIM_CROUCH:
- case ANIM_PRONE:
- // CHECK IF WE ARE NOT ON THE SAME GRIDNO
- if ( sGridNo == pSoldier->sGridNo )
- {
- // OK, JUST DROP ITEM!
- if ( pSoldier->pTempObject != NULL )
- {
- AddItemToPool( sGridNo, pSoldier->pTempObject, 1, pSoldier->bLevel, 0, -1 );
- NotifySoldiersToLookforItems( );
- MemFree( pSoldier->pTempObject );
- pSoldier->pTempObject = NULL;
- }
- }
- else
- {
- // OK, go from prone/crouch to stand first!
- ubDirection = (UINT8)GetDirectionFromGridNo( sGridNo, pSoldier );
- EVENT_SetSoldierDesiredDirection( pSoldier, ubDirection );
- ChangeSoldierState( pSoldier, THROW_ITEM, 0 , FALSE );
- }
- }
- }
- void SoldierGiveItem( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pTargetSoldier, OBJECTTYPE *pObject, INT8 bInvPos )
- {
- INT16 sActionGridNo, sAdjustedGridNo;
- UINT8 ubDirection;
- // Remove any previous actions
- pSoldier->ubPendingAction = NO_PENDING_ACTION;
- // See if we can get there to stab
- sActionGridNo = FindAdjacentGridEx( pSoldier, pTargetSoldier->sGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE );
- if ( sActionGridNo != -1 )
- {
- // SEND PENDING ACTION
- pSoldier->ubPendingAction = MERC_GIVEITEM;
- pSoldier->bPendingActionData5 = bInvPos;
- // Copy temp object
- pSoldier->pTempObject = MemAlloc( sizeof( OBJECTTYPE ) );
- memcpy( pSoldier->pTempObject, pObject, sizeof( OBJECTTYPE ) );
- pSoldier->sPendingActionData2 = pTargetSoldier->sGridNo;
- pSoldier->bPendingActionData3 = ubDirection;
- pSoldier->uiPendingActionData4 = pTargetSoldier->ubID;
- pSoldier->ubPendingActionAnimCount = 0;
- // Set soldier as engaged!
- pSoldier->uiStatusFlags |= SOLDIER_ENGAGEDINACTION;
- // CHECK IF WE ARE AT THIS GRIDNO NOW
- if ( pSoldier->sGridNo != sActionGridNo )
- {
- // WALK UP TO DEST FIRST
- EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE );
- }
- else
- {
- EVENT_SoldierBeginGiveItem( pSoldier );
- // CHANGE DIRECTION OF TARGET TO OPPOSIDE DIRECTION!
- EVENT_SetSoldierDesiredDirection( pSoldier, ubDirection );
- }
- // Set target as engaged!
- pTargetSoldier->uiStatusFlags |= SOLDIER_ENGAGEDINACTION;
- return;
- }
- else
- {
- return;
- }
- }
- BOOLEAN SoldierDropItem( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj )
- {
- pSoldier->pTempObject = MemAlloc( sizeof( OBJECTTYPE ) );
- if (pSoldier->pTempObject == NULL)
- {
- // OUT OF MEMORY! YIKES!
- return( FALSE );
- }
- memcpy( pSoldier->pTempObject, pObj, sizeof( OBJECTTYPE ) );
- PickDropItemAnimation( pSoldier );
- return( TRUE );
- }
- void SoldierPickupItem( SOLDIERTYPE *pSoldier, INT32 iItemIndex, INT16 sGridNo, INT8 bZLevel )
- {
- INT16 sActionGridNo;
- // Remove any previous actions
- pSoldier->ubPendingAction = NO_PENDING_ACTION;
- sActionGridNo = AdjustGridNoForItemPlacement( pSoldier, sGridNo );
- // SET PENDING ACTIONS!
- pSoldier->ubPendingAction = MERC_PICKUPITEM;
- pSoldier->uiPendingActionData1 = iItemIndex;
- pSoldier->sPendingActionData2 = sActionGridNo;
- pSoldier->uiPendingActionData4 = sGridNo;
- pSoldier->bPendingActionData3 = bZLevel;
- pSoldier->ubPendingActionAnimCount = 0;
- // Deduct points!
- //sAPCost = GetAPsToPickupItem( pSoldier, sGridNo );
- //DeductPoints( pSoldier, sAPCost, 0 );
- SetUIBusy( pSoldier->ubID );
- // CHECK IF NOT AT SAME GRIDNO
- if ( pSoldier->sGridNo != sActionGridNo )
- {
- if ( pSoldier->bTeam == gbPlayerNum )
- {
- EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, TRUE, TRUE );
- // Say it only if we don;t have to go too far!
- if ( pSoldier->usPathDataSize > 5 )
- {
- DoMercBattleSound( pSoldier, BATTLE_SOUND_OK1 );
- }
- }
- else
- {
- EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE );
- }
- }
- else
- {
- // DO ANIMATION OF PICKUP NOW!
- PickPickupAnimation( pSoldier, pSoldier->uiPendingActionData1, (INT16)( pSoldier->uiPendingActionData4 ), pSoldier->bPendingActionData3 );
- }
- }
- void HandleAutoPlaceFail( SOLDIERTYPE *pSoldier, INT32 iItemIndex, INT16 sGridNo )
- {
- if (pSoldier->bTeam == gbPlayerNum)
- {
- // Place it in buddy's hand!
- if ( gpItemPointer == NULL )
- {
- InternalBeginItemPointer( pSoldier, &(gWorldItems[ iItemIndex ].o ), NO_SLOT );
- }
- else
- {
- // Add back to world...
- AddItemToPool( sGridNo, &(gWorldItems[ iItemIndex ].o ), 1 , pSoldier->bLevel, 0, -1 );
- // If we are a merc, say DAMN quote....
- if ( pSoldier->bTeam == gbPlayerNum )
- {
- DoMercBattleSound( pSoldier, BATTLE_SOUND_CURSE1 );
- }
- }
- }
- }
- void SoldierGetItemFromWorld( SOLDIERTYPE *pSoldier, INT32 iItemIndex, INT16 sGridNo, INT8 bZLevel, BOOLEAN *pfSelectionList )
- {
- ITEM_POOL * pItemPool;
- ITEM_POOL * pItemPoolToDelete = NULL;
- OBJECTTYPE Object;
- INT32 cnt = 0;
- BOOLEAN fPickup;
- BOOLEAN fFailedAutoPlace = FALSE;
- INT32 iItemIndexToDelete;
- BOOLEAN fShouldSayCoolQuote = FALSE;
- BOOLEAN fDidSayCoolQuote = FALSE;
- BOOLEAN fSaidBoobyTrapQuote = FALSE;
- // OK. CHECK IF WE ARE DOING ALL IN THIS POOL....
- if ( iItemIndex == ITEM_PICKUP_ACTION_ALL || iItemIndex == ITEM_PICKUP_SELECTION )
- {
- // DO all pickup!
- // LOOP THROUGH LIST TO FIND NODE WE WANT
- GetItemPool( sGridNo, &pItemPool, pSoldier->bLevel );
- while( pItemPool )
- {
- if ( ItemPoolOKForPickup( pSoldier, pItemPool, bZLevel ) )
- {
- fPickup = TRUE;
- if ( iItemIndex == ITEM_PICKUP_SELECTION )
- {
- if ( !pfSelectionList[ cnt ] )
- {
- fPickup = FALSE;
- }
- }
-
- // Increment counter...
- //:ATE: Only incremrnt counter for items we can see..
- cnt++;
- if ( fPickup )
- {
- if ( ContinuePastBoobyTrap( pSoldier, sGridNo, bZLevel, pItemPool->iItemIndex, FALSE, &fSaidBoobyTrapQuote ) )
- {
- // Make copy of item
- memcpy( &Object, &(gWorldItems[ pItemPool->iItemIndex ].o), sizeof( OBJECTTYPE ) );
- if ( ItemIsCool( &Object ) )
- {
- fShouldSayCoolQuote = TRUE;
- }
- if (Object.usItem == SWITCH)
- {
- // ask about activating the switch!
- bTempFrequency = Object.bFrequency;
- gpTempSoldier = pSoldier;
- DoMessageBox( MSG_BOX_BASIC_STYLE, TacticalStr[ ACTIVATE_SWITCH_PROMPT ] , GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, SwitchMessageBoxCallBack, NULL );
- pItemPool = pItemPool->pNext;
- }
- else
- {
- if ( !AutoPlaceObject( pSoldier, &Object, TRUE ) )
- {
- // check to see if the object has been swapped with one in inventory
- if ( Object.usItem != gWorldItems[ pItemPool->iItemIndex ].o.usItem || Object.ubNumberOfObjects != gWorldItems[ pItemPool->iItemIndex ].o.ubNumberOfObjects )
- {
- // copy back because item changed, and we must make sure the item pool reflects this.
- memcpy( &(gWorldItems[ pItemPool->iItemIndex ].o), &Object, sizeof( OBJECTTYPE ) );
- }
- pItemPoolToDelete = pItemPool;
- pItemPool = pItemPool->pNext;
- fFailedAutoPlace = TRUE;
- // continue, to try and place ay others...
- continue;
- }
- /*
- // handle theft.. will return true if theft has failed ( if soldier was caught )
- if( pSoldier->bTeam == OUR_TEAM )
- {
- // check to see if object was owned by another
- if( Object.fFlags & OBJECT_OWNED_BY_CIVILIAN )
- {
- // owned by a civilian
- if( HandleLoyaltyAdjustmentForRobbery( pSoldier ) == TRUE )
- {
- // implememnt actual tactical reaction for theft..shoot robber, yell out, etc
- }
- // reset who owns object
- Object.fFlags &= ~( OBJECT_OWNED_BY_CIVILIAN );
- }
- }
- */
- //pItemPoolToDelete = pItemPool;
- iItemIndexToDelete = pItemPool->iItemIndex;
- pItemPool = pItemPool->pNext;
- RemoveItemFromPool( sGridNo, iItemIndexToDelete, pSoldier->bLevel );
- }
- }
- else
- {
- // boobytrap found... stop picking up things!
- break;
- }
- }
- else
- {
- pItemPool = pItemPool->pNext;
- }
- }
- else
- {
- pItemPool = pItemPool->pNext;
- }
- }
- // ATE; If here, and we failed to add any more stuff, put failed one in our cursor...
- if ( pItemPoolToDelete != NULL && fFailedAutoPlace )
- {
- gfDontChargeAPsToPickup = TRUE;
- HandleAutoPlaceFail( pSoldier, pItemPoolToDelete->iItemIndex, sGridNo );
- RemoveItemFromPool( sGridNo, pItemPoolToDelete->iItemIndex, pSoldier->bLevel );
- pItemPoolToDelete = NULL;
- }
- }
- else
- {
- // REMOVE ITEM FROM POOL
- if ( ItemExistsAtLocation( sGridNo, iItemIndex, pSoldier->bLevel ) )
- {
- if ( ContinuePastBoobyTrap( pSoldier, sGridNo, bZLevel, iItemIndex, FALSE, &fSaidBoobyTrapQuote ) )
- {
- // Make copy of item
- memcpy( &Object, &(gWorldItems[ iItemIndex ].o), sizeof( OBJECTTYPE ) );
- if ( ItemIsCool( &Object ) )
- {
- fShouldSayCoolQuote = TRUE;
- }
- if (Object.usItem == SWITCH)
- {
- // handle switch
- bTempFrequency = Object.bFrequency;
- gpTempSoldier = pSoldier;
- DoMessageBox( MSG_BOX_BASIC_STYLE, TacticalStr[ ACTIVATE_SWITCH_PROMPT ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, SwitchMessageBoxCallBack, NULL );
- }
- else
- {
- /*
- // handle theft.. will return true if theft has failed ( if soldier was caught )
- if( pSoldier->bTeam == OUR_TEAM )
- {
- // check to see if object was owned by another
- if( Object.fFlags & OBJECT_OWNED_BY_CIVILIAN )
- {
- // owned by a civilian
- if( HandleLoyaltyAdjustmentForRobbery( pSoldier ) == TRUE )
- {
- // implememnt actual tactical reaction for theft..shoot robber, yell out, etc
- }
- // reset who owns object
- Object.fFlags &= ~( OBJECT_OWNED_BY_CIVILIAN );
- }
- }
- */
- RemoveItemFromPool( sGridNo, iItemIndex, pSoldier->bLevel );
- if ( !AutoPlaceObject( pSoldier, &(gWorldItems[ iItemIndex ].o ), TRUE ) )
- {
- gfDontChargeAPsToPickup = TRUE;
- HandleAutoPlaceFail( pSoldier, iItemIndex, sGridNo );
- }
- }
- }
- }
- }
- // OK, check if potentially a good candidate for cool quote
- if ( fShouldSayCoolQuote && pSoldier->bTeam == gbPlayerNum )
- {
- // Do we have this quote..?
- if ( QuoteExp_GotGunOrUsedGun[ pSoldier->ubProfile ] == QUOTE_FOUND_SOMETHING_SPECIAL )
- {
- // Have we not said it today?
- if ( !( pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_FOUND_SOMETHING_NICE ) )
- {
- // set flag
- pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_FOUND_SOMETHING_NICE;
- // Say it....
- // We've found something!
- TacticalCharacterDialogue( pSoldier, QUOTE_FOUND_SOMETHING_SPECIAL );
- fDidSayCoolQuote = TRUE;
- }
- }
- }
- // Aknowledge....
- if( pSoldier->bTeam == OUR_TEAM && !fDidSayCoolQuote && !fSaidBoobyTrapQuote )
- {
- DoMercBattleSound( pSoldier, BATTLE_SOUND_GOTIT );
- }
- // OK partner......look for any hidden items!
- if ( pSoldier->bTeam == gbPlayerNum && LookForHiddenItems( sGridNo, pSoldier->bLevel, TRUE, 0 ) )
- {
- // WISDOM GAIN (5): Found a hidden object
- StatChange( pSoldier, WISDOMAMT, 5, FALSE );
- // We've found something!
- TacticalCharacterDialogue( pSoldier, (UINT16)( QUOTE_SPOTTED_SOMETHING_ONE + Random( 2 ) ) );
- }
- gpTempSoldier = pSoldier;
- gsTempGridno = sGridNo;
- SetCustomizableTimerCallbackAndDelay( 1000, CheckForPickedOwnership, TRUE );
- }
- void HandleSoldierPickupItem( SOLDIERTYPE *pSoldier, INT32 iItemIndex, INT16 sGridNo, INT8 bZLevel )
- {
- ITEM_POOL *pItemPool;
- UINT16 usNum;
- // Draw menu if more than one item!
- if ( GetItemPool( sGridNo, &pItemPool, pSoldier->bLevel ) )
- {
- // OK, if an enemy, go directly ( skip menu )
- if ( pSoldier->bTeam != gbPlayerNum )
- {
- SoldierGetItemFromWorld( pSoldier, iItemIndex, sGridNo, bZLevel, NULL );
- }
- else
- {
- if (gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_PLAYER_MINE_PRESENT)
- {
- // have the computer ask us if we want to proceed
- // override the item index passed in with the one for the bomb in this
- // tile
- iItemIndex = FindWorldItemForBombInGridNo( sGridNo, pSoldier->bLevel );
- #ifdef JA2TESTVERSION
- if (iItemIndex == -1)
- {
- // WTF????
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_ERROR, L"Cannot find bomb item in gridno %d", sGridNo );
- return;
- }
- #endif
- gpBoobyTrapItemPool = GetItemPoolForIndex( sGridNo, iItemIndex, pSoldier->bLevel );
- gpBoobyTrapSoldier = pSoldier;
- gsBoobyTrapGridNo = sGridNo;
- gbBoobyTrapLevel = pSoldier->bLevel;
- gfDisarmingBuriedBomb = TRUE;
- gbTrapDifficulty = gWorldItems[ iItemIndex ].o.bTrap;
- DoMessageBox( MSG_BOX_BASIC_STYLE, TacticalStr[ DISARM_TRAP_PROMPT ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, BoobyTrapMessageBoxCallBack, NULL );
- }
- else
- {
- // OK, only hidden items exist...
- if ( pSoldier->bTeam == gbPlayerNum && DoesItemPoolContainAllHiddenItems( pItemPool ) )
- {
- // He's touched them....
- if ( LookForHiddenItems( sGridNo, pSoldier->bLevel, TRUE, 0 ) )
- {
- // WISDOM GAIN (5): Found a hidden object
- StatChange( pSoldier, WISDOMAMT, 5, FALSE );
- // We've found something!
- TacticalCharacterDialogue( pSoldier, (UINT16)( QUOTE_SPOTTED_SOMETHING_ONE + Random( 2 ) ) );
- }
- else
- {
- // Say NOTHING quote...
- DoMercBattleSound( pSoldier, BATTLE_SOUND_NOTHING );
- }
- }
- else
- {
- // If only one good item exists....
- if ( ( usNum = GetNumOkForDisplayItemsInPool( pItemPool, bZLevel ) ) == 1 )
- {
- // Find first OK item....
- while( !ItemPoolOKForDisplay( pItemPool, bZLevel ) )
- {
- pItemPool = pItemPool->pNext;
- }
- SoldierGetItemFromWorld( pSoldier, pItemPool->iItemIndex, sGridNo, bZLevel, NULL );
- }
- else
- {
- if ( usNum != 0 )
- {
- // Freeze guy!
- pSoldier->fPauseAllAnimation = TRUE;
- InitializeItemPickupMenu( pSoldier, sGridNo, pItemPool, 0, 0, bZLevel );
- guiPendingOverrideEvent = G_GETTINGITEM;
- }
- else
- {
- DoMercBattleSound( pSoldier, BATTLE_SOUND_NOTHING );
- }
- }
- }
- }
- }
- }
- else
- {
- // Say NOTHING quote...
- DoMercBattleSound( pSoldier, BATTLE_SOUND_NOTHING );
- }
- }
- LEVELNODE *AddItemGraphicToWorld( INVTYPE *pItem, INT16 sGridNo, UINT8 ubLevel )
- {
- UINT16 usTileIndex;
- LEVELNODE *pNode;
- usTileIndex = GetTileGraphicForItem( pItem );
- // OK, Do stuff differently base on level!
- if ( ubLevel == 0 )
- {
- pNode = AddStructToTail( sGridNo, usTileIndex );
- //SET FLAG FOR AN ITEM
- pNode->uiFlags |= LEVELNODE_ITEM;
- }
- else
- {
- AddOnRoofToHead( sGridNo, usTileIndex );
- //SET FLAG FOR AN ITEM
- pNode = gpWorldLevelData[ sGridNo ].pOnRoofHead;
- pNode->uiFlags |= LEVELNODE_ITEM;
- }
- // DIRTY INTERFACE
- fInterfacePanelDirty = DIRTYLEVEL2;
- // DIRTY TILE
- gpWorldLevelData[ sGridNo ].uiFlags |= MAPELEMENT_REDRAW;
- SetRenderFlags(RENDER_FLAG_MARKED);
- return( pNode );
- }
- void RemoveItemGraphicFromWorld( INVTYPE *pItem, INT16 sGridNo, UINT8 ubLevel, LEVELNODE *pLevelNode )
- {
- LEVELNODE *pNode;
- // OK, Do stuff differently base on level!
- // Loop through and find pointer....
- if ( ubLevel == 0 )
- {
- pNode = gpWorldLevelData[ sGridNo ].pStructHead;
- }
- else
- {
- pNode = gpWorldLevelData[ sGridNo ].pOnRoofHead;
- }
- while( pNode != NULL )
- {
- if ( pNode == pLevelNode )
- {
- // Found one!
- if ( ubLevel == 0 )
- {
- RemoveStructFromLevelNode( sGridNo, pNode );
- }
- else
- {
- RemoveOnRoofFromLevelNode( sGridNo, pNode );
- }
- break;
- }
- pNode = pNode->pNext;
- }
- // DIRTY INTERFACE
- fInterfacePanelDirty = DIRTYLEVEL2;
- // DIRTY TILE
- gpWorldLevelData[ sGridNo ].uiFlags |= MAPELEMENT_REDRAW;
- SetRenderFlags(RENDER_FLAG_MARKED);
- //TEMP RENDER FULL!!!
- SetRenderFlags(RENDER_FLAG_FULL);
- }
- // INVENTORY POOL STUFF
- OBJECTTYPE* AddItemToPool( INT16 sGridNo, OBJECTTYPE *pObject, INT8 bVisible, UINT8 ubLevel, UINT16 usFlags, INT8 bRenderZHeightAboveLevel )
- {
- return InternalAddItemToPool( &sGridNo, pObject, bVisible, ubLevel, usFlags, bRenderZHeightAboveLevel, NULL );
- }
- OBJECTTYPE * AddItemToPoolAndGetIndex( INT16 sGridNo, OBJECTTYPE *pObject, INT8 bVisible, UINT8 ubLevel, UINT16 usFlags, INT8 bRenderZHeightAboveLevel, INT32 * piItemIndex )
- {
- return( InternalAddItemToPool( &sGridNo, pObject, bVisible, ubLevel, usFlags, bRenderZHeightAboveLevel, piItemIndex ) );
- }
- OBJECTTYPE* InternalAddItemToPool( INT16 *psGridNo, OBJECTTYPE *pObject, INT8 bVisible, UINT8 ubLevel, UINT16 usFlags, INT8 bRenderZHeightAboveLevel, INT32 * piItemIndex )
- {
- ITEM_POOL *pItemPool;
- ITEM_POOL *pItemPoolTemp;
- INT32 iWorldItem;
- STRUCTURE *pStructure, *pBase;
- INT16 sDesiredLevel;
- INT16 sNewGridNo = *psGridNo;
- LEVELNODE *pNode;
- BOOLEAN fForceOnGround = FALSE;
- BOOLEAN fObjectInOpenable = FALSE;
- INT8 bTerrainID;
- Assert( pObject->ubNumberOfObjects <= MAX_OBJECTS_PER_SLOT);
- // ATE: Check if the gridno is OK
- if ( (*psGridNo) == NOWHERE )
- {
- // Display warning.....
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Error: Item %d was given invalid grid location %d for item pool. Please Report.", pObject->usItem, (*psGridNo) );
- (*psGridNo) = sNewGridNo = gMapInformation.sCenterGridNo;
- //return( NULL );
- }
- // CHECK IF THIS ITEM IS IN DEEP WATER....
- // IF SO, CHECK IF IT SINKS...
- // IF SO, DONT'T ADD!
- bTerrainID = GetTerrainType( *psGridNo );
- if ( bTerrainID == DEEP_WATER || bTerrainID == LOW_WATER || bTerrainID == MED_WATER )
- {
- if ( Item[ pObject->usItem ].fFlags & ITEM_SINKS )
- {
- return( NULL );
- }
- }
- // First things first - look at where we are to place the items, and
- // set some flags appropriately
- // On a structure?
- //Locations on roofs without a roof is not possible, so
- //we convert the onroof intention to ground.
- if( ubLevel && !FlatRoofAboveGridNo( *psGridNo ) )
- {
- ubLevel = 0;
- }
- if ( bRenderZHeightAboveLevel == -1 )
- {
- fForceOnGround = TRUE;
- bRenderZHeightAboveLevel = 0;
- }
- // Check structure database
- if ( gpWorldLevelData[ *psGridNo ].pStructureHead && (pObject->usItem != OWNERSHIP) && (pObject->usItem != ACTION_ITEM) )
- {
- // Something is here, check obstruction in future
- sDesiredLevel = ubLevel ? STRUCTURE_ON_ROOF : STRUCTURE_ON_GROUND;
- pStructure = FindStructure( *psGridNo , STRUCTURE_BLOCKSMOVES );
- while( pStructure )
- {
- if( !(pStructure->fFlags &( STRUCTURE_PERSON | STRUCTURE_CORPSE ) ) && pStructure->sCubeOffset == sDesiredLevel )
- {
- // If we are going into a raised struct AND we have above level set to -1
- if ( StructureBottomLevel( pStructure ) != 1 && fForceOnGround )
- {
- break;
- }
- // Adjust the item's gridno to the base of struct.....
- pBase = FindBaseStructure( pStructure );
-
- // Get LEVELNODE for struct and remove!
- sNewGridNo = pBase->sGridNo;
-
- // Check for openable flag....
- if ( pStructure->fFlags & STRUCTURE_OPENABLE )
- {
- // ATE: Set a flag here - we need to know later that we're in an openable...
- fObjectInOpenable = TRUE;
- // Something of note is here....
- // SOME sort of structure is here.... set render flag to off
- usFlags |= WORLD_ITEM_DONTRENDER;
- // Openable.. check if it's closed, if so, set visiblity...
- if ( !( pStructure->fFlags & STRUCTURE_OPEN ) )
- {
- // -2 means - don't reveal!
- bVisible = -2;
- }
- bRenderZHeightAboveLevel = CONVERT_INDEX_TO_PIXELS( StructureHeight( pStructure ) );
- break;
- }
- // Else can we place an item on top?
- else if ( pStructure->fFlags & ( STRUCTURE_GENERIC ) )
- {
- UINT8 ubLevel0, ubLevel1, ubLevel2, ubLevel3;
- // If we are going into a raised struct AND we have above level set to -1
- if ( StructureBottomLevel( pStructure ) != 1 && fForceOnGround )
- {
- break;
- }
- // Find most dence area...
- if ( StructureDensity( pStructure, &ubLevel0, &ubLevel1, &ubLevel2, &ubLevel3 ) )
- {
- if ( ubLevel3 == 0 && ubLevel2 == 0 && ubLevel1 == 0 && ubLevel0 == 0 )
- {
- bRenderZHeightAboveLevel = 0;
- }
- else if ( ubLevel3 >= ubLevel0 && ubLevel3 >= ubLevel2 && ubLevel3 >= ubLevel1 )
- {
- bRenderZHeightAboveLevel = CONVERT_INDEX_TO_PIXELS( 4 );
- }
- else if ( ubLevel2 >= ubLevel0 && ubLevel2 >= ubLevel1 && ubLevel2 >= ubLevel3 )
- {
- bRenderZHeightAboveLevel = CONVERT_INDEX_TO_PIXELS( 3 );
- }
- else if ( ubLevel1 >= ubLevel0 && ubLevel1 >= ubLevel2 && ubLevel1 >= ubLevel3 )
- {
- bRenderZHeightAboveLevel = CONVERT_INDEX_TO_PIXELS( 2 );
- }
- else if ( ubLevel0 >= ubLevel1 && ubLevel0 >= ubLevel2 && ubLevel0 >= ubLevel3 )
- {
- bRenderZHeightAboveLevel = CONVERT_INDEX_TO_PIXELS( 1 );
- }
- }
-
- // Set flag indicating it has an item on top!
- pStructure->fFlags |= STRUCTURE_HASITEMONTOP;
- break;
- }
- }
-
- pStructure = FindNextStructure( pStructure, STRUCTURE_BLOCKSMOVES );
- }
- }
- if (pObject->usItem == SWITCH && !fObjectInOpenable )
- {
- if (bVisible != -2)
- {
- // switch items which are not hidden inside objects should be considered buried
- bVisible = BURIED;
- // and they are pressure-triggered unless there is a switch structure there
- if (FindStructure( *psGridNo, STRUCTURE_SWITCH ) != NULL)
- {
- pObject->bDetonatorType = BOMB_SWITCH;
- }
- else
- {
- pObject->bDetonatorType = BOMB_PRESSURE;
- }
- }
- else
- {
- // else they are manually controlled
- pObject->bDetonatorType = BOMB_SWITCH;
- }
- }
- else if ( pObject->usItem == ACTION_ITEM )
- {
- switch( pObject->bActionValue )
- {
- case ACTION_ITEM_SMALL_PIT:
- case ACTION_ITEM_LARGE_PIT:
- // mark as known about by civs and creatures
- gpWorldLevelData[ sNewGridNo ].uiFlags |= MAPELEMENT_ENEMY_MINE_PRESENT;
- break;
- default:
- break;
- }
- }
- if ( *psGridNo != sNewGridNo )
- {
- *psGridNo = sNewGridNo;
- }
- //First add the item to the global list. This is so the game can keep track
- //of where the items are, for file i/o, etc.
- iWorldItem = AddItemToWorld( *psGridNo, pObject, ubLevel, usFlags, bRenderZHeightAboveLevel, bVisible );
- // Check for and existing pool on the object layer
- if ( GetItemPool( *psGridNo, &pItemPool, ubLevel ) )
- {
- // Add to exitsing pool
- // Add graphic
- pNode = AddItemGraphicToWorld( &(Item[ pObject->usItem ] ), *psGridNo, ubLevel );
- // Set pool head value in levelnode
- pNode->pItemPool = pItemPool;
- // Add New Node
- pItemPoolTemp = pItemPool;
- // Create new pool
- pItemPool = MemAlloc( sizeof( ITEM_POOL ) );
- // Set Next to NULL
- pItemPool->pNext = NULL;
- // Set Item index
- pItemPool->iItemIndex = iWorldItem;
- // Get a link back!
- pItemPool->pLevelNode = pNode;
- if( pItemPoolTemp )
- {
- // Get last item in list
- while( pItemPoolTemp->pNext != NULL )
- pItemPoolTemp = pItemPoolTemp->pNext;
- // Set Next of previous
- pItemPoolTemp->pNext = pItemPool;
- }
- // Set Previous of new one
- pItemPool->pPrev = pItemPoolTemp;
- }
- else
- {
- pNode = AddItemGraphicToWorld( &(Item[ pObject->usItem ] ), *psGridNo, ubLevel );
- // Create new pool
- pItemPool = MemAlloc( sizeof( ITEM_POOL ) );
- pNode->pItemPool = pItemPool;
- // Set prev to NULL
- pItemPool->pPrev = NULL;
- // Set next to NULL
- pItemPool->pNext = NULL;
- // Set Item index
- pItemPool->iItemIndex = iWorldItem;
- // Get a link back!
- pItemPool->pLevelNode = pNode;
- // Set flag to indicate item pool presence
- gpWorldLevelData[*psGridNo].uiFlags |= MAPELEMENT_ITEMPOOL_PRESENT;
- }
- // Set visible!
- pItemPool->bVisible = bVisible;
- // If bbisible is true, render makered world
- if ( bVisible == 1 && GridNoOnScreen( (*psGridNo ) ) )
- {
- //gpWorldLevelData[*psGridNo].uiFlags|=MAPELEMENT_REDRAW;
- //SetRenderFlags(RENDER_FLAG_MARKED);
- SetRenderFlags(RENDER_FLAG_FULL);
- }
- // Set flahs timer
- pItemPool->bFlashColor = FALSE;
- pItemPool->sGridNo = *psGridNo;
- pItemPool->ubLevel = ubLevel;
- pItemPool->usFlags = usFlags;
- pItemPool->bVisible = bVisible;
- pItemPool->bRenderZHeightAboveLevel = bRenderZHeightAboveLevel;
- // ATE: Get head of pool again....
- if ( GetItemPool( *psGridNo, &pItemPool, ubLevel ) )
- {
- AdjustItemPoolVisibility( pItemPool );
- }
- if (piItemIndex)
- {
- *piItemIndex = iWorldItem;
- }
-
- return( &(gWorldItems[ iWorldItem ].o ) );
- }
- BOOLEAN ItemExistsAtLocation( INT16 sGridNo, INT32 iItemIndex, UINT8 ubLevel )
- {
- ITEM_POOL *pItemPool;
- ITEM_POOL *pItemPoolTemp;
- BOOLEAN fItemFound = FALSE;
- // Check for an existing pool on the object layer
- if ( GetItemPool( sGridNo, &pItemPool, ubLevel ) )
- {
- // LOOP THROUGH LIST TO FIND NODE WE WANT
- pItemPoolTemp = pItemPool;
- while( pItemPoolTemp != NULL )
- {
- if ( pItemPoolTemp->iItemIndex == iItemIndex )
- {
- return( TRUE );
- }
- pItemPoolTemp = pItemPoolTemp->pNext;
- }
- }
- return( FALSE );
- }
- BOOLEAN ItemTypeExistsAtLocation( INT16 sGridNo, UINT16 usItem, UINT8 ubLevel, INT32 * piItemIndex )
- {
- ITEM_POOL *pItemPool;
- ITEM_POOL *pItemPoolTemp;
- BOOLEAN fItemFound = FALSE;
- // Check for an existing pool on the object layer
- if ( GetItemPool( sGridNo, &pItemPool, ubLevel ) )
- {
- // LOOP THROUGH LIST TO FIND ITEM WE WANT
- pItemPoolTemp = pItemPool;
- while( pItemPoolTemp != NULL )
- {
- if ( gWorldItems[ pItemPoolTemp->iItemIndex ].o.usItem == usItem )
- {
- if ( piItemIndex )
- {
- *piItemIndex = pItemPoolTemp->iItemIndex;
- }
- return( TRUE );
- }
- pItemPoolTemp = pItemPoolTemp->pNext;
- }
- }
- return( FALSE );
- }
- INT32 GetItemOfClassTypeInPool( INT16 sGridNo, UINT32 uiItemClass, UINT8 ubLevel )
- {
- ITEM_POOL *pItemPool;
- ITEM_POOL *pItemPoolTemp;
- BOOLEAN fItemFound = FALSE;
- // Check for an existing pool on the object layer
- if ( GetItemPool( sGridNo, &pItemPool, ubLevel ) )
- {
- // LOOP THROUGH LIST TO FIND NODE WE WANT
- pItemPoolTemp = pItemPool;
- while( pItemPoolTemp != NULL )
- {
- if ( Item[ gWorldItems[ pItemPoolTemp->iItemIndex ].o.usItem ].usItemClass & uiItemClass )
- {
- return( pItemPoolTemp->iItemIndex );
- }
- pItemPoolTemp = pItemPoolTemp->pNext;
- }
- }
- return( -1 );
- }
- ITEM_POOL * GetItemPoolForIndex( INT16 sGridNo, INT32 iItemIndex, UINT8 ubLevel )
- {
- ITEM_POOL *pItemPool;
- ITEM_POOL *pItemPoolTemp;
- BOOLEAN fItemFound = FALSE;
- // Check for an existing pool on the object layer
- if ( GetItemPool( sGridNo, &pItemPool, ubLevel ) )
- {
- // LOOP THROUGH LIST TO FIND NODE WE WANT
- pItemPoolTemp = pItemPool;
- while( pItemPoolTemp != NULL )
- {
- if (pItemPoolTemp->iItemIndex == iItemIndex )
- {
- return( pItemPoolTemp );
- }
- pItemPoolTemp = pItemPoolTemp->pNext;
- }
- }
- return( NULL );
- }
- BOOLEAN DoesItemPoolContainAnyHiddenItems( ITEM_POOL *pItemPool )
- {
- // LOOP THROUGH LIST TO FIND NODE WE WANT
- while( pItemPool != NULL )
- {
- if ( gWorldItems[ pItemPool->iItemIndex ].bVisible == HIDDEN_ITEM )
- {
- return( TRUE );
- }
- pItemPool = pItemPool->pNext;
- }
- return( FALSE );
- }
- BOOLEAN DoesItemPoolContainAllHiddenItems( ITEM_POOL *pItemPool )
- {
- // LOOP THROUGH LIST TO FIND NODE WE WANT
- while( pItemPool != NULL )
- {
- if ( gWorldItems[ pItemPool->iItemIndex ].bVisible != HIDDEN_ITEM )
- {
- return( FALSE );
- }
- pItemPool = pItemPool->pNext;
- }
- return( TRUE );
- }
- BOOLEAN LookForHiddenItems( INT16 sGridNo, INT8 ubLevel, BOOLEAN fSetLocator, INT8 bZLevel )
- {
- ITEM_POOL *pItemPool = NULL;
- ITEM_POOL *pHeadItemPool = NULL;
- BOOLEAN fFound = FALSE;
- if ( GetItemPool( sGridNo, &pItemPool, ubLevel ) )
- {
- pHeadItemPool = pItemPool;
- // LOOP THROUGH LIST TO FIND NODE WE WANT
- while( pItemPool != NULL )
- {
- if ( gWorldItems[ pItemPool->iItemIndex ].bVisible == HIDDEN_ITEM && gWorldItems[ pItemPool->iItemIndex ].o.usItem != OWNERSHIP )
- {
- fFound = TRUE;
-
- gWorldItems[ pItemPool->iItemIndex ].bVisible = INVISIBLE;
- }
- pItemPool = pItemPool->pNext;
- }
- }
- // If found, set item pool visibility...
- if ( fFound )
- {
- SetItemPoolVisibilityOn( pHeadItemPool, INVISIBLE, fSetLocator );
- }
- return( fFound );
- }
- INT8 GetZLevelOfItemPoolGivenStructure( INT16 sGridNo, UINT8 ubLevel, STRUCTURE *pStructure )
- {
- ITEM_POOL *pItemPool;
- if ( pStructure == NULL )
- {
- return( 0 );
- }
- // OK, check if this struct contains items....
- if ( GetItemPool( sGridNo, &pItemPool, ubLevel ) == TRUE )
- {
- return( GetLargestZLevelOfItemPool( pItemPool ) );
- }
- return( 0 );
- }
- INT8 GetLargestZLevelOfItemPool( ITEM_POOL *pItemPool )
- {
- // OK, loop through pools and get any height != 0........
- while( pItemPool != NULL )
- {
- if ( pItemPool->bRenderZHeightAboveLevel > 0 )
- {
- return( pItemPool->bRenderZHeightAboveLevel );
- }
- pItemPool = pItemPool->pNext;
- }
- return( 0 );
- }
- BOOLEAN DoesItemPoolContainAllItemsOfHigherZLevel( ITEM_POOL *pItemPool )
- {
- // LOOP THROUGH LIST TO FIND NODE WE WANT
- while( pItemPool != NULL )
- {
- if ( pItemPool->bRenderZHeightAboveLevel == 0 )
- {
- return( FALSE );
- }
- pItemPool = pItemPool->pNext;
- }
- return( TRUE );
- }
- BOOLEAN DoesItemPoolContainAllItemsOfZeroZLevel( ITEM_POOL *pItemPool )
- {
- // LOOP THROUGH LIST TO FIND NODE WE WANT
- while( pItemPool != NULL )
- {
- if ( pItemPool->bRenderZHeightAboveLevel != 0 )
- {
- return( FALSE );
- }
- pItemPool = pItemPool->pNext;
- }
- return( TRUE );
- }
- void RemoveItemPool( INT16 sGridNo, UINT8 ubLevel )
- {
- ITEM_POOL *pItemPool;
- // Check for and existing pool on the object layer
- while ( GetItemPool( sGridNo, &pItemPool, ubLevel ) == TRUE )
- {
- RemoveItemFromPool( sGridNo, pItemPool->iItemIndex, ubLevel );
- }
- }
- void RemoveAllUnburiedItems( INT16 sGridNo, UINT8 ubLevel )
- {
- ITEM_POOL *pItemPool;
- // Check for and existing pool on the object layer
- GetItemPool( sGridNo, &pItemPool, ubLevel );
- while( pItemPool )
- {
- if ( gWorldItems[ pItemPool->iItemIndex ].bVisible == BURIED)
- {
- pItemPool = pItemPool->pNext;
- }
- else
- {
- RemoveItemFromPool( sGridNo, pItemPool->iItemIndex, ubLevel );
- // get new start pointer
- GetItemPool( sGridNo, &pItemPool, ubLevel );
- }
- }
- }
- void LoopLevelNodeForShowThroughFlag( LEVELNODE *pNode, INT16 sGridNo, UINT8 ubLevel )
- {
- while ( pNode != NULL )
- {
- if ( pNode->uiFlags & LEVELNODE_ITEM )
- {
- if ( ubLevel == 0 )
- {
- // If we are in a room....
- // if ( IsRoofPresentAtGridno( sGridNo ) || gfCaves || gfBasement )
- {
- pNode->uiFlags |= LEVELNODE_SHOW_THROUGH;
- }
- }
- else
- {
- pNode->uiFlags |= LEVELNODE_SHOW_THROUGH;
- }
- if( gGameSettings.fOptions[ TOPTION_GLOW_ITEMS ] )
- {
- pNode->uiFlags |= LEVELNODE_DYNAMIC;
- }
- }
- pNode = pNode->pNext;
- }
- }
- void HandleItemObscuredFlag( INT16 sGridNo, UINT8 ubLevel )
- {
- LEVELNODE *pNode;
- if ( ubLevel == 0 )
- {
- pNode = gpWorldLevelData[ sGridNo ].pStructHead;
- LoopLevelNodeForShowThroughFlag( pNode, sGridNo, ubLevel );
- }
- else
- {
- pNode = gpWorldLevelData[ sGridNo ].pOnRoofHead;
- LoopLevelNodeForShowThroughFlag( pNode, sGridNo, ubLevel );
- }
- }
- BOOLEAN SetItemPoolVisibilityOn( ITEM_POOL *pItemPool, INT8 bAllGreaterThan, BOOLEAN fSetLocator )
- {
- ITEM_POOL *pItemPoolTemp;
- BOOLEAN fAtLeastModified = FALSE, fDeleted = FALSE;
- INT8 bVisibleValue;
- //OBJECTTYPE *pObj;
- pItemPoolTemp = pItemPool;
- while( pItemPoolTemp != NULL )
- {
- bVisibleValue = gWorldItems[ pItemPoolTemp->iItemIndex ].bVisible;
- // Update each item...
- if ( bVisibleValue != VISIBLE )
- {
- if ( gWorldItems[ pItemPoolTemp->iItemIndex ].o.usItem == ACTION_ITEM )
- {
- // NEVER MAKE VISIBLE!
- pItemPoolTemp = pItemPoolTemp->pNext;
- continue;
- }
- // If we have reached a visible value we should not modify, ignore...
- if ( bVisibleValue >= bAllGreaterThan && gWorldItems[ pItemPoolTemp->iItemIndex ].o.usItem != OWNERSHIP )
- {
- // Update the world value
- gWorldItems[ pItemPoolTemp->iItemIndex ].bVisible = VISIBLE;
- fAtLeastModified = TRUE;
- }
- /*
- if ( gWorldItems[ pItemPoolTemp->iItemIndex ].o.usItem == ACTION_ITEM )
- {
- pObj = &(gWorldItems[ pItemPoolTemp->iItemIndex ].o);
- switch( pObj->bActionValue )
- {
- case ACTION_ITEM_SMALL_PIT:
- case ACTION_ITEM_LARGE_PIT:
- if (pObj->bDetonatorType == 0)
- {
- // randomly set to active or destroy the item!
- if (Random( 100 ) < 65)
- {
- ArmBomb( pObj, 0 ); // will be set to pressure type so freq is irrelevant
- gWorldItems[ pItemPoolTemp->iItemIndex ].usFlags |= WORLD_ITEM_ARMED_BOMB;
- AddBombToWorld( pItemPoolTemp->iItemIndex );
- }
- else
- {
- // get pointer to the next element NOW
- pItemPoolTemp = pItemPoolTemp->pNext;
- // set flag so we don't traverse an additional time
- fDeleted = TRUE;
- // remove item from pool
- RemoveItemFromPool( pItemPool->sGridNo, pItemPool->iItemIndex, pItemPool->ubLevel );
- }
- }
- break;
- default:
- break;
- }
- }
- */
- if (fDeleted)
- {
- // don't get the 'next' pointer because we did so above
- // reset fDeleted to false so we don't skip moving through the list more than once
- fDeleted = FALSE;
- }
- else
- {
- pItemPoolTemp = pItemPoolTemp->pNext;
- }
- }
- else
- {
- pItemPoolTemp = pItemPoolTemp->pNext;
- }
- }
- // If we didn;t find any that should be modified..
- if ( !fAtLeastModified )
- {
- return( FALSE );
- }
- // Update global pool bVisible to true ( if at least one is visible... )
- pItemPoolTemp = pItemPool;
- while( pItemPoolTemp != NULL )
- {
- pItemPoolTemp->bVisible = VISIBLE;
- pItemPoolTemp = pItemPoolTemp->pNext;
- }
- // Handle obscured flag...
- HandleItemObscuredFlag( pItemPool->sGridNo, pItemPool->ubLevel );
- if ( fSetLocator )
- {
- SetItemPoolLocator( pItemPool );
- }
- return( TRUE );
- }
- void SetItemPoolVisibilityHidden( ITEM_POOL *pItemPool )
- {
- ITEM_POOL *pItemPoolTemp;
- pItemPoolTemp = pItemPool;
- while( pItemPoolTemp != NULL )
- {
- // Update the world value
- gWorldItems[ pItemPoolTemp->iItemIndex ].bVisible = HIDDEN_IN_OBJECT;
- pItemPoolTemp->bVisible = HIDDEN_IN_OBJECT;
- pItemPoolTemp = pItemPoolTemp->pNext;
- }
- }
- // This determines the overall initial visibility of the pool...
- // IF ANY are set to VISIBLE, MODIFY
- void AdjustItemPoolVisibility( ITEM_POOL *pItemPool )
- {
- ITEM_POOL *pItemPoolTemp;
- BOOLEAN fAtLeastModified = FALSE;
- pItemPoolTemp = pItemPool;
- while( pItemPoolTemp != NULL )
- {
- // DEFAULT ITEM POOL TO INVISIBLE....
- pItemPoolTemp->bVisible = INVISIBLE;
- // Update each item...
- // If we have reached a visible value we should not modify, ignore...
- if ( gWorldItems[ pItemPoolTemp->iItemIndex ].bVisible == VISIBLE )
- {
- fAtLeastModified = TRUE;
- }
- pItemPoolTemp = pItemPoolTemp->pNext;
- }
- // Handle obscured flag...
- HandleItemObscuredFlag( pItemPool->sGridNo, pItemPool->ubLevel );
- // If we didn;t find any that should be modified..
- if ( !fAtLeastModified )
- {
- return;
- }
- // Update global pool bVisible to true ( if at least one is visible... )
- pItemPoolTemp = pItemPool;
- while( pItemPoolTemp != NULL )
- {
- pItemPoolTemp->bVisible = VISIBLE;
- pItemPoolTemp = pItemPoolTemp->pNext;
- }
- // Handle obscured flag...
- HandleItemObscuredFlag( pItemPool->sGridNo, pItemPool->ubLevel );
- }
- BOOLEAN RemoveItemFromPool( INT16 sGridNo, INT32 iItemIndex, UINT8 ubLevel )
- {
- ITEM_POOL *pItemPool;
- ITEM_POOL *pItemPoolTemp;
- BOOLEAN fItemFound = FALSE;
- LEVELNODE *pObject;
- // Check for and existing pool on the object layer
- if ( GetItemPool( sGridNo, &pItemPool, ubLevel ) )
- {
- // REMOVE FROM LIST
-
- // LOOP THROUGH LIST TO FIND NODE WE WANT
- pItemPoolTemp = pItemPool;
- while( pItemPoolTemp != NULL )
- {
- if ( pItemPoolTemp->iItemIndex == iItemIndex )
- {
- fItemFound = TRUE;
- break;
- }
- pItemPoolTemp = pItemPoolTemp->pNext;
- }
- if ( !fItemFound )
- {
- // COULDNOT FIND ITEM? MAYBE SOMEBODY GOT IT BEFORE WE GOT THERE!
- return( FALSE );
- }
- // REMOVE GRAPHIC
- RemoveItemGraphicFromWorld( &(Item[ gWorldItems[ iItemIndex ].o.usItem ] ), sGridNo, ubLevel, pItemPoolTemp->pLevelNode );
- // IF WE ARE LOCATIONG STILL, KILL LOCATOR!
- if ( pItemPoolTemp->bFlashColor != 0 )
- {
- // REMOVE TIMER!
- RemoveFlashItemSlot( pItemPoolTemp );
- }
- // REMOVE PREV
- if ( pItemPoolTemp->pPrev != NULL )
- {
- pItemPoolTemp->pPrev->pNext = pItemPoolTemp->pNext;
- }
- // REMOVE NEXT
- if ( pItemPoolTemp->pNext != NULL )
- {
- pItemPoolTemp->pNext->pPrev = pItemPoolTemp->pPrev;
- }
- // IF THIS NODE WAS THE HEAD, SET ANOTHER AS HEAD AT THIS GRIDNO
- if ( pItemPoolTemp->pPrev == NULL )
- {
- // WE'RE HEAD
- if ( ubLevel == 0 )
- {
- pObject = gpWorldLevelData[ sGridNo ].pStructHead;
- }
- else
- {
- pObject = gpWorldLevelData[ sGridNo ].pOnRoofHead;
- }
- fItemFound = FALSE;
- // LOOP THORUGH OBJECT LAYER
- while( pObject != NULL )
- {
- if ( pObject->uiFlags & LEVELNODE_ITEM )
- {
- // ADJUST TO NEXT GUY FOR HEAD
- pObject->pItemPool = pItemPoolTemp->pNext;
- fItemFound = TRUE;
- }
- pObject = pObject->pNext;
- }
- if (!fItemFound)
- {
- // THIS WAS THE LAST ITEM IN THE POOL!
- gpWorldLevelData[sGridNo].uiFlags &= ~(MAPELEMENT_ITEMPOOL_PRESENT);
- }
- }
- // Find any structure with flag set as having items on top.. if this one did...
- if ( pItemPoolTemp->bRenderZHeightAboveLevel > 0 )
- {
- STRUCTURE *pStructure;
- ITEM_POOL *pTempPool;
- // Check if an item pool exists here....
- if ( !GetItemPool( pItemPoolTemp->sGridNo, &pTempPool, pItemPoolTemp->ubLevel ) )
- {
- pStructure = FindStructure( pItemPoolTemp->sGridNo , STRUCTURE_HASITEMONTOP );
-
- if ( pStructure != NULL )
- {
- // Remove...
- pStructure->fFlags &= (~STRUCTURE_HASITEMONTOP );
- // Re-adjust interactive tile...
- BeginCurInteractiveTileCheck( INTILE_CHECK_SELECTIVE );
- }
- }
- }
- AdjustItemPoolVisibility( pItemPoolTemp );
- // DELETE
- MemFree( pItemPoolTemp );
- RemoveItemFromWorld( iItemIndex );
-
- return( TRUE );
- }
- return( FALSE );
- }
- BOOLEAN MoveItemPools( INT16 sStartPos, INT16 sEndPos )
- {
- // note, only works between locations on the ground
- ITEM_POOL *pItemPool;
- WORLDITEM TempWorldItem;
- // While there is an existing pool
- while( GetItemPool( sStartPos, &pItemPool, 0 ) )
- {
- memcpy( &TempWorldItem, &(gWorldItems[ pItemPool->iItemIndex ]), sizeof( WORLDITEM ) );
- RemoveItemFromPool( sStartPos, pItemPool->iItemIndex, 0 );
- AddItemToPool( sEndPos, &(TempWorldItem.o), -1, TempWorldItem.ubLevel, TempWorldItem.usFlags, TempWorldItem.bRenderZHeightAboveLevel );
- }
- return( TRUE );
- }
- BOOLEAN GetItemPool( UINT16 usMapPos, ITEM_POOL **ppItemPool, UINT8 ubLevel )
- {
- LEVELNODE *pObject;
- if ( ubLevel == 0 )
- {
- pObject = gpWorldLevelData[ usMapPos ].pStructHead;
- }
- else
- {
- pObject = gpWorldLevelData[ usMapPos ].pOnRoofHead;
- }
- (*ppItemPool) = NULL;
- // LOOP THORUGH OBJECT LAYER
- while( pObject != NULL )
- {
- if ( pObject->uiFlags & LEVELNODE_ITEM )
- {
- (*ppItemPool) = pObject->pItemPool;
- //DEF added the check because pObject->pItemPool was NULL which was causing problems
- if( *ppItemPool )
- return( TRUE );
- else
- return( FALSE );
- }
- pObject = pObject->pNext;
- }
- return( FALSE );
- }
- void NotifySoldiersToLookforItems( )
- {
- UINT32 cnt;
- SOLDIERTYPE *pSoldier;
- for ( cnt = 0; cnt < guiNumMercSlots; cnt++ )
- {
- pSoldier = MercSlots[ cnt ];
- if ( pSoldier != NULL )
- {
- pSoldier->uiStatusFlags |= SOLDIER_LOOKFOR_ITEMS;
- }
- }
- }
- void AllSoldiersLookforItems( BOOLEAN fShowLocators )
- {
- UINT32 cnt;
- SOLDIERTYPE *pSoldier;
- for ( cnt = 0; cnt < guiNumMercSlots; cnt++ )
- {
- pSoldier = MercSlots[ cnt ];
- if ( pSoldier != NULL )
- {
- RevealRoofsAndItems(pSoldier, TRUE, fShowLocators, pSoldier->bLevel, FALSE );
- }
- }
- }
- INT16 GetNumOkForDisplayItemsInPool( ITEM_POOL *pItemPool, INT8 bZLevel )
- {
- INT32 cnt;
- //Determine total #
- cnt = 0;
- while( pItemPool != NULL )
- {
- if ( ItemPoolOKForDisplay( pItemPool, bZLevel ) )
- {
- cnt++;
- }
- pItemPool = pItemPool->pNext;
- }
- return( (UINT16) cnt );
- }
- BOOLEAN AnyItemsVisibleOnLevel( ITEM_POOL *pItemPool, INT8 bZLevel )
- {
- if ( ( gTacticalStatus.uiFlags & SHOW_ALL_ITEMS ) )
- {
- return( TRUE );
- }
- //Determine total #
- while( pItemPool != NULL )
- {
- if ( pItemPool->bRenderZHeightAboveLevel == bZLevel )
- {
- if ( gWorldItems[ pItemPool->iItemIndex ].bVisible == VISIBLE )
- {
- return( TRUE );
- }
- }
- pItemPool = pItemPool->pNext;
- }
- return( FALSE );
- }
- BOOLEAN ItemPoolOKForDisplay( ITEM_POOL *pItemPool, INT8 bZLevel )
- {
- if (gTacticalStatus.uiFlags&SHOW_ALL_ITEMS)
- {
- return( TRUE );
- }
- // Setup some conditions!
- if ( gWorldItems[ pItemPool->iItemIndex ].bVisible != VISIBLE )
- {
- return( FALSE );
- }
- // If -1, it means find all
- if ( pItemPool->bRenderZHeightAboveLevel != bZLevel && bZLevel != -1 )
- {
- return( FALSE );
- }
- return( TRUE );
- }
- BOOLEAN ItemPoolOKForPickup( SOLDIERTYPE * pSoldier, ITEM_POOL *pItemPool, INT8 bZLevel )
- {
- if (gTacticalStatus.uiFlags&SHOW_ALL_ITEMS)
- {
- return( TRUE );
- }
- if ( pSoldier->bTeam == gbPlayerNum )
- {
- // Setup some conditions!
- if ( gWorldItems[ pItemPool->iItemIndex ].bVisible != VISIBLE )
- {
- return( FALSE );
- }
- }
- // If -1, it means find all
- if ( pItemPool->bRenderZHeightAboveLevel != bZLevel && bZLevel != -1 )
- {
- return( FALSE );
- }
- return( TRUE );
- }
- extern void HandleAnyMercInSquadHasCompatibleStuff( UINT8 ubSquad, OBJECTTYPE *pObject, BOOLEAN fReset );
- BOOLEAN DrawItemPoolList( ITEM_POOL *pItemPool, INT16 sGridNo, UINT8 bCommand, INT8 bZLevel, INT16 sXPos, INT16 sYPos )
- {
- INT16 sY;
- INVTYPE *pItem;
- ITEM_POOL *pTempItemPool;
- INT16 pStr[ 100 ];
- INT16 cnt = 0, sHeight = 0;
- INT16 sLargeLineWidth = 0, sLineWidth;
- BOOLEAN fRecalcNumListed = FALSE;
- BOOLEAN fSelectionDone = FALSE;
- INT8 gbCurrentItemSel = 0;
- INT8 bNumItemsListed = 0;
- INT16 sFontX, sFontY;
- INT16 sLargestLineWidth = 30;
- INT8 bCurStart = 0;
- BOOLEAN fDoBack;
- // Take a look at each guy in current sqaud and check for compatible ammo...
- // Determine how many there are
- // MOVE HEAD TO CURRENT START
- cnt = 0;
- pTempItemPool = pItemPool;
- while( pTempItemPool != NULL )
- {
- if ( cnt == bCurStart )
- {
- break;
- }
- // ATE: Put some conditions on this....
- if ( ItemPoolOKForDisplay( pTempItemPool, bZLevel ) )
- {
- cnt++;
- }
- pTempItemPool = pTempItemPool->pNext;
- }
- cnt = bCurStart;
- fDoBack = FALSE;
- while( pTempItemPool != NULL )
- {
- // IF WE HAVE MORE THAN THE SET AMOUNT, QUIT NOW!
- if ( cnt == ( bCurStart + NUM_ITEMS_LISTED ) )
- {
- cnt++;
- fDoBack = TRUE;
- break;
- }
- // ATE: Put some conditions on this....
- if ( ItemPoolOKForDisplay( pTempItemPool, bZLevel ) )
- {
- cnt++;
- }
- sHeight += GetFontHeight( SMALLFONT1 ) - 2;
- pTempItemPool = pTempItemPool->pNext;
- }
- pTempItemPool = pItemPool;
- while( pTempItemPool != NULL )
- {
- // ATE: Put some conditions on this....
- if ( ItemPoolOKForDisplay( pTempItemPool, bZLevel ) )
- {
- HandleAnyMercInSquadHasCompatibleStuff( (INT8)CurrentSquad( ), &(gWorldItems[ pTempItemPool->iItemIndex ].o ), FALSE );
- }
- pTempItemPool = pTempItemPool->pNext;
- }
- // IF COUNT IS ALREADY > MAX, ADD A PREV...
- if ( bCurStart >= NUM_ITEMS_LISTED )
- {
- cnt++;
- }
-
- bNumItemsListed = (INT8)cnt;
-
- //RENDER LIST!
- // Determine max length
- pTempItemPool = pItemPool;
- while( pTempItemPool != NULL )
- {
- if ( ItemPoolOKForDisplay( pTempItemPool, bZLevel ) )
- {
- // GET ITEM
- pItem = &Item[ gWorldItems[ pTempItemPool->iItemIndex ].o.usItem ];
- // Set string
- if ( gWorldItems[ pTempItemPool->iItemIndex ].o.ubNumberOfObjects > 1 )
- {
- swprintf( pStr, L"%s (%d)", ShortItemNames[ gWorldItems[ pTempItemPool->iItemIndex ].o.usItem ], gWorldItems[ pTempItemPool->iItemIndex ].o.ubNumberOfObjects );
- }
- else
- {
- swprintf( pStr, L"%s", ShortItemNames[ gWorldItems[ pTempItemPool->iItemIndex ].o.usItem ] );
- }
- // Get Width
- sLineWidth = StringPixLength( pStr,SMALLFONT1 );
- if ( sLineWidth > sLargeLineWidth )
- {
- sLargeLineWidth = sLineWidth;
- }
- sLargestLineWidth = sLargeLineWidth;
- }
- pTempItemPool = pTempItemPool->pNext;
- }
- // Determine where our mouse is!
- if ( sXPos > ( 640 - sLargestLineWidth ) )
- {
- sFontX = sXPos - sLargestLineWidth;
- }
- else
- {
- sFontX = sXPos + 15;
- }
- sFontY = sYPos;
- // Move up if over interface....
- if ( ( sFontY + sHeight ) > 340 )
- {
- sFontY = 340 - sHeight;
- }
- // Detertime vertiacal center
- sFontY -= ( sHeight / 2 );
- SetFont( SMALLFONT1 );
- SetFontBackground( FONT_MCOLOR_BLACK );
- SetFontForeground( FONT_MCOLOR_DKGRAY );
- // MOVE HEAD TO CURRENT START
- cnt = 0;
- while( pItemPool != NULL )
- {
- if ( cnt == bCurStart )
- {
- break;
- }
- if ( ItemPoolOKForDisplay( pItemPool, bZLevel ) )
- {
- cnt++;
- }
- pItemPool = pItemPool->pNext;
- }
- // START DISPLAY LOOP
- cnt = bCurStart;
- sY = sFontY;
- // ADD PREV TO THIS LIST!
- if ( bCurStart >= NUM_ITEMS_LISTED )
- {
- // Set string
- if ( cnt == gbCurrentItemSel )
- {
- SetFontForeground( FONT_MCOLOR_LTGRAY );
- }
- else
- {
- SetFontForeground( FONT_MCOLOR_DKGRAY );
- }
- swprintf( pStr, TacticalStr[ ITEMPOOL_POPUP_PREV_STR ] );
- gprintfdirty( sFontX, sY, pStr );
- mprintf( sFontX, sY, pStr );
- sY += GetFontHeight( SMALLFONT1 ) - 2;
- cnt++;
- }
- while( pItemPool != NULL )
- {
- if ( bCommand == ITEMLIST_HANDLE )
- {
- if ( cnt == gbCurrentItemSel )
- {
- SetFontForeground( FONT_MCOLOR_LTGRAY );
- }
- else
- {
- SetFontForeground( FONT_MCOLOR_DKGRAY );
- }
- }
- if ( ItemPoolOKForDisplay( pItemPool, bZLevel ) )
- {
- // GET ITEM
- pItem = &Item[ gWorldItems[ pItemPool->iItemIndex ].o.usItem ];
- // Set string
- if ( gWorldItems[ pItemPool->iItemIndex ].o.ubNumberOfObjects > 1 )
- {
- swprintf( pStr, L"%s (%d)", ShortItemNames[ gWorldItems[ pItemPool->iItemIndex ].o.usItem ], gWorldItems[ pItemPool->iItemIndex ].o.ubNumberOfObjects );
- }
- else
- {
- swprintf( pStr, L"%s", ShortItemNames[ gWorldItems[ pItemPool->iItemIndex ].o.usItem ] );
- }
- gprintfdirty( sFontX, sY, pStr );
- mprintf( sFontX, sY, pStr );
- sY += GetFontHeight( SMALLFONT1 ) - 2;
- cnt++;
- }
- pItemPool = pItemPool->pNext;
- if ( fDoBack )
- {
- if ( cnt == ( bNumItemsListed - 1) )
- {
- break;
- }
- }
- }
- if ( fDoBack )
- {
- if ( cnt == ( bNumItemsListed - 1) )
- {
- // Set string
- if ( cnt == gbCurrentItemSel )
- {
- SetFontForeground( FONT_MCOLOR_LTGRAY );
- }
- else
- {
- SetFontForeground( FONT_MCOLOR_DKGRAY );
- }
- swprintf( pStr, TacticalStr[ ITEMPOOL_POPUP_MORE_STR ] );
- gprintfdirty( sFontX, sY, pStr );
- mprintf( sFontX, sY, pStr );
- }
- }
- return( fSelectionDone );
- }
- INT8 GetListMouseHotSpot( INT16 sLargestLineWidth, INT8 bNumItemsListed, INT16 sFontX, INT16 sFontY, INT8 bCurStart )
- {
- INT16 cnt = 0;
- INT16 sTestX1, sTestX2, sTestY1, sTestY2;
- INT16 sLineHeight;
- INT8 gbCurrentItemSel = -1;
- INT8 bListedItems;
- sLineHeight = GetFontHeight( SMALLFONT1 ) - 2;
- sTestX1 = sFontX;
- sTestX2 = sFontX + sLargestLineWidth;
- bListedItems = ( bNumItemsListed - bCurStart );
- if ( gusMouseXPos < sTestX1 || gusMouseXPos > sTestX2 )
- {
- gbCurrentItemSel = -1;
- }
- else
- {
- // Determine where mouse is!
- for ( cnt = 0; cnt < bListedItems; cnt++ )
- {
- sTestY1 = sFontY + ( sLineHeight * cnt );
- sTestY2 = sFontY + ( sLineHeight * ( cnt + 1 ) );
- if ( gusMouseYPos > sTestY1 && gusMouseYPos < sTestY2 )
- {
- gbCurrentItemSel = (INT8)cnt;
- break;
- }
- }
- }
- // OFFSET START
- gbCurrentItemSel += bCurStart;
-
- return( gbCurrentItemSel );
- }
- void SetItemPoolLocator( ITEM_POOL *pItemPool )
- {
- pItemPool->bFlashColor = 59;
- pItemPool->uiTimerID = AddFlashItemSlot( pItemPool, NULL, 0 );
- }
- void SetItemPoolLocatorWithCallback( ITEM_POOL *pItemPool, ITEM_POOL_LOCATOR_HOOK Callback )
- {
- pItemPool->bFlashColor = 59;
- pItemPool->uiTimerID = AddFlashItemSlot( pItemPool, Callback, 0 );
- }
- /// ITEM POOL INDICATOR FUNCTIONS
- INT32 GetFreeFlashItemSlot(void)
- {
- UINT32 uiCount;
- for(uiCount=0; uiCount < guiNumFlashItemSlots; uiCount++)
- {
- if(( FlashItemSlots[uiCount].fAllocated == FALSE ) )
- return((INT32)uiCount);
- }
- if(guiNumFlashItemSlots < NUM_ITEM_FLASH_SLOTS )
- return((INT32)guiNumFlashItemSlots++);
- return(-1);
- }
- void RecountFlashItemSlots(void)
- {
- INT32 uiCount;
- for(uiCount=guiNumFlashItemSlots-1; (uiCount >=0) ; uiCount--)
- {
- if( ( FlashItemSlots[uiCount].fAllocated ) )
- {
- guiNumFlashItemSlots=(UINT32)(uiCount+1);
- break;
- }
- }
- }
- INT32 AddFlashItemSlot( ITEM_POOL *pItemPool, ITEM_POOL_LOCATOR_HOOK Callback, UINT8 ubFlags )
- {
- INT32 iFlashItemIndex;
- if( ( iFlashItemIndex = GetFreeFlashItemSlot() )==(-1) )
- return(-1);
- ubFlags |= ITEM_LOCATOR_LOCKED;
- FlashItemSlots[ iFlashItemIndex ].pItemPool = pItemPool;
- FlashItemSlots[ iFlashItemIndex ].bRadioFrame = 0;
- FlashItemSlots[ iFlashItemIndex ].uiLastFrameUpdate = GetJA2Clock( );
- FlashItemSlots[ iFlashItemIndex ].Callback = Callback;
- FlashItemSlots[ iFlashItemIndex ].fAllocated = TRUE;
- FlashItemSlots[ iFlashItemIndex ].ubFlags = ubFlags;
- return( iFlashItemIndex );
- }
- BOOLEAN RemoveFlashItemSlot( ITEM_POOL *pItemPool )
- {
- UINT32 uiCount;
- CHECKF( pItemPool != NULL );
- for( uiCount=0; uiCount < guiNumFlashItemSlots; uiCount++)
- {
- if ( FlashItemSlots[ uiCount ].fAllocated )
- {
- if ( FlashItemSlots[ uiCount ].pItemPool == pItemPool )
- {
- FlashItemSlots[ uiCount ].fAllocated = FALSE;
- // Check if we have a callback and call it if so!
- if ( FlashItemSlots[ uiCount ].Callback != NULL )
- {
- FlashItemSlots[ uiCount ].Callback( );
- }
- return( TRUE );
- }
- }
- }
- return( TRUE );
- }
- void HandleFlashingItems( )
- {
- UINT32 cnt;
- ITEM_POOL *pItemPool;
- LEVELNODE *pObject;
- ITEM_POOL_LOCATOR *pLocator;
- BOOLEAN fDoLocator = FALSE;
- if ( COUNTERDONE( CYCLERENDERITEMCOLOR ) )
- {
- RESETCOUNTER( CYCLERENDERITEMCOLOR );
- for ( cnt = 0; cnt < guiNumFlashItemSlots; cnt++ )
- {
- pLocator = &( FlashItemSlots[ cnt ] );
- if ( pLocator->fAllocated )
- {
- fDoLocator = TRUE;
- if ( ( pLocator->ubFlags & ITEM_LOCATOR_LOCKED ) )
- {
- if ( gTacticalStatus.fLockItemLocators == FALSE )
- {
- // Turn off!
- pLocator->ubFlags &= (~ITEM_LOCATOR_LOCKED);
- }
- else
- {
- fDoLocator = FALSE;
- }
- }
- if ( fDoLocator )
- {
- pItemPool = pLocator->pItemPool;
- // Update radio locator
- {
- UINT32 uiClock;
- uiClock = GetJA2Clock( );
-
- // Update frame values!
- if ( ( uiClock - pLocator->uiLastFrameUpdate ) > 80 )
- {
- pLocator->uiLastFrameUpdate = uiClock;
- // Update frame
- pLocator->bRadioFrame++;
- if ( pLocator->bRadioFrame == 5 )
- {
- pLocator->bRadioFrame = 0;
- }
- }
- }
- // UPDATE FLASH COLOR VALUE
- pItemPool->bFlashColor--;
- if ( pItemPool->ubLevel == 0 )
- {
- pObject = gpWorldLevelData[ pItemPool->sGridNo ].pStructHead;
- }
- else
- {
- pObject = gpWorldLevelData[ pItemPool->sGridNo ].pOnRoofHead;
- }
- // LOOP THORUGH OBJECT LAYER
- while( pObject != NULL )
- {
- if ( pObject->uiFlags & LEVELNODE_ITEM )
- {
- if ( pItemPool->bFlashColor == 1 )
- {
- //pObject->uiFlags &= (~LEVELNODE_DYNAMIC);
- //pObject->uiFlags |= ( LEVELNODE_LASTDYNAMIC );
- }
- else
- {
- //pObject->uiFlags |= LEVELNODE_DYNAMIC;
- }
- }
- pObject = pObject->pNext;
- }
- if ( pItemPool->bFlashColor == 1 )
- {
- pItemPool->bFlashColor = 0;
- // REMOVE TIMER!
- RemoveFlashItemSlot( pItemPool );
- SetRenderFlags( RENDER_FLAG_FULL );
- }
- }
- }
- }
- RecountFlashItemSlots( );
- }
- }
- void RenderTopmostFlashingItems( )
- {
- UINT32 cnt;
- ITEM_POOL *pItemPool;
- ITEM_POOL_LOCATOR *pLocator;
- for ( cnt = 0; cnt < guiNumFlashItemSlots; cnt++ )
- {
- pLocator = &( FlashItemSlots[ cnt ] );
- if ( pLocator->fAllocated )
- {
- if ( !( pLocator->ubFlags & ( ITEM_LOCATOR_LOCKED ) ) )
- {
- pItemPool = pLocator->pItemPool;
- // Update radio locator
- {
- FLOAT dOffsetX, dOffsetY;
- FLOAT dTempX_S, dTempY_S;
- INT16 sX, sY, sXPos, sYPos;
- INT32 iBack;
- ConvertGridNoToCenterCellXY( pItemPool->sGridNo, &sX, &sY );
- dOffsetX = (FLOAT)( sX - gsRenderCenterX );
- dOffsetY = (FLOAT)( sY - gsRenderCenterY );
- // Calculate guy's position
- FloatFromCellToScreenCoordinates( dOffsetX, dOffsetY, &dTempX_S, &dTempY_S );
- sXPos = ( ( gsVIEWPORT_END_X - gsVIEWPORT_START_X ) /2 ) + (INT16)dTempX_S;
- sYPos = ( ( gsVIEWPORT_END_Y - gsVIEWPORT_START_Y ) /2 ) + (INT16)dTempY_S - gpWorldLevelData[ pItemPool->sGridNo ].sHeight;
- // Adjust for offset position on screen
- sXPos -= gsRenderWorldOffsetX;
- sYPos -= gsRenderWorldOffsetY;
- sYPos -= pItemPool->bRenderZHeightAboveLevel;
- // Adjust for render height
- sYPos += gsRenderHeight;
- // Adjust for level height
- if ( pItemPool->ubLevel )
- {
- sYPos -= ROOF_LEVEL_HEIGHT;
- }
- // Center circle!
- sXPos -= 20;
- sYPos -= 20;
- iBack = RegisterBackgroundRect( BGND_FLAG_SINGLE, NULL, sXPos, sYPos, (INT16)(sXPos +40 ), (INT16)(sYPos + 40 ) );
- if ( iBack != -1 )
- {
- SetBackgroundRectFilled( iBack );
- }
- BltVideoObjectFromIndex( FRAME_BUFFER, guiRADIO, pLocator->bRadioFrame, sXPos, sYPos, VO_BLT_SRCTRANSPARENCY, NULL );
- DrawItemPoolList( pItemPool, pItemPool->sGridNo , ITEMLIST_DISPLAY, pItemPool->bRenderZHeightAboveLevel, sXPos, sYPos );
- }
- }
- }
- }
- }
- BOOLEAN VerifyGiveItem( SOLDIERTYPE *pSoldier, SOLDIERTYPE **ppTargetSoldier )
- {
- SOLDIERTYPE *pTSoldier;
- UINT16 usSoldierIndex;
- OBJECTTYPE *pObject;
- INT16 sGridNo;
- UINT8 ubDirection;
- UINT8 ubTargetMercID;
- // DO SOME CHECKS IF WE CAN DO ANIMATION.....
- // Get items from pending data
- pObject = pSoldier->pTempObject;
- sGridNo = pSoldier->sPendingActionData2;
- ubDirection = pSoldier->bPendingActionData3;
- ubTargetMercID = (UINT8)pSoldier->uiPendingActionData4;
- usSoldierIndex = WhoIsThere2( sGridNo, pSoldier->bLevel );
- // See if our target is still available
- if ( usSoldierIndex != NOBODY )
- {
- // Check if it's the same merc!
- if ( usSoldierIndex != ubTargetMercID )
- {
- return( FALSE );
- }
- // Get soldier
- GetSoldier( &pTSoldier, usSoldierIndex );
- // Look for item in hand....
- (*ppTargetSoldier) = pTSoldier;
- return( TRUE );
- }
- else
- {
- if ( pSoldier->pTempObject != NULL )
- {
- AddItemToPool( pSoldier->sGridNo, pSoldier->pTempObject, 1, pSoldier->bLevel, 0 , -1 );
- // Place it on the ground!
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ ITEM_HAS_BEEN_PLACED_ON_GROUND_STR ], ShortItemNames[ pSoldier->pTempObject->usItem ] );
- // OK, disengage buddy
- pSoldier->uiStatusFlags &= (~SOLDIER_ENGAGEDINACTION );
- if ( ubTargetMercID != NOBODY )
- {
- MercPtrs[ ubTargetMercID ]->uiStatusFlags &= (~SOLDIER_ENGAGEDINACTION );
- }
- MemFree( pSoldier->pTempObject );
- pSoldier->pTempObject = NULL;
- }
- }
- return( FALSE );
- }
- void SoldierGiveItemFromAnimation( SOLDIERTYPE *pSoldier )
- {
- SOLDIERTYPE *pTSoldier;
- INT8 bInvPos;
- OBJECTTYPE TempObject;
- UINT8 ubProfile;
- INT16 sGridNo;
- UINT8 ubDirection;
- UINT8 ubTargetMercID;
- UINT16 usItemNum;
- BOOLEAN fToTargetPlayer = FALSE;
- // Get items from pending data
- // Get objectype and delete
- memcpy( &TempObject, pSoldier->pTempObject, sizeof( OBJECTTYPE ) );
- MemFree( pSoldier->pTempObject );
- pSoldier->pTempObject = NULL;
- bInvPos = pSoldier->bPendingActionData5;
- usItemNum = TempObject.usItem;
- // ATE: OK, check if we have an item in the cursor from
- // this soldier and from this inv slot, if so, delete!!!!!!!
- if ( gpItemPointer != NULL )
- {
- if ( pSoldier->ubID == gpItemPointerSoldier->ubID )
- {
- if ( bInvPos == gbItemPointerSrcSlot && usItemNum == gpItemPointer->usItem )
- {
- // Remove!!!
- EndItemPointer( );
- }
- }
- }
- sGridNo = pSoldier->sPendingActionData2;
- ubDirection = pSoldier->bPendingActionData3;
- ubTargetMercID = (UINT8)pSoldier->uiPendingActionData4;
- // ATE: Deduct APs!
- DeductPoints( pSoldier, AP_PICKUP_ITEM, 0 );
- if ( VerifyGiveItem( pSoldier, &pTSoldier ) )
- {
- // DAVE! - put stuff here to bring up shopkeeper.......
- //if the user just clicked on an arms dealer
- if( IsMercADealer( pTSoldier->ubProfile ) )
- {
- UnSetEngagedInConvFromPCAction( pSoldier );
- //if the dealer is Micky,
- /*
- if( pTSoldier->ubProfile == MICKY )
- {
- //and the items are alcohol, dont enter the shopkeeper
- if( GetArmsDealerItemTypeFromItemNumber( TempObject.usItem ) == ARMS_DEALER_ALCOHOL )
- return;
- }
- */
- if ( NPCHasUnusedRecordWithGivenApproach( pTSoldier->ubProfile, APPROACH_BUYSELL ) )
- {
- TriggerNPCWithGivenApproach( pTSoldier->ubProfile, APPROACH_BUYSELL, TRUE );
- return;
- }
- // now also check for buy/sell lines (Oct 13)
- /*
- else if ( NPCWillingToAcceptItem( pTSoldier->ubProfile, pSoldier->ubProfile, &TempObject ) )
- {
- TriggerNPCWithGivenApproach( pTSoldier->ubProfile, APPROACH_GIVINGITEM, TRUE );
- return;
- }*/
- else if ( !NPCWillingToAcceptItem( pTSoldier->ubProfile, pSoldier->ubProfile, &TempObject ) )
- {
- //Enter the shopkeeper interface
- EnterShopKeeperInterfaceScreen( pTSoldier->ubProfile );
- // removed the if, because if the player picked up an item straight from the ground or money strait from the money
- // interface, the item would NOT have a bInvPos, therefore it would not get added to the dealer, and would get deleted
- // if ( bInvPos != NO_SLOT )
- {
- // MUST send in NO_SLOT, as the SKI wille expect it to exist in inv if not....
- AddItemToPlayersOfferAreaAfterShopKeeperOpen( &TempObject, NO_SLOT );
- /*
- Changed because if the player gave 1 item from a pile, the rest of the items in the piule would disappear
- // OK, r emove the item, as the SKI will give it back once done
- DeleteObj( &( pSoldier->inv[ bInvPos ] ) );
- */
- if ( bInvPos != NO_SLOT )
- {
- RemoveObjFrom( &pSoldier->inv[ bInvPos ], TempObject.ubNumberOfObjects );
- }
- DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
- }
- return;
- }
- }
- // OK< FOR NOW HANDLE NPC's DIFFERENT!
- ubProfile = pTSoldier->ubProfile;
- // 1 ) PLayer to NPC = NPC
- // 2 ) Player to player = player;
- // 3 ) NPC to player = player;
- // 4 ) NPC TO NPC = NPC
- // Switch on target...
- // Are we a player dude.. ( target? )
- if ( ubProfile < FIRST_RPC || RPC_RECRUITED( pTSoldier ) )
- {
- fToTargetPlayer = TRUE;
- }
- if ( fToTargetPlayer )
- {
- // begin giving
- DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
- // We are a merc, add!
- if ( !AutoPlaceObject( pTSoldier, &TempObject, TRUE ) )
- {
- // Erase!
- if ( bInvPos != NO_SLOT )
- {
- DeleteObj( &( pSoldier->inv[ bInvPos ] ) );
- DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
- }
-
- AddItemToPool( pSoldier->sGridNo, &TempObject, 1, pSoldier->bLevel, 0 , -1 );
- // We could not place it!
- // Drop it on the ground?
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ ITEM_HAS_BEEN_PLACED_ON_GROUND_STR ], ShortItemNames[ usItemNum ] );
- // OK, disengage buddy
- pSoldier->uiStatusFlags &= (~SOLDIER_ENGAGEDINACTION );
- pTSoldier->uiStatusFlags &= (~SOLDIER_ENGAGEDINACTION );
- }
- else
- {
- // Erase!
- if ( bInvPos != NO_SLOT )
- {
- DeleteObj( &( pSoldier->inv[ bInvPos ] ) );
- DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
- }
- // OK, it's given, display message!
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ ITEM_HAS_BEEN_GIVEN_TO_STR ], ShortItemNames[ usItemNum ], pTSoldier->name );
- if (usItemNum == MONEY)
- {
- // are we giving money to an NPC, to whom we owe money?
- if (pTSoldier->ubProfile != NO_PROFILE && gMercProfiles[pTSoldier->ubProfile].iBalance < 0)
- {
- gMercProfiles[pTSoldier->ubProfile].iBalance += TempObject.uiMoneyAmount;
- if (gMercProfiles[pTSoldier->ubProfile].iBalance >= 0)
- {
- // don't let the player accumulate credit (?)
- gMercProfiles[pTSoldier->ubProfile].iBalance = 0;
- // report the payment and set facts to indicate people not being owed money
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ GUY_HAS_BEEN_PAID_IN_FULL_STR ], pTSoldier->name );
- }
- else
- {
- // report the payment
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ GUY_STILL_OWED_STR ], pTSoldier->name, -gMercProfiles[pTSoldier->ubProfile].iBalance );
- }
- }
- }
- }
- }
- else
- {
- // Erase!
- if ( bInvPos != NO_SLOT )
- {
- RemoveObjs( &(pSoldier->inv[ bInvPos ]), TempObject.ubNumberOfObjects );
- DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
- }
- // Now intiate conv
- InitiateConversation( pTSoldier, pSoldier, APPROACH_GIVINGITEM, (INT32)&TempObject );
- }
- }
- // OK, disengage buddy
- pSoldier->uiStatusFlags &= (~SOLDIER_ENGAGEDINACTION );
- pTSoldier->uiStatusFlags &= (~SOLDIER_ENGAGEDINACTION );
- }
- INT16 AdjustGridNoForItemPlacement( SOLDIERTYPE *pSoldier, INT16 sGridNo )
- {
- STRUCTURE *pStructure;
- INT16 sDesiredLevel;
- INT16 sActionGridNo;
- BOOLEAN fStructFound = FALSE;
- UINT8 ubDirection;
- INT16 sAdjustedGridNo;
- UINT8 ubTargetID;
-
- sActionGridNo = sGridNo;
- // Check structure database
- if( gpWorldLevelData[ sGridNo ].pStructureHead )
- {
- // Something is here, check obstruction in future
- sDesiredLevel = pSoldier->bLevel ? STRUCTURE_ON_ROOF : STRUCTURE_ON_GROUND;
- pStructure = FindStructure( (INT16)sGridNo, STRUCTURE_BLOCKSMOVES );
- while( pStructure )
- {
- if( !(pStructure->fFlags & STRUCTURE_PASSABLE) && pStructure->sCubeOffset == sDesiredLevel )
- {
- // Check for openable flag....
- //if ( pStructure->fFlags & ( STRUCTURE_OPENABLE | STRUCTURE_HASITEMONTOP ) )
- {
- fStructFound = TRUE;
- break;
- }
- }
- pStructure = FindNextStructure( pStructure, STRUCTURE_BLOCKSMOVES );
- }
- }
- // ATE: IF a person is found, use adjacent gridno for it!
- ubTargetID = WhoIsThere2( sGridNo, pSoldier->bLevel );
- if ( fStructFound || ( ubTargetID != NOBODY && ubTargetID != pSoldier->ubID ) )
- {
- // GET ADJACENT GRIDNO
- sActionGridNo = FindAdjacentGridEx( pSoldier, sGridNo, &ubDirection, &sAdjustedGridNo, FALSE, FALSE );
- if ( sActionGridNo == -1 )
- {
- sActionGridNo = sAdjustedGridNo;
- }
- }
- return( sActionGridNo );
- }
-
- void StartBombMessageBox( SOLDIERTYPE * pSoldier, INT16 sGridNo )
- {
- UINT8 ubRoom;
- gpTempSoldier = pSoldier;
- gsTempGridno = sGridNo;
- if (pSoldier->inv[HANDPOS].usItem == REMOTEBOMBTRIGGER)
- {
- DoMessageBox( MSG_BOX_BASIC_SMALL_BUTTONS, TacticalStr[ CHOOSE_BOMB_FREQUENCY_STR ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_FOUR_NUMBERED_BUTTONS, BombMessageBoxCallBack, NULL );
- }
- else if (pSoldier->inv[HANDPOS].usItem == REMOTETRIGGER)
- {
- #ifdef JA2DEMO
- {
- UINT8 ubRoom;
- if ( InARoom( pSoldier->sGridNo, &ubRoom ) && ubRoom == 31 )
- {
- SetOffBombsByFrequency( pSoldier->ubID, FIRST_MAP_PLACED_FREQUENCY + 4 );
- DoMercBattleSound( pSoldier, BATTLE_SOUND_OK1 );
- }
- else
- {
- DoMercBattleSound( pSoldier, BATTLE_SOUND_CURSE1 );
- }
- }
- #else
- // ATE ignore the commented-out code and add stuff to open the secret passage here
- /*
- switch( pSoldier->inv[HANDPOS].ubLocationID )
- {
- // check to make sure the appropriate sector is loaded
- }
- SetOffBombsByFrequency( pSoldier->ubID, pSoldier->inv[HANDPOS].bFrequency );
- */
-
- // PLay sound....
- PlayJA2Sample( USE_STATUE_REMOTE, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN );
- // Check what sector we are in....
- if ( gWorldSectorX == 3 && gWorldSectorY == MAP_ROW_O && gbWorldSectorZ == 0 )
- {
- if ( InARoom( pSoldier->sGridNo, &ubRoom ) && ubRoom == 4 )
- {
- DoMercBattleSound( pSoldier, BATTLE_SOUND_OK1 );
- // Open statue
- ChangeO3SectorStatue( FALSE );
- }
- else
- {
- DoMercBattleSound( pSoldier, BATTLE_SOUND_CURSE1 );
- }
- }
- else
- {
- DoMercBattleSound( pSoldier, BATTLE_SOUND_CURSE1 );
- }
- #endif
- }
- else if ( FindAttachment( &(pSoldier->inv[HANDPOS]), DETONATOR) != ITEM_NOT_FOUND )
- {
- DoMessageBox( MSG_BOX_BASIC_SMALL_BUTTONS, TacticalStr[ CHOOSE_TIMER_STR ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_FOUR_NUMBERED_BUTTONS, BombMessageBoxCallBack, NULL );
- }
- else if ( FindAttachment( &(pSoldier->inv[HANDPOS]), REMDETONATOR) != ITEM_NOT_FOUND )
- {
- DoMessageBox( MSG_BOX_BASIC_SMALL_BUTTONS, TacticalStr[ CHOOSE_REMOTE_FREQUENCY_STR ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_FOUR_NUMBERED_BUTTONS, BombMessageBoxCallBack, NULL );
- }
- }
- void BombMessageBoxCallBack( UINT8 ubExitValue )
- {
- if (gpTempSoldier)
- {
- if (gpTempSoldier->inv[HANDPOS].usItem == REMOTEBOMBTRIGGER)
- {
- SetOffBombsByFrequency( gpTempSoldier->ubID, ubExitValue );
- }
- else
- {
- INT32 iResult;
- if (FindAttachment( &(gpTempSoldier->inv[HANDPOS]), REMDETONATOR ) != ITEM_NOT_FOUND )
- {
- iResult = SkillCheck( gpTempSoldier, PLANTING_REMOTE_BOMB_CHECK, 0 );
- }
- else
- {
- iResult = SkillCheck( gpTempSoldier, PLANTING_BOMB_CHECK, 0 );
- }
- if ( iResult >= 0 )
- {
- // EXPLOSIVES GAIN (25): Place a bomb, or buried and armed a mine
- StatChange( gpTempSoldier, EXPLODEAMT, 25, FALSE );
- }
- else
- {
- // EXPLOSIVES GAIN (10): Failed to place a bomb, or bury and arm a mine
- StatChange( gpTempSoldier, EXPLODEAMT, 10, FROM_FAILURE );
- // oops! How badly did we screw up?
- if ( iResult >= -20 )
- {
- // messed up the setting
- if ( ubExitValue == 0 )
- {
- ubExitValue = 1;
- }
- else
- {
- // change up/down by 1
- ubExitValue = (UINT8) (ubExitValue + Random( 3 ) - 1);
- }
- // and continue
- }
- else
- {
- // OOPS! ... BOOM!
- IgniteExplosion( NOBODY, gpTempSoldier->sX, gpTempSoldier->sY, (INT16) (gpWorldLevelData[gpTempSoldier->sGridNo].sHeight), gpTempSoldier->sGridNo, gpTempSoldier->inv[ HANDPOS ].usItem, gpTempSoldier->bLevel );
- return;
- }
- }
- if ( ArmBomb( &(gpTempSoldier->inv[HANDPOS]), ubExitValue ) )
- {
- gpTempSoldier->inv[ HANDPOS ].bTrap = __min( 10, ( EffectiveExplosive( gpTempSoldier ) / 20) + (EffectiveExpLevel( gpTempSoldier ) / 3) );
- // HACK IMMINENT!
- // value of 1 is stored in maps for SIDE of bomb owner... when we want to use IDs!
- // so we add 2 to all owner IDs passed through here and subtract 2 later
- gpTempSoldier->inv[HANDPOS].ubBombOwner = gpTempSoldier->ubID + 2;
- AddItemToPool( gsTempGridno, &(gpTempSoldier->inv[HANDPOS]), 1, gpTempSoldier->bLevel, WORLD_ITEM_ARMED_BOMB, 0 );
- DeleteObj( &(gpTempSoldier->inv[HANDPOS]) );
- }
- }
- }
- }
- BOOLEAN HandItemWorks( SOLDIERTYPE *pSoldier, INT8 bSlot )
- {
- BOOLEAN fItemJustBroke = FALSE, fItemWorks = TRUE;
- OBJECTTYPE * pObj;
-
- pObj = &( pSoldier->inv[ bSlot ] );
- // if the item can be damaged, than we must check that it's in good enough
- // shape to be usable, and doesn't break during use.
- // Exception: land mines. You can bury them broken, they just won't blow!
- if ( (Item[ pObj->usItem ].fFlags & ITEM_DAMAGEABLE) && (pObj->usItem != MINE) && (Item[ pObj->usItem ].usItemClass != IC_MEDKIT) && pObj->usItem != GAS_CAN )
- {
- // if it's still usable, check whether it breaks
- if ( pObj->bStatus[0] >= USABLE)
- {
- // if a dice roll is greater than the item's status
- if ( (Random(80) + 20) >= (UINT32) (pObj->bStatus[0] + 50) )
- {
- fItemJustBroke = TRUE;
- fItemWorks = FALSE;
- // item breaks, and becomes unusable... so its status is reduced
- // to somewhere between 1 and the 1 less than USABLE
- pObj->bStatus[0] = (INT8) ( 1 + Random( USABLE - 1 ) );
- }
- }
- else // it's already unusable
- {
- fItemWorks = FALSE;
- }
- if (!fItemWorks && pSoldier->bTeam == gbPlayerNum)
- {
- // merc says "This thing doesn't work!"
- TacticalCharacterDialogue( pSoldier, QUOTE_USELESS_ITEM );
- if (fItemJustBroke)
- {
- DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
- }
- }
- }
- if ( fItemWorks && bSlot == HANDPOS && Item[ pObj->usItem ].usItemClass == IC_GUN )
- {
- // are we using two guns at once?
- if ( Item[ pSoldier->inv[SECONDHANDPOS].usItem ].usItemClass == IC_GUN &&
- pSoldier->inv[SECONDHANDPOS].bGunStatus >= USABLE &&
- pSoldier->inv[SECONDHANDPOS].ubGunShotsLeft > 0)
- {
- // check the second gun for breakage, and if IT breaks, return false
- return( HandItemWorks( pSoldier, SECONDHANDPOS ) );
- }
- }
- return( fItemWorks );
- }
- void SetOffBoobyTrapInMapScreen( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject )
- {
- UINT8 ubPtsDmg = 0;
- // check if trapped item is an explosive, if so then up the amount of dmg
- if( ( pObject -> usItem == TNT )|| ( pObject -> usItem == RDX ) )
- {
- // for explosive
- ubPtsDmg = 0;
- }
- else
- {
- // normal mini grenade dmg
- ubPtsDmg = 0;
- }
- // injure the inventory character
- SoldierTakeDamage( pSoldier, 0, ubPtsDmg, ubPtsDmg, TAKE_DAMAGE_EXPLOSION, NOBODY, NOWHERE, 0, TRUE );
- // play the sound
- PlayJA2Sample( EXPLOSION_1, RATE_11025, BTNVOLUME, 1, MIDDLEPAN );
- }
- void SetOffBoobyTrap( ITEM_POOL * pItemPool )
- {
- if ( pItemPool )
- {
- INT16 sX, sY;
- sX = CenterX( pItemPool->sGridNo );
- sY = CenterY( pItemPool->sGridNo );
- IgniteExplosion( NOBODY, sX, sY, (INT16) (gpWorldLevelData[pItemPool->sGridNo].sHeight + pItemPool->bRenderZHeightAboveLevel), pItemPool->sGridNo, MINI_GRENADE, 0 );
- RemoveItemFromPool( pItemPool->sGridNo, pItemPool->iItemIndex, pItemPool->ubLevel );
- }
- }
- BOOLEAN ContinuePastBoobyTrap( SOLDIERTYPE * pSoldier, INT16 sGridNo, INT8 bLevel, INT32 iItemIndex, BOOLEAN fInStrategic, BOOLEAN *pfSaidQuote )
- {
- BOOLEAN fBoobyTrapKnowledge;
- INT8 bTrapDifficulty, bTrapDetectLevel;
- OBJECTTYPE * pObj;
- pObj = &(gWorldItems[ iItemIndex ].o);
- (*pfSaidQuote) = FALSE;
- if (pObj->bTrap > 0)
- {
- if (pSoldier->bTeam == gbPlayerNum)
- {
- // does the player know about this item?
- fBoobyTrapKnowledge = ((pObj->fFlags & OBJECT_KNOWN_TO_BE_TRAPPED) > 0);
- // blue flag stuff?
- if (!fBoobyTrapKnowledge)
- {
- bTrapDifficulty = pObj->bTrap;
- bTrapDetectLevel = CalcTrapDetectLevel( pSoldier, FALSE );
- if (bTrapDetectLevel >= bTrapDifficulty)
- {
- // spotted the trap!
- pObj->fFlags |= OBJECT_KNOWN_TO_BE_TRAPPED;
- fBoobyTrapKnowledge = TRUE;
- // Make him warn us:
- // Set things up..
- gpBoobyTrapSoldier = pSoldier;
- gpBoobyTrapItemPool = GetItemPoolForIndex( sGridNo, iItemIndex, pSoldier->bLevel );
- gsBoobyTrapGridNo = sGridNo;
- gbBoobyTrapLevel = pSoldier->bLevel;
- gfDisarmingBuriedBomb = FALSE;
- gbTrapDifficulty = bTrapDifficulty;
- // And make the call for the dialogue
- SetStopTimeQuoteCallback( BoobyTrapDialogueCallBack );
- TacticalCharacterDialogue( pSoldier, QUOTE_BOOBYTRAP_ITEM );
- (*pfSaidQuote) = TRUE;
- return( FALSE );
- }
- }
- gpBoobyTrapItemPool = GetItemPoolForIndex( sGridNo, iItemIndex, pSoldier->bLevel );
- if (fBoobyTrapKnowledge)
- {
- // have the computer ask us if we want to proceed
- gpBoobyTrapSoldier = pSoldier;
- gsBoobyTrapGridNo = sGridNo;
- gbBoobyTrapLevel = pSoldier->bLevel;
- gfDisarmingBuriedBomb = FALSE;
- gbTrapDifficulty = pObj->bTrap;
- if( fInStrategic )
- {
- DoMessageBox( MSG_BOX_BASIC_STYLE, TacticalStr[ DISARM_BOOBYTRAP_PROMPT ], MAP_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, BoobyTrapInMapScreenMessageBoxCallBack, NULL );
- }
- else
- {
- DoMessageBox( MSG_BOX_BASIC_STYLE, TacticalStr[ DISARM_BOOBYTRAP_PROMPT ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, BoobyTrapMessageBoxCallBack, NULL );
- }
- }
- else
- {
- // oops!
- SetOffBoobyTrap( gpBoobyTrapItemPool );
- }
- return( FALSE );
- }
- // else, enemies etc always know about boobytraps and are not affected by them
- }
- return( TRUE );
- }
- void BoobyTrapDialogueCallBack( void )
- {
- gfJustFoundBoobyTrap = TRUE;
- // now prompt the user...
- if( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN )
- {
- DoScreenIndependantMessageBox( TacticalStr[ DISARM_BOOBYTRAP_PROMPT ], ( UINT8 )MSG_BOX_FLAG_YESNO, BoobyTrapInMapScreenMessageBoxCallBack );
- }
- else
- {
- DoScreenIndependantMessageBox( TacticalStr[ DISARM_BOOBYTRAP_PROMPT ], ( UINT8 )MSG_BOX_FLAG_YESNO, BoobyTrapMessageBoxCallBack );
- }
- }
- void BoobyTrapMessageBoxCallBack( UINT8 ubExitValue )
- {
- if ( gfJustFoundBoobyTrap )
- {
- // NOW award for finding boobytrap
- // WISDOM GAIN: Detected a booby-trap
- StatChange( gpBoobyTrapSoldier, WISDOMAMT, (UINT16) (3 * gbTrapDifficulty), FALSE );
- // EXPLOSIVES GAIN: Detected a booby-trap
- StatChange( gpBoobyTrapSoldier, EXPLODEAMT, (UINT16) (3 * gbTrapDifficulty), FALSE );
- gfJustFoundBoobyTrap = FALSE;
- }
- if (ubExitValue == MSG_BOX_RETURN_YES)
- {
- INT32 iCheckResult;
- OBJECTTYPE Object;
- iCheckResult = SkillCheck( gpBoobyTrapSoldier, DISARM_TRAP_CHECK, 0 );
- if (iCheckResult >= 0)
- {
- // get the item
- memcpy( &Object, &(gWorldItems[ gpBoobyTrapItemPool->iItemIndex ].o), sizeof( OBJECTTYPE ) );
- // NB owner grossness... bombs 'owned' by the enemy are stored with side value 1 in
- // the map. So if we want to detect a bomb placed by the player, owner is > 1, and
- // owner - 2 gives the ID of the character who planted it
- if ( Object.ubBombOwner > 1 && ( (INT32)Object.ubBombOwner - 2 >= gTacticalStatus.Team[ OUR_TEAM ].bFirstID && Object.ubBombOwner - 2 <= gTacticalStatus.Team[ OUR_TEAM ].bLastID ) )
- {
- // our own bomb! no exp
- }
- else
- {
- // disarmed a boobytrap!
- StatChange( gpBoobyTrapSoldier, EXPLODEAMT, (UINT16) (6 * gbTrapDifficulty), FALSE );
- // have merc say this is good
- DoMercBattleSound( gpBoobyTrapSoldier, BATTLE_SOUND_COOL1 );
- }
- if (gfDisarmingBuriedBomb)
- {
- if (Object.usItem == SWITCH)
- {
- // give the player a remote trigger instead
- CreateItem( REMOTEBOMBTRIGGER, (INT8) (1 + Random( 9 )), &Object );
- }
- else if (Object.usItem == ACTION_ITEM && Object.bActionValue != ACTION_ITEM_BLOW_UP )
- {
- // give the player a detonator instead
- CreateItem( DETONATOR, (INT8) (1 + Random( 9 )), &Object );
- }
- else
- {
- // switch action item to the real item type
- CreateItem( Object.usBombItem, Object.bBombStatus, &Object );
- }
- // remove any blue flag graphic
- RemoveBlueFlag( gsBoobyTrapGridNo, gbBoobyTrapLevel );
- }
- else
- {
- Object.bTrap = 0;
- Object.fFlags &= ~( OBJECT_KNOWN_TO_BE_TRAPPED );
- }
- // place it in the guy's inventory/cursor
- if ( AutoPlaceObject( gpBoobyTrapSoldier, &Object, TRUE ) )
- {
- // remove it from the ground
- RemoveItemFromPool( gsBoobyTrapGridNo, gpBoobyTrapItemPool->iItemIndex, gbBoobyTrapLevel );
- }
- else
- {
- // make sure the item in the world is untrapped
- gWorldItems[ gpBoobyTrapItemPool->iItemIndex ].o.bTrap = 0;
- gWorldItems[ gpBoobyTrapItemPool->iItemIndex ].o.fFlags &= ~( OBJECT_KNOWN_TO_BE_TRAPPED );
- // ATE; If we failed to add to inventory, put failed one in our cursor...
- gfDontChargeAPsToPickup = TRUE;
- HandleAutoPlaceFail( gpBoobyTrapSoldier, gpBoobyTrapItemPool->iItemIndex, gsBoobyTrapGridNo );
- RemoveItemFromPool( gsBoobyTrapGridNo, gpBoobyTrapItemPool->iItemIndex, gbBoobyTrapLevel );
- }
- }
- else
- {
- // oops! trap goes off
- StatChange( gpBoobyTrapSoldier, EXPLODEAMT, (INT8) (3 * gbTrapDifficulty ), FROM_FAILURE );
- DoMercBattleSound( gpBoobyTrapSoldier, BATTLE_SOUND_CURSE1 );
- if (gfDisarmingBuriedBomb)
- {
- SetOffBombsInGridNo( gpBoobyTrapSoldier->ubID, gsBoobyTrapGridNo, TRUE, gbBoobyTrapLevel );
- }
- else
- {
- SetOffBoobyTrap( gpBoobyTrapItemPool );
- }
- }
- }
- else
- {
- if (gfDisarmingBuriedBomb)
- {
- DoMessageBox( MSG_BOX_BASIC_STYLE, TacticalStr[ REMOVE_BLUE_FLAG_PROMPT ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, RemoveBlueFlagDialogueCallBack, NULL );
- }
- // otherwise do nothing
- }
- }
- void BoobyTrapInMapScreenMessageBoxCallBack( UINT8 ubExitValue )
- {
- if ( gfJustFoundBoobyTrap )
- {
- // NOW award for finding boobytrap
- // WISDOM GAIN: Detected a booby-trap
- StatChange( gpBoobyTrapSoldier, WISDOMAMT, (UINT16) (3 * gbTrapDifficulty), FALSE );
- // EXPLOSIVES GAIN: Detected a booby-trap
- StatChange( gpBoobyTrapSoldier, EXPLODEAMT, (UINT16) (3 * gbTrapDifficulty), FALSE );
- gfJustFoundBoobyTrap = FALSE;
- }
- if (ubExitValue == MSG_BOX_RETURN_YES)
- {
- INT32 iCheckResult;
- OBJECTTYPE Object;
- iCheckResult = SkillCheck( gpBoobyTrapSoldier, DISARM_TRAP_CHECK, 0 );
- if (iCheckResult >= 0)
- {
- // disarmed a boobytrap!
- StatChange( gpBoobyTrapSoldier, EXPLODEAMT, (UINT16) (6 * gbTrapDifficulty), FALSE );
- // have merc say this is good
- DoMercBattleSound( gpBoobyTrapSoldier, BATTLE_SOUND_COOL1 );
- // get the item
- memcpy( &Object, gpItemPointer, sizeof( OBJECTTYPE ) );
- if (gfDisarmingBuriedBomb)
- {
- if (Object.usItem == SWITCH)
- {
- // give the player a remote trigger instead
- CreateItem( REMOTEBOMBTRIGGER, (INT8) (1 + Random( 9 )), &Object );
- }
- else if (Object.usItem == ACTION_ITEM && Object.bActionValue != ACTION_ITEM_BLOW_UP )
- {
- // give the player a detonator instead
- CreateItem( DETONATOR, (INT8) (1 + Random( 9 )), &Object );
- }
- else
- {
- // switch action item to the real item type
- CreateItem( Object.usBombItem, Object.bBombStatus, &Object );
- }
- }
- else
- {
- Object.bTrap = 0;
- Object.fFlags &= ~( OBJECT_KNOWN_TO_BE_TRAPPED );
- }
- MAPEndItemPointer( );
- // place it in the guy's inventory/cursor
- if ( !AutoPlaceObject( gpBoobyTrapSoldier, &Object, TRUE ) )
- {
- AutoPlaceObjectInInventoryStash( &Object );
- }
- HandleButtonStatesWhileMapInventoryActive( );
- }
- else
- {
- // oops! trap goes off
- StatChange( gpBoobyTrapSoldier, EXPLODEAMT, (INT8) (3 * gbTrapDifficulty ), FROM_FAILURE );
- DoMercBattleSound( gpBoobyTrapSoldier, BATTLE_SOUND_CURSE1 );
-
- if (gfDisarmingBuriedBomb)
- {
- SetOffBombsInGridNo( gpBoobyTrapSoldier->ubID, gsBoobyTrapGridNo, TRUE, gbBoobyTrapLevel );
- }
- else
- {
- SetOffBoobyTrap( gpBoobyTrapItemPool );
- }
- }
- }
- else
- {
- if (gfDisarmingBuriedBomb)
- {
- DoMessageBox( MSG_BOX_BASIC_STYLE, TacticalStr[ REMOVE_BLUE_FLAG_PROMPT ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, RemoveBlueFlagDialogueCallBack, NULL );
- }
- // otherwise do nothing
- }
- }
- void SwitchMessageBoxCallBack( UINT8 ubExitValue )
- {
- if ( ubExitValue == MSG_BOX_RETURN_YES )
- {
- // Message that switch is activated...
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[ 60 ] );
- SetOffBombsByFrequency( gpTempSoldier->ubID, bTempFrequency );
- }
- }
- BOOLEAN NearbyGroundSeemsWrong( SOLDIERTYPE * pSoldier, INT16 sGridNo, BOOLEAN fCheckAroundGridno, INT16 * psProblemGridNo )
- {
- INT16 sNextGridNo;
- // BOOLEAN fWorthChecking = FALSE, fProblemExists = FALSE, fDetectedProblem = FALSE;
- UINT8 ubDetectLevel, ubDirection;
- MAP_ELEMENT * pMapElement;
- UINT32 fCheckFlag;
- UINT32 uiWorldBombIndex;
- OBJECTTYPE * pObj;
- BOOLEAN fMining, fFoundMetal = FALSE;
- // ITEM_POOL * pItemPool;
- UINT8 ubMovementCost;
- ubDetectLevel = 0;
- if ( FindObj( pSoldier, METALDETECTOR ) != NO_SLOT )
- {
- fMining = TRUE;
- }
- else
- {
- fMining = FALSE;
- ubDetectLevel = CalcTrapDetectLevel( pSoldier, FALSE );
- /*
- if (pSoldier->bStealthMode)
- {
- ubDetectLevel++;
- }
- switch (pSoldier->usAnimState)
- {
- case CRAWLING:
- ubDetectLevel += 2;
- break;
- case SWATTING:
- ubDetectLevel++;
- break;
- default:
- break;
- }
- */
- }
- if (pSoldier->bSide == 0)
- {
- fCheckFlag = MAPELEMENT_PLAYER_MINE_PRESENT;
- }
- else
- {
- fCheckFlag = MAPELEMENT_ENEMY_MINE_PRESENT;
- }
- // check every tile around gridno for the presence of "nasty stuff"
- for (ubDirection = 0; ubDirection < 8; ubDirection++)
- {
- if ( fCheckAroundGridno )
- {
- // get the gridno of the next spot adjacent to lastGridno in that direction
- sNextGridNo = NewGridNo( sGridNo, (INT16) DirectionInc( (UINT8) ubDirection ) );
- // don't check directions that are impassable!
- ubMovementCost = gubWorldMovementCosts[ sNextGridNo ][ ubDirection ][ pSoldier->bLevel ];
- if ( IS_TRAVELCOST_DOOR( ubMovementCost ) )
- {
- ubMovementCost = DoorTravelCost( NULL, sNextGridNo, ubMovementCost, FALSE, NULL );
- }
- if ( ubMovementCost >= TRAVELCOST_BLOCKED)
- {
- continue;
- }
- }
- else
- {
- // we should just be checking the gridno
- sNextGridNo = sGridNo;
- ubDirection = 8; // don't loop
- }
- // if this sNextGridNo isn't out of bounds... but it never can be
- pMapElement = &(gpWorldLevelData[sNextGridNo]);
-
- if (pMapElement->uiFlags & fCheckFlag)
- {
- // already know there's a mine there
- continue;
- }
- // check for boobytraps
- for (uiWorldBombIndex = 0; uiWorldBombIndex < guiNumWorldBombs; uiWorldBombIndex++)
- {
- if (gWorldBombs[uiWorldBombIndex].fExists && gWorldItems[ gWorldBombs[uiWorldBombIndex].iItemIndex ].sGridNo == sNextGridNo)
- {
- pObj = &( gWorldItems[ gWorldBombs[uiWorldBombIndex].iItemIndex ].o );
- if ( pObj->bDetonatorType == BOMB_PRESSURE && !(pObj->fFlags & OBJECT_KNOWN_TO_BE_TRAPPED) && (!(pObj->fFlags & OBJECT_DISABLED_BOMB)) )
- {
- if ( fMining && pObj->bTrap <= 10 )
- {
- // add blue flag
- AddBlueFlag( sNextGridNo, pSoldier->bLevel );
- fFoundMetal = TRUE;
- break;
- }
- else if (ubDetectLevel >= pObj->bTrap)
- {
- if (pSoldier->uiStatusFlags & SOLDIER_PC )
- {
- // detected exposives buried nearby...
- StatChange( pSoldier, EXPLODEAMT, (UINT16) (pObj->bTrap), FALSE );
- // set item as known
- pObj->fFlags |= OBJECT_KNOWN_TO_BE_TRAPPED;
- }
- *psProblemGridNo = sNextGridNo;
- return( TRUE );
- }
- }
- }
- }
- /*
- // also check for metal items if using a metal detector
- if (fMining)
- {
- // add blue flags where we find metallic objects hidden
- GetItemPool( sNextGridNo, &pItemPool, pSoldier->bLevel );
- while( pItemPool )
- {
- if ( pItemPool->bVisible == BURIED || (pItemPool->bVisible != TRUE && gWorldItems[ pItemPool->iItemIndex ].o.bTrap > 0 ) )
- {
- pObj = &( gWorldItems[ pItemPool->iItemIndex ].o );
- if ( pObj->usItem == ACTION_ITEM && pObj-> )
- {
- switch( pObj->bActionValue )
- {
- case ACTION_ITEM_BLOW_UP:
- case ACTION_ITEM_LOCAL_ALARM:
- case ACTION_ITEM_GLOBAL_ALARM:
- // add blue flag
- AddBlueFlag( sNextGridNo, pSoldier->bLevel );
- fFoundMetal = TRUE;
- break;
- default:
- break;
- }
- }
- else if (Item[ pObj->usItem ].fFlags & ITEM_METAL)
- {
- // add blue flag
- AddBlueFlag( sNextGridNo, pSoldier->bLevel );
- fFoundMetal = TRUE;
- break;
- }
- }
- pItemPool = pItemPool->pNext;
- }
- }
- */
- }
- *psProblemGridNo = NOWHERE;
- if (fFoundMetal)
- {
- return( TRUE );
- }
- else
- {
- return( FALSE );
- }
- }
- void MineSpottedDialogueCallBack( void )
- {
- ITEM_POOL * pItemPool;
- // ATE: REALLY IMPORTANT - ALL CALLBACK ITEMS SHOULD UNLOCK
- gTacticalStatus.fLockItemLocators = FALSE;
- GetItemPool( gsBoobyTrapGridNo, &pItemPool, gbBoobyTrapLevel );
- guiPendingOverrideEvent = LU_BEGINUILOCK;
- // play a locator at the location of the mine
- SetItemPoolLocatorWithCallback( pItemPool, MineSpottedLocatorCallback );
- }
- void MineSpottedLocatorCallback( void )
- {
- guiPendingOverrideEvent = LU_ENDUILOCK;
- // now ask the player if he wants to place a blue flag.
- DoMessageBox( MSG_BOX_BASIC_STYLE, TacticalStr[ PLACE_BLUE_FLAG_PROMPT ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, MineSpottedMessageBoxCallBack, NULL );
- }
- void MineSpottedMessageBoxCallBack( UINT8 ubExitValue )
- {
- if (ubExitValue == MSG_BOX_RETURN_YES)
- {
- // place a blue flag where the mine was found
- AddBlueFlag( gsBoobyTrapGridNo, gbBoobyTrapLevel );
- }
- }
- void RemoveBlueFlagDialogueCallBack( UINT8 ubExitValue )
- {
- if (ubExitValue == MSG_BOX_RETURN_YES)
- {
- RemoveBlueFlag( gsBoobyTrapGridNo, gbBoobyTrapLevel );
- }
- }
- void AddBlueFlag( INT16 sGridNo ,INT8 bLevel )
- {
- LEVELNODE *pNode;
- ApplyMapChangesToMapTempFile( TRUE );
- gpWorldLevelData[ sGridNo ].uiFlags |= MAPELEMENT_PLAYER_MINE_PRESENT;
- pNode = AddStructToTail( sGridNo, BLUEFLAG_GRAPHIC );
- if ( pNode )
- {
- pNode->uiFlags |= LEVELNODE_SHOW_THROUGH;
- }
- ApplyMapChangesToMapTempFile( FALSE );
- RecompileLocalMovementCostsFromRadius( sGridNo, bLevel );
- SetRenderFlags(RENDER_FLAG_FULL);
- }
- void RemoveBlueFlag( INT16 sGridNo, INT8 bLevel )
- {
- ApplyMapChangesToMapTempFile( TRUE );
- gpWorldLevelData[sGridNo].uiFlags &= ~(MAPELEMENT_PLAYER_MINE_PRESENT);
- if ( bLevel == 0 )
- {
- RemoveStruct( sGridNo, BLUEFLAG_GRAPHIC );
- }
- else
- {
- RemoveOnRoof( sGridNo, BLUEFLAG_GRAPHIC );
- }
- ApplyMapChangesToMapTempFile( FALSE );
- RecompileLocalMovementCostsFromRadius( sGridNo, bLevel );
- SetRenderFlags(RENDER_FLAG_FULL);
- }
- void MakeNPCGrumpyForMinorOffense( SOLDIERTYPE * pSoldier, SOLDIERTYPE *pOffendingSoldier )
- {
- CancelAIAction( pSoldier, TRUE );
- switch( pSoldier->ubProfile )
- {
- case FREDO:
- case FRANZ:
- case HERVE:
- case PETER:
- case ALBERTO:
- case CARLO:
- case MANNY:
- case GABBY:
- case ARNIE:
- case HOWARD:
- case SAM:
- case FATHER:
- case TINA:
- case ARMAND:
- case WALTER:
- gMercProfiles[ pSoldier->ubProfile ].ubMiscFlags3 |= PROFILE_MISC_FLAG3_NPC_PISSED_OFF;
- TriggerNPCWithIHateYouQuote( pSoldier->ubProfile );
- break;
- default:
- // trigger NPCs with quote if available
- AddToShouldBecomeHostileOrSayQuoteList( pSoldier->ubID );
- break;
- }
- if ( pOffendingSoldier )
- {
- pSoldier->bNextAction = AI_ACTION_CHANGE_FACING;
- pSoldier->usNextActionData = atan8( pSoldier->sX, pSoldier->sY, pOffendingSoldier->sX, pOffendingSoldier->sY );
- }
- }
- void TestPotentialOwner( SOLDIERTYPE * pSoldier )
- {
- if ( pSoldier->bActive && pSoldier->bInSector && pSoldier->bLife >= OKLIFE )
- {
- if ( SoldierToSoldierLineOfSightTest( pSoldier, gpTempSoldier, (UINT8) DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, 0, gpTempSoldier->sGridNo, gpTempSoldier->bLevel ), TRUE ) )
- {
- MakeNPCGrumpyForMinorOffense( pSoldier, gpTempSoldier );
- }
- }
- }
- void CheckForPickedOwnership( void )
- {
- ITEM_POOL * pItemPool;
- UINT8 ubProfile;
- UINT8 ubCivGroup;
- SOLDIERTYPE * pSoldier;
- UINT8 ubLoop;
- // LOOP THROUGH LIST TO FIND NODE WE WANT
- GetItemPool( gsTempGridno, &pItemPool, gpTempSoldier->bLevel );
- while( pItemPool )
- {
- if ( gWorldItems[ pItemPool->iItemIndex ].o.usItem == OWNERSHIP )
- {
- if ( gWorldItems[ pItemPool->iItemIndex ].o.ubOwnerProfile != NO_PROFILE )
- {
- ubProfile = gWorldItems[ pItemPool->iItemIndex ].o.ubOwnerProfile;
- pSoldier = FindSoldierByProfileID( ubProfile, FALSE );
- if ( pSoldier )
- {
- TestPotentialOwner( pSoldier );
- }
- }
- if ( gWorldItems[ pItemPool->iItemIndex ].o.ubOwnerCivGroup != NON_CIV_GROUP )
- {
- ubCivGroup = gWorldItems[ pItemPool->iItemIndex ].o.ubOwnerCivGroup;
- if ( ubCivGroup == HICKS_CIV_GROUP && CheckFact( FACT_HICKS_MARRIED_PLAYER_MERC, 0 ) )
- {
- // skip because hicks appeased
- pItemPool = pItemPool->pNext;
- continue;
- }
- for ( ubLoop = gTacticalStatus.Team[ CIV_TEAM ].bFirstID; ubLoop <= gTacticalStatus.Team[ CIV_TEAM ].bLastID; ubLoop++ )
- {
- pSoldier = MercPtrs[ ubLoop ];
- if ( pSoldier && pSoldier->ubCivilianGroup == ubCivGroup )
- {
- TestPotentialOwner( pSoldier );
- }
- }
- }
- }
- pItemPool = pItemPool->pNext;
- }
- }
- void LoopLevelNodeForItemGlowFlag( LEVELNODE *pNode, INT16 sGridNo, UINT8 ubLevel, BOOLEAN fOn )
- {
- while ( pNode != NULL )
- {
- if ( pNode->uiFlags & LEVELNODE_ITEM )
- {
- if ( fOn )
- {
- pNode->uiFlags |= LEVELNODE_DYNAMIC;
- }
- else
- {
- pNode->uiFlags &= (~LEVELNODE_DYNAMIC);
- }
- }
- pNode = pNode->pNext;
- }
- }
- void HandleItemGlowFlag( INT16 sGridNo, UINT8 ubLevel, BOOLEAN fOn )
- {
- LEVELNODE *pNode;
- if ( ubLevel == 0 )
- {
- pNode = gpWorldLevelData[ sGridNo ].pStructHead;
- LoopLevelNodeForItemGlowFlag( pNode, sGridNo, ubLevel, fOn );
- }
- else
- {
- pNode = gpWorldLevelData[ sGridNo ].pOnRoofHead;
- LoopLevelNodeForItemGlowFlag( pNode, sGridNo, ubLevel, fOn );
- }
- }
- void ToggleItemGlow( BOOLEAN fOn )
- {
- UINT32 cnt;
- for ( cnt = 0; cnt < WORLD_MAX; cnt++ )
- {
- HandleItemGlowFlag( ( INT16 )cnt, 0, fOn );
- HandleItemGlowFlag( ( INT16 )cnt, 1, fOn );
- }
- if ( !fOn )
- {
- gGameSettings.fOptions[ TOPTION_GLOW_ITEMS ] = FALSE;
- }
- else
- {
- gGameSettings.fOptions[ TOPTION_GLOW_ITEMS ] = TRUE;
- }
- SetRenderFlags(RENDER_FLAG_FULL);
- }
- BOOLEAN ContinuePastBoobyTrapInMapScreen( OBJECTTYPE *pObject, SOLDIERTYPE *pSoldier )
- {
- BOOLEAN fBoobyTrapKnowledge;
- INT8 bTrapDifficulty, bTrapDetectLevel;
- if (pObject->bTrap > 0)
- {
- if (pSoldier->bTeam == gbPlayerNum)
- {
- // does the player know about this item?
- fBoobyTrapKnowledge = ((pObject->fFlags & OBJECT_KNOWN_TO_BE_TRAPPED) > 0);
- // blue flag stuff?
- if (!fBoobyTrapKnowledge)
- {
- bTrapDifficulty = pObject->bTrap;
- bTrapDetectLevel = CalcTrapDetectLevel( pSoldier, FALSE );
- if (bTrapDetectLevel >= bTrapDifficulty)
- {
- // spotted the trap!
- pObject->fFlags |= OBJECT_KNOWN_TO_BE_TRAPPED;
- fBoobyTrapKnowledge = TRUE;
- // Make him warn us:
- gpBoobyTrapSoldier = pSoldier;
- // And make the call for the dialogue
- SetStopTimeQuoteCallback( BoobyTrapDialogueCallBack );
- TacticalCharacterDialogue( pSoldier, QUOTE_BOOBYTRAP_ITEM );
- return( FALSE );
- }
- }
- if (fBoobyTrapKnowledge)
- {
- // have the computer ask us if we want to proceed
- gpBoobyTrapSoldier = pSoldier;
- gbTrapDifficulty = pObject->bTrap;
- DoMessageBox( MSG_BOX_BASIC_STYLE, TacticalStr[ DISARM_BOOBYTRAP_PROMPT ], MAP_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, BoobyTrapInMapScreenMessageBoxCallBack, NULL );
- }
- else
- {
- // oops!
- SetOffBoobyTrapInMapScreen( pSoldier, pObject );
- }
- return( FALSE );
- }
- // else, enemies etc always know about boobytraps and are not affected by them
- }
- return( TRUE );
- }
- // Well, clears all item pools
- void ClearAllItemPools( )
- {
- UINT32 cnt;
- for ( cnt = 0; cnt < WORLD_MAX; cnt++ )
- {
- RemoveItemPool( (INT16)cnt, 0 );
- RemoveItemPool( (INT16)cnt, 1 );
- }
- }
- // Refresh item pools
- void RefreshItemPools( WORLDITEM * pItemList, INT32 iNumberOfItems )
- {
- ClearAllItemPools( );
- RefreshWorldItemsIntoItemPools( pItemList, iNumberOfItems );
- }
- INT16 FindNearestAvailableGridNoForItem( INT16 sSweetGridNo, INT8 ubRadius )
- {
- INT16 sTop, sBottom;
- INT16 sLeft, sRight;
- INT16 cnt1, cnt2, cnt3;
- INT16 sGridNo;
- INT32 uiRange, uiLowestRange = 999999;
- INT16 sLowestGridNo=0;
- INT32 leftmost;
- BOOLEAN fFound = FALSE;
- SOLDIERTYPE soldier;
- UINT8 ubSaveNPCAPBudget;
- UINT8 ubSaveNPCDistLimit;
- BOOLEAN fSetDirection = FALSE;
- cnt3 = 0;
- //Save AI pathing vars. changing the distlimit restricts how
- //far away the pathing will consider.
- ubSaveNPCAPBudget = gubNPCAPBudget;
- ubSaveNPCDistLimit = gubNPCDistLimit;
- gubNPCAPBudget = 0;
- gubNPCDistLimit = ubRadius;
- //create dummy soldier, and use the pathing to determine which nearby slots are
- //reachable.
- memset( &soldier, 0, sizeof( SOLDIERTYPE ) );
- soldier.bTeam = 1;
- soldier.sGridNo = sSweetGridNo;
- sTop = ubRadius;
- sBottom = -ubRadius;
- sLeft = - ubRadius;
- sRight = ubRadius;
- //clear the mapelements of potential residue MAPELEMENT_REACHABLE flags
- //in the square region.
- for( cnt1 = sBottom; cnt1 <= sTop; cnt1++ )
- {
- for( cnt2 = sLeft; cnt2 <= sRight; cnt2++ )
- {
- sGridNo = sSweetGridNo + (WORLD_COLS * cnt1) + cnt2;
- if ( sGridNo >=0 && sGridNo < WORLD_MAX )
- {
- gpWorldLevelData[ sGridNo ].uiFlags &= (~MAPELEMENT_REACHABLE);
- }
- }
- }
- //Now, find out which of these gridnos are reachable
- //(use the fake soldier and the pathing settings)
- FindBestPath( &soldier, NOWHERE, 0, WALKING, COPYREACHABLE, 0 );
-
- uiLowestRange = 999999;
- for( cnt1 = sBottom; cnt1 <= sTop; cnt1++ )
- {
- leftmost = ( ( sSweetGridNo + ( WORLD_COLS * cnt1 ) )/ WORLD_COLS ) * WORLD_COLS;
- for( cnt2 = sLeft; cnt2 <= sRight; cnt2++ )
- {
- sGridNo = sSweetGridNo + ( WORLD_COLS * cnt1 ) + cnt2;
- if ( sGridNo >=0 && sGridNo < WORLD_MAX && sGridNo >= leftmost && sGridNo < ( leftmost + WORLD_COLS ) &&
- gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_REACHABLE )
- {
- // Go on sweet stop
- if ( NewOKDestination( &soldier, sGridNo, TRUE, soldier.bLevel ) )
- {
- uiRange = GetRangeInCellCoordsFromGridNoDiff( sSweetGridNo, sGridNo );
- if ( uiRange < uiLowestRange )
- {
- sLowestGridNo = sGridNo;
- uiLowestRange = uiRange;
- fFound = TRUE;
- }
- }
- }
- }
- }
- gubNPCAPBudget = ubSaveNPCAPBudget;
- gubNPCDistLimit = ubSaveNPCDistLimit;
- if ( fFound )
- {
- return sLowestGridNo;
- }
- return NOWHERE;
- }
- BOOLEAN CanPlayerUseRocketRifle( SOLDIERTYPE *pSoldier, BOOLEAN fDisplay )
- {
- if ( pSoldier->inv[ pSoldier->ubAttackingHand ].usItem == ROCKET_RIFLE || pSoldier->inv[ pSoldier->ubAttackingHand ].usItem == AUTO_ROCKET_RIFLE )
- {
- // check imprint ID
- // NB not-imprinted value is NO_PROFILE
- // imprinted value is profile for mercs & NPCs and NO_PROFILE + 1 for generic dudes
- if (pSoldier->ubProfile != NO_PROFILE)
- {
- if ( pSoldier->inv[ pSoldier->ubAttackingHand ].ubImprintID != pSoldier->ubProfile )
- {
- // NOT a virgin gun...
- if ( pSoldier->inv[ pSoldier->ubAttackingHand ].ubImprintID != NO_PROFILE )
- {
- // access denied!
- if (pSoldier->bTeam == gbPlayerNum)
- {
- PlayJA2Sample( RG_ID_INVALID, RATE_11025, HIGHVOLUME, 1, MIDDLE );
-
- if ( fDisplay )
- {
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, L"\"%s\"", TacticalStr[ GUN_NOGOOD_FINGERPRINT ] );
- }
- }
- return( FALSE );
- }
- }
- }
- }
- return( TRUE );
- }
|