| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179 |
- /*
- ** Command & Conquer Generals Zero Hour(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- ////////////////////////////////////////////////////////////////////////////////
- // //
- // (c) 2001-2003 Electronic Arts Inc. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- // CommandXlat.cpp
- // Translate raw input events into tactical commands
- // Author: Michael S. Booth, February 2001
- #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
- #include "stdlib.h" // VC++ wants this here, or gives compile error...
- #include "Common/AudioAffect.h"
- #include "Common/ActionManager.h"
- #include "Common/GameAudio.h"
- #include "Common/GameEngine.h"
- #include "Common/GameType.h"
- #include "Common/GlobalData.h"
- #include "Common/MessageStream.h"
- #include "Common/MiscAudio.h"
- #include "Common/MultiplayerSettings.h"
- #include "Common/PerfTimer.h"
- #include "Common/Player.h"
- #include "Common/PlayerList.h"
- #include "Common/PlayerTemplate.h"
- #include "Common/Radar.h"
- #include "Common/Recorder.h"
- #include "Common/SpecialPower.h"
- #include "Common/StatsCollector.h"
- #include "Common/ThingTemplate.h"
- #include "Common/GameLOD.h"
- #include "GameClient/InGameUI.h"
- #include "GameClient/CommandXlat.h"
- #include "GameClient/DebugDisplay.h"
- #include "GameClient/Drawable.h"
- #include "GameClient/GameClient.h"
- #include "GameClient/GameWindowManager.h"
- #include "GameClient/GameText.h"
- #include "GameClient/ParticleSys.h"
- #include "GameClient/GUICallbacks.h"
- #include "GameClient/Shell.h"
- #include "GameClient/ControlBar.h"
- #include "GameClient/SelectionInfo.h"
- #include "GameClient/SelectionXlat.h"
- #include "GameLogic/Module/AIUpdate.h"
- #include "GameLogic/ExperienceTracker.h"
- #include "GameLogic/GameLogic.h"
- #include "GameLogic/Module/BodyModule.h"
- #include "GameLogic/Object.h"
- #include "GameLogic/PartitionManager.h"
- #include "GameLogic/ScriptEngine.h"
- #include "GameLogic/TerrainLogic.h"
- #include "GameLogic/GhostObject.h"
- #include "GameLogic/Weapon.h"
- #include "GameLogic/Module/SpawnBehavior.h"
- #include "GameLogic/Module/SpecialPowerModule.h"
- #include "Common/ThingFactory.h"
- #include "GameLogic/Module/ContainModule.h"
- #include "GameNetwork/NetworkInterface.h"
- #include "GameNetwork/GameInfo.h"
- #include "GameNetwork/GameSpyOverlay.h"
- #include "GameNetwork/GameSpy/BuddyThread.h"
- #ifdef _INTERNAL
- // for occasional debugging...
- //#pragma optimize("", off)
- //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
- #endif
- #define dont_ALLOW_ALT_F4
- #if defined(_DEBUG) || defined(_INTERNAL)
- /*non-static*/ Real TheSkateDistOverride = 0.0f;
- void countObjects(Object *obj, void *userData)
- {
- Int *numObjects = (Int *)userData;
- if (!numObjects || !obj)
- return;
- DEBUG_LOG(("Looking at obj %d (%s) - isEffectivelyDead()==%d, isDestroyed==%d, numObjects==%d\n",
- obj->getID(), obj->getTemplate()->getName().str(), obj->isEffectivelyDead(), obj->isDestroyed(), *numObjects));
- if (!obj->isEffectivelyDead() && !obj->isDestroyed() && !obj->isKindOf(KINDOF_INERT))
- ++(*numObjects);
- }
- void printObjects(Object *obj, void *userData)
- {
- if (!obj)
- return;
- Bool isDead = obj->isEffectivelyDead() || obj->isDestroyed();
- Bool isInert = obj->isKindOf(KINDOF_INERT);
- AsciiString statusStr = (isDead)?"Dead":(isInert)?"Inert":"Living";
- AsciiString line;
- if (obj->getName().isEmpty())
- line.format(" Obj#%d %s - (%g,%g) %s", obj->getID(), obj->getTemplate()->getName().str(),
- obj->getPosition()->x, obj->getPosition()->y, statusStr.str());
- else
- line.format(" Obj#%d %s (%s) - (%g,%g) %s", obj->getID(), obj->getTemplate()->getName().str(),
- obj->getName().str(), obj->getPosition()->x, obj->getPosition()->y, statusStr.str());
- TheScriptEngine->AppendDebugMessage(line, FALSE);
- }
- #endif
- static Bool isSystemMessage( const GameMessage *msg );
- enum{ DROPPED_MAX_PARTICLE_COUNT = 1000};
- static Bool canSelectionSalvage( const Object *targetObj)
- {
- if (!targetObj) {
- return FALSE;
- }
- if (!targetObj->isSalvageCrate()) {
- return FALSE;
- }
- const DrawableList *drawList = TheInGameUI->getAllSelectedDrawables();
- for (DrawableListCIt cit = drawList->begin(); cit != drawList->end(); ++cit)
- {
- Drawable *draw = *cit;
- if (!draw)
- {
- continue;
- }
-
- Object *obj = draw->getObject();
- if (!obj)
- {
- continue;
- }
- if (obj->isKindOf(KINDOF_SALVAGER)) {
- return TRUE;
- }
- }
- return FALSE;
- }
- //-------------------------------------------------------------------------------------------------
- static CanAttackResult canObjectForceAttack( Object *obj, const Object *victim, const Coord3D *pos )
- {
- CanAttackResult result;
- result = obj->isAbleToAttack() ? ATTACKRESULT_POSSIBLE : ATTACKRESULT_NOT_POSSIBLE;
- if( result == ATTACKRESULT_NOT_POSSIBLE )
- {
- return ATTACKRESULT_NOT_POSSIBLE;
- }
-
- if (victim)
- {
- result = obj->getAbleToAttackSpecificObject(ATTACK_NEW_TARGET_FORCED, victim, CMD_FROM_PLAYER );
- //Special case -- objects with spawn weapons have to do different checks. Stinger site with stinger soldiers is
- //the catalyst example.
- if ( obj->isKindOf( KINDOF_SPAWNS_ARE_THE_WEAPONS ) )
- {
- if( result != ATTACKRESULT_POSSIBLE && result != ATTACKRESULT_POSSIBLE_AFTER_MOVING )
- {
- SpawnBehaviorInterface *spawnInterface = obj->getSpawnBehaviorInterface();
- if( spawnInterface )
- {
- //We found the spawn interface, now get the closest slave to the target.
- Object *slave = spawnInterface->getClosestSlave( victim->getPosition() );
- if( slave )
- {
- result = slave->getAbleToAttackSpecificObject( ATTACK_NEW_TARGET_FORCED, victim, CMD_FROM_PLAYER );
- }
- }
- }
- else // oh dear me. The wierd case of a garrisoncontainer being a KINDOF_SPAWNS_ARE_THE_WEAPONS... the AmericaBuildingFirebase
- {
- ContainModuleInterface *contain = obj->getContain();
- if ( contain )
- {
- Object *rider = contain->getClosestRider( victim->getPosition() );
- if ( rider )
- {
- result = rider->getAbleToAttackSpecificObject( ATTACK_NEW_TARGET_FORCED, victim, CMD_FROM_PLAYER );
- if( result != ATTACKRESULT_NOT_POSSIBLE )
- return result;
- }
- }
- }
- } // end if spawnsRweapons
-
- return result;
- }
- else
- {
- //Almost every combat unit can force attack a position. The exceptions include stationary units
- //that try to force attack in a location beyond their reach (range, LOS, etc).
- if( pos )
- {
- Object *testObj = obj;
- if( obj->isKindOf( KINDOF_IMMOBILE ) || obj->isKindOf( KINDOF_SPAWNS_ARE_THE_WEAPONS ) )
- {
- SpawnBehaviorInterface *spawnInterface = obj->getSpawnBehaviorInterface();
- if( spawnInterface )
- {
- //We found the spawn interface, now get the closest slave to the target.
- Object *slave = spawnInterface->getClosestSlave( pos );
- if( slave )
- {
- testObj = slave;
- }
- }
- else
- {
- result = obj->getAbleToUseWeaponAgainstTarget( ATTACK_NEW_TARGET, NULL, pos, CMD_FROM_PLAYER );
- if( result != ATTACKRESULT_POSSIBLE ) // oh dear me. The wierd case of a garrisoncontainer being a KINDOF_SPAWNS_ARE_THE_WEAPONS... the AmericaBuildingFirebase
- {
- ContainModuleInterface *contain = obj->getContain();
- if ( contain )
- {
- Object *rider = contain->getClosestRider( pos );
- if ( rider )
- testObj = rider;
- }
- }
- }
- }
- //Now evaluate the testObj again to see if it is capable of force attacking the pos.
- result = testObj->getAbleToUseWeaponAgainstTarget( ATTACK_NEW_TARGET, NULL, pos, CMD_FROM_PLAYER );
- return result;
- }
- }
- return ATTACKRESULT_NOT_POSSIBLE;
- }
- //-------------------------------------------------------------------------------------------------
- static CanAttackResult canAnyForceAttack(const DrawableList *allSelected, const Object *victim, const Coord3D *pos )
- {
- // check to make sure that allSelected can attack obj.
- for (DrawableListCIt cit = allSelected->begin(); cit != allSelected->end(); ++cit)
- {
- Drawable *draw = *cit;
- if (!draw)
- {
- continue;
- }
-
- Object *obj = draw->getObject();
- if (!obj)
- {
- continue;
- }
- return canObjectForceAttack( obj, victim, pos );
- }
- return ATTACKRESULT_NOT_POSSIBLE;
- }
- //-------------------------------------------------------------------------------------------------
- void pickAndPlayUnitVoiceResponse( const DrawableList *list, GameMessage::Type msgType, PickAndPlayInfo *info )
- {
- if (!list)
- {
- return;
- }
- const AudioEventRTS* soundToPlayPtr = NULL;
- Object *objectWithSound = NULL;
- Bool skip = false;
- Object *target = NULL;
- if( info && info->m_drawTarget )
- {
- target = info->m_drawTarget->getObject();
- }
-
- //Now, loop through all the drawables (even if you find a match on the first.
- //The innards are responsible for "upgrading" a sound that is played based on
- //priorities. For example, the voice move or voice crush. Voice move gets set
- //when we have a null event -- but if any of the units can crush the specified
- //target, then it changes to VoiceCrush.
- for( DrawableListCIt it = list->begin(); it != list->end(); ++it )
- {
- Object *obj = (*it)->getObject();
- if (obj->isKindOf( KINDOF_IGNORED_IN_GUI ))
- continue;
- // Use the object instead of the drawable to get the thing template from. This way, we get the
- // sounds even if the thing is disguised as something else. (Ala bomb truck.)
- const ThingTemplate *templ = obj->getTemplate();
- if (!templ)
- {
- return;
- }
- switch (msgType)
- {
- case GameMessage::MSG_DOCK:
- soundToPlayPtr = templ->getPerUnitSound("VoiceSupply");
- objectWithSound = obj;
- skip = true;
- break;
- case GameMessage::MSG_SELECT_TEAM0:
- case GameMessage::MSG_SELECT_TEAM1:
- case GameMessage::MSG_SELECT_TEAM2:
- case GameMessage::MSG_SELECT_TEAM3:
- case GameMessage::MSG_SELECT_TEAM4:
- case GameMessage::MSG_SELECT_TEAM5:
- case GameMessage::MSG_SELECT_TEAM6:
- case GameMessage::MSG_SELECT_TEAM7:
- case GameMessage::MSG_SELECT_TEAM8:
- case GameMessage::MSG_SELECT_TEAM9:
- case GameMessage::MSG_CREATE_SELECTED_GROUP:
- soundToPlayPtr = templ->getVoiceSelect();
- objectWithSound = obj;
- skip = true;
- break;
- case GameMessage::MSG_EVACUATE:
- soundToPlayPtr = templ->getPerUnitSound( "VoiceUnload" );
- objectWithSound = obj;
- skip = true;
- break;
- case GameMessage::MSG_DO_REPAIR:
- soundToPlayPtr = templ->getPerUnitSound( "VoiceRepair" );
- objectWithSound = obj;
- skip = true;
- break;
- #ifdef ALLOW_SURRENDER
- case GameMessage::MSG_PICK_UP_PRISONER:
- soundToPlayPtr = templ->getPerUnitSound( "VoicePickup" );
- objectWithSound = obj;
- skip = true;
- break;
- #endif
- case GameMessage::MSG_COMBATDROP_AT_LOCATION:
- case GameMessage::MSG_COMBATDROP_AT_OBJECT:
- soundToPlayPtr = templ->getPerUnitSound( "VoiceCombatDrop" );
- objectWithSound = obj;
- skip = true;
- break;
- case GameMessage::MSG_ENTER:
- if( target && target->isKindOf( KINDOF_HEAL_PAD ) )
- {
- soundToPlayPtr = templ->getPerUnitSound( "VoiceGetHealed" );
- }
- else if( target && target->isKindOf( KINDOF_STRUCTURE ) )
- {
- if( obj->getRelationship( target ) == ENEMIES )
- {
- //Saboteurs
- soundToPlayPtr = templ->getPerUnitSound( "VoiceEnterHostile" );
- }
- else
- {
- soundToPlayPtr = templ->getPerUnitSound( "VoiceGarrison" );
- }
- }
- // order matters: we want to know if I consider it to be an ally, not vice versa
- else if( target && obj->getRelationship(target) != ALLIES )
- {
- soundToPlayPtr = templ->getPerUnitSound( "VoiceEnterHostile" );
- }
- else
- {
- soundToPlayPtr = templ->getPerUnitSound( "VoiceEnter" );
- }
- objectWithSound = obj;
- skip = true;
- break;
-
- case GameMessage::MSG_DO_MOVETO:
- case GameMessage::MSG_DO_ATTACKMOVETO:
- case GameMessage::MSG_GET_REPAIRED:
- case GameMessage::MSG_GET_HEALED:
- case GameMessage::MSG_DO_SALVAGE:
- {
- AIUpdateInterface *ai = obj->getAI();
- if( ai )
- {
- //This flag determines if the object has started moving yet... if not
- //it's a good initial check.
- Bool isEffectivelyMoving = ai->isMoving() || ai->isWaitingForPath();
- if( TheInGameUI->isInWaypointMode() )
- {
- if( isEffectivelyMoving )
- {
- //Don't want to play the sound unless he's not moving!
- continue;
- }
- }
- //Default to voice move (it'll be selected if we can't find a crush case as we iterate
- //through the rest of the drawables)
- if( !soundToPlayPtr )
- {
- soundToPlayPtr = templ->getVoiceMove();
- objectWithSound = obj;
- }
- if( TheInGameUI->isInForceMoveToMode() && target )
- {
- if( obj->canCrushOrSquish( target ) )
- {
- //Change it to voice crush because we are intentionally trying to crush this!
- soundToPlayPtr = templ->getPerUnitSound( "VoiceCrush" );
- objectWithSound = obj;
- skip = true;
- }
- }
- if (msgType == GameMessage::MSG_DO_SALVAGE)
- {
- const AudioEventRTS *tempSound = templ->getPerUnitSound( "VoiceSalvage" );
- if (TheAudio->isValidAudioEvent(tempSound))
- {
- soundToPlayPtr = tempSound;
- objectWithSound = obj;
- skip = true;
- }
- }
- // Special case for GLA worker to use a different set of move voices when he has received the worker shoes upgrade
- Player *player = obj->getControllingPlayer();
- static const UpgradeTemplate *workerShoeTemplate = TheUpgradeCenter->findUpgrade( "Upgrade_GLAWorkerShoes" );
- if (player && player->hasUpgradeComplete(workerShoeTemplate))
- {
- if (obj->isKindOf(KINDOF_INFANTRY) && obj->isKindOf(KINDOF_DOZER) && obj->isKindOf(KINDOF_HARVESTER)) // Only Workers fit all 3
- {
- soundToPlayPtr = templ->getPerUnitSound( "VoiceMoveUpgraded" );
- objectWithSound = obj;
- skip = true;
- }
- }
- }
- break;
- }
- case GameMessage::MSG_RESUME_CONSTRUCTION:
- case GameMessage::MSG_DOZER_CONSTRUCT:
- case GameMessage::MSG_DOZER_CONSTRUCT_LINE:
- {
- soundToPlayPtr = templ->getPerUnitSound( "VoiceBuildResponse" );
- objectWithSound = obj;
- skip = true;
- break;
- }
- case GameMessage::MSG_DO_FORCE_ATTACK_GROUND:
- {
- soundToPlayPtr = templ->getPerUnitSound( "VoiceBombard" );
- objectWithSound = obj;
- skip = true;
- if (TheAudio->isValidAudioEvent(soundToPlayPtr)) {
- break;
- } else {
- // clear out the sound to play, and drop into the attack object logic.
- soundToPlayPtr = NULL;
- }
- }
-
- case GameMessage::MSG_SWITCH_WEAPONS:
- {
- if( info && info->m_weaponSlot )
- {
- switch( *info->m_weaponSlot )
- {
- case PRIMARY_WEAPON:
- soundToPlayPtr = templ->getPerUnitSound( "VoicePrimaryWeaponMode" );
- break;
- case SECONDARY_WEAPON:
- soundToPlayPtr = templ->getPerUnitSound( "VoiceSecondaryWeaponMode" );
- break;
- case TERTIARY_WEAPON:
- soundToPlayPtr = templ->getPerUnitSound( "VoiceTertiaryWeaponMode" );
- break;
- }
- objectWithSound = obj;
- skip = true;
- }
- break;
- }
-
- case GameMessage::MSG_DO_FORCE_ATTACK_OBJECT:
- case GameMessage::MSG_DO_ATTACK_OBJECT:
- case GameMessage::MSG_DO_WEAPON_AT_OBJECT:
- {
- if( !soundToPlayPtr )
- {
- //Low priority sounds -- only do this if uninitialized.
- if( info && info->m_air )
- soundToPlayPtr = templ->getVoiceAttackAir();
- else
- soundToPlayPtr = templ->getVoiceAttack();
- objectWithSound = obj;
- }
- //Look for a specialty weapon fired via command button!
- Bool specialtyWeapon = FALSE;
- if( msgType == GameMessage::MSG_DO_WEAPON_AT_OBJECT )
- {
- specialtyWeapon = TRUE;
- }
- Weapon *weapon = obj->getCurrentWeapon();
- if( info && info->m_weaponSlot )
- {
- weapon = obj->getWeaponInWeaponSlot( *info->m_weaponSlot );
- }
- if( weapon )
- {
- switch( weapon->getDamageType() )
- {
- // this stays, even if ALLOW_SURRENDER is not defed, since flashbangs still use 'em
- case DAMAGE_SURRENDER:
- if( target && target->isKindOf( KINDOF_STRUCTURE ) )
- {
- //We are attempting to take over a building with rangers and flashbangs!
- soundToPlayPtr = templ->getPerUnitSound( "VoiceClearBuilding" );
- }
- else
- {
- //Special for subdue attacks.
- soundToPlayPtr = templ->getPerUnitSound( "VoiceSubdue" );
- }
- objectWithSound = obj;
- skip = true;
- break;
- case DAMAGE_DISARM:
- //Special for mine clearing attacks.
- soundToPlayPtr = templ->getPerUnitSound( "VoiceDisarm" );
- objectWithSound = obj;
- skip = true;
- break;
- case DAMAGE_KILLPILOT:
- if( specialtyWeapon )
- {
- //Special for sniping vehicle pilots.
- soundToPlayPtr = templ->getPerUnitSound( "VoiceSnipePilot" );
- objectWithSound = obj;
- skip = true;
- }
- break;
- case DAMAGE_MELEE:
- if( specialtyWeapon )
- {
- //Special for stabbing
- soundToPlayPtr = templ->getPerUnitSound( "VoiceMelee" );
- objectWithSound = obj;
- skip = true;
- }
- break;
- }
- }
- break;
- }
-
- case GameMessage::MSG_DO_WEAPON_AT_LOCATION:
- {
- if( !soundToPlayPtr )
- {
- //Low priority sounds -- only do this if uninitialized.
- if( info && info->m_air )
- soundToPlayPtr = templ->getVoiceAttackAir();
- else
- soundToPlayPtr = templ->getVoiceAttack();
- objectWithSound = obj;
- }
- //Check for possibility of a higher priority sound!
- Weapon *weapon = obj->getCurrentWeapon();
- if( info && info->m_weaponSlot )
- {
- weapon = obj->getWeaponInWeaponSlot( *info->m_weaponSlot );
- }
- if( weapon )
- {
- switch( weapon->getDamageType() )
- {
- // this stays, even if ALLOW_SURRENDER is not defed, since flashbangs still use 'em
- case DAMAGE_SURRENDER:
- break;
- case DAMAGE_DISARM:
- //Special for mine clearing attacks.
- soundToPlayPtr = templ->getPerUnitSound( "VoiceDisarm" );
- objectWithSound = obj;
- break;
- //these are specific to the guicommand based ground attacks, the toxin sprinkler and the firestorm wall thing
- //hence the additional check for it being a non-primary weapon
- case DAMAGE_FLAME:
- if (weapon->getWeaponSlot() != PRIMARY_WEAPON)
- {
- soundToPlayPtr = templ->getPerUnitSound( "VoiceFlameLocation" );
- objectWithSound = obj;
- }
- break;
- case DAMAGE_POISON:
- if (weapon->getWeaponSlot() != PRIMARY_WEAPON)
- {
- soundToPlayPtr = templ->getPerUnitSound( "VoicePoisonLocation" );
- objectWithSound = obj;
- }
- break;
- default:
- if( !weapon->getName().compare( "ComancheRocketPodWeapon" ) )
- {
- //Special case for comanche rocket pods.
- soundToPlayPtr = templ->getPerUnitSound( "VoiceFireRocketPods" );
- objectWithSound = obj;
- skip = true;
- }
- }
- }
- break;
- }
- case GameMessage::MSG_DO_GUARD_POSITION:
- case GameMessage::MSG_DO_GUARD_OBJECT:
- soundToPlayPtr = templ->getVoiceGuard();
- objectWithSound = obj;
- skip = true;
- break;
- case GameMessage::MSG_DO_SPECIAL_POWER:
- case GameMessage::MSG_DO_SPECIAL_POWER_AT_LOCATION:
- case GameMessage::MSG_DO_SPECIAL_POWER_AT_OBJECT:
- {
- if( info && info->m_specialPowerType != SPECIAL_INVALID )
- {
- SpecialPowerModuleInterface *spmInterface = obj->findSpecialPowerModuleInterface( info->m_specialPowerType );
- if( spmInterface )
- {
- objectWithSound = obj;
- soundToPlayPtr = &spmInterface->getInitiateSound();
- skip = TRUE;
- }
- }
- break;
- }
- case GameMessage::MSG_INTERNET_HACK:
- objectWithSound = obj;
- soundToPlayPtr = templ->getPerUnitSound( "VoiceHackInternet" );
- skip = TRUE;
- break;
- default:
- DEBUG_LOG(("Requested to add voice of message type %d, but don't know how - jkmcd\n", msgType));
- break;
- }
- if( skip )
- {
- //The unit sound doesn't have any sort of priority or special case, so simply play the first one that comes along.
- break;
- }
-
- }//next drawable in list
-
- if (!soundToPlayPtr)
- return;
- AudioEventRTS soundToPlay = *soundToPlayPtr;
- // to prevent voice stepping.
- if( objectWithSound )
- {
- soundToPlay.setObjectID( objectWithSound->getID() );
- TheAudio->addAudioEvent(&soundToPlay);
- // This seems really hacky, and MarkL admits that it is. However, we do this so that we
- // can "randomly" pick a different sound the next time, if we have 3 or more sounds. - jkmcd
- ((AudioEventRTS*)soundToPlayPtr)->setPlayingAudioIndex( soundToPlay.getPlayingAudioIndex() );
- if( objectWithSound->testStatus( OBJECT_STATUS_IS_CARBOMB ) )
- {
- //Additional sounds for terrorists in cars.
- switch (msgType)
- {
- case GameMessage::MSG_DO_FORCE_ATTACK_GROUND:
- case GameMessage::MSG_DO_FORCE_ATTACK_OBJECT:
- case GameMessage::MSG_DO_ATTACK_OBJECT:
- soundToPlay = TheAudio->getMiscAudio()->m_terroristInCarAttackVoice;
- soundToPlay.setObjectID( objectWithSound->getID() );
- TheAudio->addAudioEvent(&soundToPlay);
- break;
- case GameMessage::MSG_DO_MOVETO:
- case GameMessage::MSG_DO_ATTACKMOVETO:
- case GameMessage::MSG_GET_REPAIRED:
- case GameMessage::MSG_GET_HEALED:
- case GameMessage::MSG_DO_SALVAGE:
- soundToPlay = TheAudio->getMiscAudio()->m_terroristInCarMoveVoice;
- soundToPlay.setObjectID( objectWithSound->getID() );
- TheAudio->addAudioEvent(&soundToPlay);
- break;
- case GameMessage::MSG_SELECT_TEAM0:
- case GameMessage::MSG_SELECT_TEAM1:
- case GameMessage::MSG_SELECT_TEAM2:
- case GameMessage::MSG_SELECT_TEAM3:
- case GameMessage::MSG_SELECT_TEAM4:
- case GameMessage::MSG_SELECT_TEAM5:
- case GameMessage::MSG_SELECT_TEAM6:
- case GameMessage::MSG_SELECT_TEAM7:
- case GameMessage::MSG_SELECT_TEAM8:
- case GameMessage::MSG_SELECT_TEAM9:
- case GameMessage::MSG_CREATE_SELECTED_GROUP:
- soundToPlay = TheAudio->getMiscAudio()->m_terroristInCarSelectVoice;
- soundToPlay.setObjectID( objectWithSound->getID() );
- TheAudio->addAudioEvent(&soundToPlay);
- break;
- }
- }
- }
- }
- //------------------------------------------------------------------------------------
- /**
- * Find a suitable command center to view.
- */
- struct CommandCenterLocator
- {
- Bool atLeastOne;
- Bool isCommandCenter;
- Int val;
- Coord3D loc;
- CommandCenterLocator() : atLeastOne(false), isCommandCenter(false), val(-1)
- {
- loc.zero();
- }
- };
- void findCommandCenterOrMostExpensiveBuilding(Object* obj, void* vccl)
- {
- if (!obj) {
- return;
- }
- CommandCenterLocator *ccl = (CommandCenterLocator*) vccl;
- // here's the deal. We want to get the first Command Center in the list.
- // Barring that, we want the most expensive structure we currently own.
- if (obj->isKindOf(KINDOF_COMMANDCENTER)) {
- ccl->isCommandCenter = true;
- ccl->loc = *obj->getPosition();
- } else if (!ccl->isCommandCenter) {
- if (!obj->isKindOf(KINDOF_STRUCTURE)) {
- return;
- }
- Int costToBuild = obj->getTemplate()->calcCostToBuild(obj->getControllingPlayer());
- if (costToBuild > ccl->val) {
- ccl->val = costToBuild;
- ccl->loc = *obj->getPosition();
- }
- }
- ccl->atLeastOne = true;
- }
- static void viewCommandCenter( void )
- {
- Player* localPlayer = ThePlayerList->getLocalPlayer();
- if (!localPlayer)
- return;
- CommandCenterLocator ccl;
- localPlayer->iterateObjects(findCommandCenterOrMostExpensiveBuilding, &ccl);
- if (ccl.atLeastOne) {
- TheTacticalView->lookAt(&ccl.loc);
- } else {
- // @todo. Find their starting position and look at that instead?
- }
- }
- //----------------- Select and View Hero -----------------------------------
- struct HeroHolder
- {
- Object *hero;
- };
- void amIAHero(Object* obj, void* heroHolder)
- {
- if (!obj || ((HeroHolder*)heroHolder)->hero != NULL)
- {
- return;
- }
- if (obj->isKindOf( KINDOF_HERO ))
- {
- ((HeroHolder*)heroHolder)->hero = obj;
- }
- }
- static Object *iNeedAHero( void )
- {
- Player* localPlayer = ThePlayerList->getLocalPlayer();
- if (!localPlayer)
- return NULL;
- HeroHolder heroHolder;
- heroHolder.hero = NULL;
- localPlayer->iterateObjects(amIAHero, (void*)&heroHolder);
- return heroHolder.hero;
- }
- //------------------------------------------------------------------------------------
- /**
- * Create DO_MOVE_TO messages for each selected object, instructing it to move to the given location.
- */
- GameMessage::Type CommandTranslator::issueMoveToLocationCommand( const Coord3D *pos, Drawable *drawableInWay,
- CommandEvaluateType commandType )
- {
- GameMessage::Type msgType = GameMessage::MSG_INVALID;
- Object *obj = drawableInWay ? drawableInWay->getObject() : NULL;
- Bool isForceAttackable = FALSE;
- if (obj) {
- isForceAttackable = obj->isKindOf(KINDOF_FORCEATTACKABLE);
- }
- if (m_teamExists)
- {
- if( TheInGameUI->isInWaypointMode() )
- {
- msgType = GameMessage::MSG_ADD_WAYPOINT;
- }
- else if( TheInGameUI->isInAttackMoveToMode())
- {
- msgType = GameMessage::MSG_DO_ATTACKMOVETO;
- }
- else if( TheInGameUI->isInForceMoveToMode() )
- {
- msgType = GameMessage::MSG_DO_FORCEMOVETO;
- }
- else if( TheInGameUI->isInForceAttackMode() && isForceAttackable )
- {
- msgType = GameMessage::MSG_DO_ATTACK_OBJECT;
- }
- else
- {
- msgType = GameMessage::MSG_DO_MOVETO;
- }
- if( commandType == DO_COMMAND )
- {
- GameMessage *movemsg = TheMessageStream->appendMessage( msgType );
- if (msgType == GameMessage::MSG_DO_ATTACK_OBJECT)
- movemsg->appendObjectIDArgument( obj->getID() );
- else
- movemsg->appendLocationArgument( *pos );
- } // end if
- }
-
- // only make sounds if we really did the command messages
- if( commandType == DO_COMMAND )
- {
- PickAndPlayInfo info;
- info.m_drawTarget = drawableInWay;
- pickAndPlayUnitVoiceResponse( TheInGameUI->getAllSelectedDrawables(), GameMessage::MSG_DO_MOVETO, &info );
- } // end if
-
- if(TheStatsCollector)
- TheStatsCollector->incrementMoveCount();
- // return the actual msg type used
- return msgType;
- }
- //------------------------------------------------------------------------------------
- /// @todo Play attack command response sound on client-side to hide latency
- GameMessage::Type CommandTranslator::createAttackMessage( Drawable *draw,
- Drawable *other,
- CommandEvaluateType commandType )
- {
- GameMessage::Type msgType = GameMessage::MSG_INVALID;
- // the drawable must have an object to be able to attack
- if( draw->getObject() == NULL )
- return msgType;
- // the target must have an object to be attacked
- if( other->getObject() == NULL )
- return msgType;
- // insert object attack command message into stream
- msgType = GameMessage::MSG_DO_ATTACK_OBJECT;
- // only make the message if we are really doing a command
- if( commandType == DO_COMMAND )
- {
- GameMessage *attackmsg = TheMessageStream->appendMessage( msgType );
- attackmsg->appendObjectIDArgument( other->getObject()->getID() ); // must pass object IDs to logic
- } // end if
- // return the message type created
- return msgType;
- }
- //------------------------------------------------------------------------------------
- /**
- * Create DO_ATTACK_GROUND_OBJECT messages for each selected object, instructing it to attack the given enemy.
- * Return TRUE if any attacks actually occurred.
- */
- GameMessage::Type CommandTranslator::issueAttackCommand( Drawable *target,
- CommandEvaluateType commandType,
- GUICommandType command )
- {
- GameMessage::Type msgType = GameMessage::MSG_INVALID;
- if (target == NULL)
- return msgType;
- // you cannot attack an enemy that has no object representation
- Object *targetObj = target->getObject();
- if( !targetObj )
- return msgType;
-
- if( m_teamExists )
- {
- //DEBUG_LOG(("issuing team-attack cmd against %s\n",enemy->getTemplate()->getName().str()));
- // insert team attack command message into stream
- switch( command )
- {
- #ifdef ALLOW_SURRENDER
- case GUICOMMANDMODE_PICK_UP_PRISONER:
- msgType = GameMessage::MSG_PICK_UP_PRISONER;
- break;
- #endif
- case GUI_COMMAND_NONE:
- msgType = GameMessage::MSG_DO_ATTACK_OBJECT;
- break;
- default:
- DEBUG_ASSERTCRASH( 0, ("issueAttackCommand was passed in a GUICommandType type that isn't supported yet...") );
- return msgType;
- }
- // only create the message if our command type is DO_COMMAND
- if( commandType == DO_COMMAND )
- {
- GameMessage *attackMsg;
- attackMsg = TheMessageStream->appendMessage( msgType );
-
- attackMsg->appendObjectIDArgument( targetObj->getID() ); // must pass target object ID to logic
- // if we have a stats collector, inrement the stats
- if(TheStatsCollector)
- TheStatsCollector->incrementAttackCount();
- } // end if
- }
- else
- {
- DEBUG_LOG(("issuing NON-team-attack cmd against %s\n",target->getTemplate()->getName().str()));
- // send single attack command for selected drawable
- const DrawableList *selected = TheInGameUI->getAllSelectedDrawables();
- // loop through all the selected drawables
- Drawable *draw;
- for( DrawableListCIt it = selected->begin(); it != selected->end(); ++it )
- {
- draw = *it;
- msgType = createAttackMessage(draw, target, commandType );
- }
- }
-
- // only make sounds if the command was for real
- if( commandType == DO_COMMAND )
- {
- PickAndPlayInfo info;
- info.m_air = targetObj->isUsingAirborneLocomotor();
- info.m_drawTarget = target;
- pickAndPlayUnitVoiceResponse( TheInGameUI->getAllSelectedDrawables(), msgType, &info );
- } // end if
- // return the actual message type created
- return msgType;
- }
- //-------------------------------------------------------------------------------------------------
- GameMessage::Type CommandTranslator::issueSpecialPowerCommand( const CommandButton *command, CommandEvaluateType commandType, Drawable *target, const Coord3D *pos, Object* ignoreSelObj )
- {
- GameMessage::Type msgType = GameMessage::MSG_INVALID;
- if( !command || !command->getSpecialPowerTemplate())
- {
- return msgType;
- }
- Drawable* sourceDraw = ignoreSelObj ? ignoreSelObj->getDrawable() : TheInGameUI->getFirstSelectedDrawable();
- ObjectID specificSource = ignoreSelObj ? ignoreSelObj->getID() : INVALID_ID;
- if( BitTest( command->getOptions(), COMMAND_OPTION_NEED_OBJECT_TARGET ) )
- {
- // OBJECT BASED SPECIAL
- if (!command->isValidObjectTarget(sourceDraw, target))
- return msgType;
- msgType = GameMessage::MSG_DO_SPECIAL_POWER_AT_OBJECT;
- if( commandType == DO_COMMAND )
- {
- GameMessage *msg;
- msg = TheMessageStream->appendMessage( msgType );
- msg->appendIntegerArgument( command->getSpecialPowerTemplate()->getID() );
- msg->appendObjectIDArgument( target->getObject()->getID() );
- msg->appendIntegerArgument( command->getOptions() );
- msg->appendObjectIDArgument( specificSource );
- // say something like " I think I'll put some dynamite on that there tank."
- PickAndPlayInfo info;
- info.m_drawTarget = target;
- info.m_specialPowerType = command->getSpecialPowerTemplate()->getSpecialPowerType();
- pickAndPlayUnitVoiceResponse( TheInGameUI->getAllSelectedDrawables(), msgType, &info );
- }
- }
- else if( BitTest( command->getOptions(), NEED_TARGET_POS ) )
- {
- //LOCATION BASED SPECIAL
- msgType = GameMessage::MSG_DO_SPECIAL_POWER_AT_LOCATION;
- if( commandType == DO_COMMAND )
- {
- GameMessage *msg;
- msg = TheMessageStream->appendMessage( msgType );
- msg->appendIntegerArgument( command->getSpecialPowerTemplate()->getID() );
- msg->appendLocationArgument( *pos );
- msg->appendRealArgument( INVALID_ANGLE ); //We don't use the angle (unless we're using a construction special in PlaceEventTranslator).
- //Object in way.... some specials care, others don't
- ObjectID targetID = (target && target->getObject()) ? target->getObject()->getID() : INVALID_ID;
- msg->appendObjectIDArgument( targetID );
- msg->appendIntegerArgument( command->getOptions() );
- msg->appendObjectIDArgument( specificSource );
- // say something like " I think I'll put a timed charge on the ground, here."
- PickAndPlayInfo info;
- info.m_drawTarget = target;
- info.m_specialPowerType = command->getSpecialPowerTemplate()->getSpecialPowerType();
- pickAndPlayUnitVoiceResponse( TheInGameUI->getAllSelectedDrawables(), msgType, &info );
-
- }
- }
- else
- {
- //NO TARGET SPECIAL
- msgType = GameMessage::MSG_DO_SPECIAL_POWER;
- if( commandType == DO_COMMAND )
- {
- GameMessage *msg;
- msg = TheMessageStream->appendMessage( msgType );
- msg->appendIntegerArgument( command->getSpecialPowerTemplate()->getID() );
- msg->appendIntegerArgument( command->getOptions() );
- msg->appendObjectIDArgument( specificSource );
- // say something like " I think I'll set down my laptop and hack some cash from a bank in the Cayman Islands."
- PickAndPlayInfo info;
- info.m_drawTarget = target;
- info.m_specialPowerType = command->getSpecialPowerTemplate()->getSpecialPowerType();
- pickAndPlayUnitVoiceResponse( TheInGameUI->getAllSelectedDrawables(), msgType, &info );
-
- }
- }
- if( command->getCommandType() == GUI_COMMAND_SPECIAL_POWER_FROM_SHORTCUT && commandType == DO_COMMAND )
- {
- Object *obj = sourceDraw->getObject();
- SpecialPowerUpdateInterface *spUpdate = obj->findSpecialPowerWithOverridableDestination();
- if( spUpdate )
- {
- //Deselect the drawables before posting the selection message.
- TheInGameUI->deselectAllDrawables();
- //Because we just launched a special power via shortcut, and the special power accepts input
- //from the player (particle uplink cannon, spectre gunship), simply select the object now.
- //--------------------
- GameMessage *teamMsg = TheMessageStream->appendMessage( GameMessage::MSG_CREATE_SELECTED_GROUP_NO_SOUND );
- // creating a new team so pass in true
- teamMsg->appendBooleanArgument( TRUE );
- teamMsg->appendObjectIDArgument( obj->getID() );
- TheInGameUI->selectDrawable( obj->getDrawable() );
- }
- }
-
- return msgType;
- }
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- GameMessage::Type CommandTranslator::issueCombatDropCommand( const CommandButton *command, CommandEvaluateType commandType, Drawable *target, const Coord3D *pos )
- {
- if( !command )
- {
- return GameMessage::MSG_INVALID;
- }
- if( target != NULL && BitTest( command->getOptions(), COMMAND_OPTION_NEED_OBJECT_TARGET ) )
- {
- // OBJECT BASED SPECIAL
- if (!command->isValidObjectTarget(TheInGameUI->getFirstSelectedDrawable(), target))
- return GameMessage::MSG_INVALID;
- GameMessage::Type msgType = GameMessage::MSG_COMBATDROP_AT_OBJECT;
- if( commandType == DO_COMMAND )
- {
- GameMessage *msg = TheMessageStream->appendMessage( msgType );
- ObjectID targetID = (target && target->getObject()) ? target->getObject()->getID() : INVALID_ID;
- msg->appendObjectIDArgument( targetID );
- pickAndPlayUnitVoiceResponse( TheInGameUI->getAllSelectedDrawables(), GameMessage::MSG_COMBATDROP_AT_OBJECT );
- }
- return msgType;
- }
- else if ( BitTest( command->getOptions(), NEED_TARGET_POS ) )
- {
- GameMessage::Type msgType = GameMessage::MSG_COMBATDROP_AT_LOCATION;
- if( commandType == DO_COMMAND )
- {
- GameMessage *msg = TheMessageStream->appendMessage( msgType );
- msg->appendLocationArgument( *pos );
- pickAndPlayUnitVoiceResponse( TheInGameUI->getAllSelectedDrawables(), GameMessage::MSG_COMBATDROP_AT_LOCATION );
- }
- return msgType;
- }
- else
- {
- return GameMessage::MSG_INVALID;
- }
- }
- //-------------------------------------------------------------------------------------------------
- GameMessage::Type CommandTranslator::issueFireWeaponCommand( const CommandButton *command, CommandEvaluateType commandType, Drawable *target, const Coord3D *pos )
- {
- GameMessage::Type msgType = GameMessage::MSG_INVALID;
- if( !command )
- {
- return msgType;
- }
- if( BitTest( command->getOptions(), COMMAND_OPTION_NEED_OBJECT_TARGET ) )
- {
- //OBJECT BASED FIRE WEAPON
- if (!target || !target->getObject())
- return msgType;
- if (!command->isValidObjectTarget(TheInGameUI->getFirstSelectedDrawable(), target))
- return msgType;
- if( BitTest( command->getOptions(), ATTACK_OBJECTS_POSITION ) )
- {
- //Actually, you know what.... we want to attack the object's location instead.
- msgType = GameMessage::MSG_DO_WEAPON_AT_LOCATION;
- if( commandType == DO_COMMAND )
- {
- GameMessage *msg;
- msg = TheMessageStream->appendMessage( msgType );
- msg->appendIntegerArgument( command->getWeaponSlot() );
- msg->appendLocationArgument( *pos );
- msg->appendIntegerArgument( command->getMaxShotsToFire() );
- //Object in way.... some location weapons care, others don't
- ObjectID targetID = (target && target->getObject()) ? target->getObject()->getID() : INVALID_ID;
- msg->appendObjectIDArgument( targetID );
- }
- }
- else
- {
- msgType = GameMessage::MSG_DO_WEAPON_AT_OBJECT;
- if( commandType == DO_COMMAND )
- {
- GameMessage *msg;
- msg = TheMessageStream->appendMessage( msgType );
- msg->appendIntegerArgument( command->getWeaponSlot() );
- ObjectID targetID = (target && target->getObject()) ? target->getObject()->getID() : INVALID_ID;
- msg->appendObjectIDArgument( targetID );
- msg->appendIntegerArgument( command->getMaxShotsToFire() );
- //play a unit specific sound?
- PickAndPlayInfo info;
- WeaponSlotType slot = command->getWeaponSlot();
- info.m_weaponSlot = &slot;
- pickAndPlayUnitVoiceResponse( TheInGameUI->getAllSelectedDrawables(), GameMessage::MSG_DO_WEAPON_AT_OBJECT, &info );
- }
- }
- }
- else if( BitTest( command->getOptions(), NEED_TARGET_POS ) )
- {
- //LOCATION BASED FIRE WEAPON
- msgType = GameMessage::MSG_DO_WEAPON_AT_LOCATION;
- if( commandType == DO_COMMAND )
- {
- GameMessage *msg;
- msg = TheMessageStream->appendMessage( msgType );
- msg->appendIntegerArgument( command->getWeaponSlot() );
- msg->appendLocationArgument( *pos );
- msg->appendIntegerArgument( command->getMaxShotsToFire() );
- //Object in way.... some location weapons care, others don't
- ObjectID targetID = (target && target->getObject()) ? target->getObject()->getID() : INVALID_ID;
- msg->appendObjectIDArgument( targetID );
- }
- }
- else
- {
- //NO TARGET WEAPON
- msgType = GameMessage::MSG_DO_WEAPON;
- if( commandType == DO_COMMAND )
- {
- GameMessage *msg;
- msg = TheMessageStream->appendMessage( msgType );
- DEBUG_ASSERTCRASH( (command->getSpecialPowerTemplate()), ("No Special Power Weapon here to 'do' with! ML"));
- msg->appendIntegerArgument( command->getSpecialPowerTemplate()->getID() );
- }
- }
-
- return msgType;
- }
- //-------------------------------------------------------------------------------------------------
- GameMessage::Type CommandTranslator::createEnterMessage( Drawable *enter,
- CommandEvaluateType commandType )
- {
- GameMessage::Type msgType = GameMessage::MSG_ENTER;
- // if we're just evaluating then get out of here without actually doing the action
- if( commandType == EVALUATE_ONLY )
- return msgType;
- if (!enter || !enter->getObject())
- return msgType;
- // sanity
- DEBUG_ASSERTCRASH( commandType == DO_COMMAND, ("createEnterMessage - commandType is not DO_COMMAND\n") );
- if( m_teamExists )
- {
- PickAndPlayInfo info;
- info.m_drawTarget = enter;
- pickAndPlayUnitVoiceResponse(TheInGameUI->getAllSelectedDrawables(), msgType, &info );
- GameMessage *enterMsg = TheMessageStream->appendMessage( msgType );
- enterMsg->appendObjectIDArgument( INVALID_ID ); // 0 means current "selection team" of this player
- enterMsg->appendObjectIDArgument( enter->getObject()->getID() );
- } // end if
- else
- {
- DEBUG_CRASH(("Shouldn't get here. jkmcd"));
- }
- // return the type of the message used
- return msgType;
- } // end createEnterMessage
- //====================================================================================
- CommandTranslator::CommandTranslator() :
- m_objective(0),
- m_teamExists(false),
- m_mouseRightDown(0),
- m_mouseRightUp(0)
- {
- m_mouseRightDragAnchor.x = 0;
- m_mouseRightDragAnchor.y = 0;
- m_mouseRightDragLift.x = 0;
- m_mouseRightDragLift.y = 0;
- }
- //====================================================================================
- CommandTranslator::~CommandTranslator()
- {
- }
- //-------------------------------------------------------------------------------------------------
- GameMessage::Type CommandTranslator::evaluateForceAttack( Drawable *draw, const Coord3D *pos, CommandEvaluateType type )
- {
- // evaluateForceAttack is used to determine whether or not we can force attack the
- // given target, and if we can, to issue the appropriate command.
- GameMessage::Type retVal = GameMessage::MSG_INVALID;
- if( !draw && !pos )
- {
- return retVal;
- }
- const DrawableList *allSelected = TheInGameUI->getAllSelectedDrawables();
- if( draw )
- {
- Object *obj = draw ? draw->getObject() : NULL;
- if( !obj )
- {
- return retVal;
- }
- CanAttackResult result = canAnyForceAttack( allSelected, obj, pos );
- if( result == ATTACKRESULT_POSSIBLE || result == ATTACKRESULT_POSSIBLE_AFTER_MOVING )
- {
- retVal = GameMessage::MSG_DO_FORCE_ATTACK_OBJECT;
- if( type == DO_COMMAND )
- {
- pickAndPlayUnitVoiceResponse( allSelected, retVal );
- GameMessage *newMsg = TheMessageStream->appendMessage( retVal );
- newMsg->appendObjectIDArgument( obj->getID() );
-
- }
- else if( type == DO_HINT )
- {
- retVal = GameMessage::MSG_DO_FORCE_ATTACK_OBJECT_HINT;
- // Don't need the message back, cause there is nothing to append to it.
- TheMessageStream->appendMessage( retVal );
- }
- }
- else if( result == ATTACKRESULT_INVALID_SHOT && type == DO_HINT )
- {
- retVal = GameMessage::MSG_IMPOSSIBLE_ATTACK_HINT;
- TheMessageStream->appendMessage( retVal );
- }
- }
- else if( pos )
- {
- CanAttackResult result = canAnyForceAttack( allSelected, NULL, pos );
- if( result == ATTACKRESULT_POSSIBLE || result == ATTACKRESULT_POSSIBLE_AFTER_MOVING )
- {
- retVal = GameMessage::MSG_DO_FORCE_ATTACK_GROUND;
- if( type == DO_COMMAND )
- {
- pickAndPlayUnitVoiceResponse( allSelected, retVal );
- GameMessage *newMsg = TheMessageStream->appendMessage( retVal );
- newMsg->appendLocationArgument( *pos );
- }
- else if( type == DO_HINT )
- {
- retVal = GameMessage::MSG_DO_FORCE_ATTACK_GROUND_HINT;
- // Don't need the message back, cause there is nothing to append to it.
- TheMessageStream->appendMessage( retVal );
- }
- }
- else if( result == ATTACKRESULT_INVALID_SHOT && type == DO_HINT )
- {
- retVal = GameMessage::MSG_IMPOSSIBLE_ATTACK_HINT;
- TheMessageStream->appendMessage( retVal );
- }
- }
- return retVal;
- }
- // ------------------------------------------------------------------------------------------------
- /** This method and the order of operations in the check here, determine what command would
- * actually happen (if type parameter == DO_COMMAND) if the user clicked on the drawable
- * 'draw'. If type == DO_HINT, then the user hasn't actually clicked, but has moused over
- * the drawable 'draw' and we want to generate a hint message as to what the actual
- * command would be if clicked
- * NOTE: draw can be NULL, in which case we give a hint for the location */
- // ------------------------------------------------------------------------------------------------
- GameMessage::Type CommandTranslator::evaluateContextCommand( Drawable *draw,
- const Coord3D *pos,
- CommandEvaluateType type )
- {
- Object *obj = draw ? draw->getObject() : NULL;
- Drawable *drawableInWay = draw;
- //This piece of code is used to prevent interaction with unselectable objects or masked objects. When we
- //call this function, we typically pass in both a position and a drawable (if applicable), so if the
- //drawable is invalid... then convert it to a position to be evaluated instead.
- //Added: shrubberies are the exception for interactions...
- //Removed: GS Took out ObjectStatusUnselectable, since that status only prevents selection, not everything
- if( obj == NULL ||
- obj->getStatusBits().test( OBJECT_STATUS_MASKED ) &&
- !obj->isKindOf(KINDOF_SHRUBBERY) && !obj->isKindOf(KINDOF_FORCEATTACKABLE) )
- {
- //Nulling out the draw and obj pointer will force the remainder of this code to evaluate
- //a position interaction.
- draw = NULL;
- obj = NULL;
- } // end if
- // If the thing is a mine, and is locally controlled, then we should issue a moveto to its location.
- if (obj && obj->isLocallyControlled() && obj->isKindOf(KINDOF_MINE)) {
- draw = NULL;
- obj = NULL;
- }
- if( TheInGameUI->isInForceMoveToMode() )
- {
- //Nulling out the draw and obj pointer will force the remainder of this code to evaluate
- //a position interaction.
- draw = NULL;
- obj = NULL;
- } else if (TheInGameUI->isInForceAttackMode() ) {
- // setting the drawableInWay to draw will allow us to force attack in the issue move command
- // if there is a location to which we should attack.
- drawableInWay = draw;
- }
-
- GameMessage::Type msgType = GameMessage::MSG_INVALID;
- // Then we should determine if the game currently prefers selection events. If it does, then return
- // the invalid message.
- if (obj) {
- if (obj->isLocallyControlled() && TheInGameUI->isInPreferSelectionMode()) {
- return msgType;
- }
- }
- // Kris: Now that we can select non-controllable units/structures, don't allow any actions to be performed.
- const CommandButton *command = TheInGameUI->getGUICommand();
- if( TheInGameUI->areSelectedObjectsControllable()
- || (command && command->getCommandType() == GUI_COMMAND_SPECIAL_POWER_FROM_SHORTCUT))
- {
- GameMessage *hintMessage;
- if( TheInGameUI->isInWaypointMode() )
- {
- //Override any *other* commands with waypoint commands.
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
- if( TheTerrainLogic )
- {
- msgType = issueMoveToLocationCommand( pos, draw, type );
- }
- }
- else
- {
- msgType = GameMessage::MSG_ADD_WAYPOINT_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendLocationArgument( *pos );
- }
- return msgType;
- }
- CanAttackResult result;
- if(command &&
- (command->isContextCommand()
- || command->getCommandType() == GUI_COMMAND_SPECIAL_POWER
- || command->getCommandType() == GUI_COMMAND_SPECIAL_POWER_FROM_SHORTCUT))
- {
- if( obj && obj->isKindOf( KINDOF_SHRUBBERY ) && !BitTest( command->getOptions(), ALLOW_SHRUBBERY_TARGET ) )
- {
- //If our object is a shrubbery, and we don't allow targetting it... then null it out.
- //Nulling out the draw and obj pointer will force the remainder of this code to evaluate
- //a position interaction.
- draw = NULL;
- obj = NULL;
- }
- if( obj && obj->isKindOf( KINDOF_MINE ) && !BitTest( command->getOptions(), ALLOW_MINE_TARGET ) )
- {
- //If our object is a mine, and we don't allow targetting it... then null it out.
- //Nulling out the draw and obj pointer will force the remainder of this code to evaluate
- //a position interaction.
- draw = NULL;
- obj = NULL;
- }
-
- //Kris: September 27, 2002
- //Added relationship tests to make sure we're not attempting a context-command on a restricted relationship.
- //This case prevents rebels from using tranq darts on allies.
- if( obj && BitTest( command->getOptions(), COMMAND_OPTION_NEED_OBJECT_TARGET ) )
- {
- Relationship relationship = ThePlayerList->getLocalPlayer()->getRelationship( obj->getTeam() );
- switch( relationship )
- {
- case ALLIES:
- if( !BitTest( command->getOptions(), NEED_TARGET_ALLY_OBJECT ) )
- {
- draw = NULL;
- obj = NULL;
- }
- break;
- case ENEMIES:
- if( !BitTest( command->getOptions(), NEED_TARGET_ENEMY_OBJECT ) )
- {
- draw = NULL;
- obj = NULL;
- }
- break;
- case NEUTRAL:
- if( !BitTest( command->getOptions(), NEED_TARGET_NEUTRAL_OBJECT ) )
- {
- draw = NULL;
- obj = NULL;
- }
- break;
- }
- }
- Bool currentlyValid = FALSE;
- ObjectID objectID = obj ? obj->getID() : INVALID_ID;
- switch( command->getCommandType() )
- {
- //Kris: June 06, 2002
- //This is a GUI command button that triggers a mode. In any of these modes, only one specific action
- //can occur. If the mouse isn't over a valid target, then the conditions aren't met and the code will
- //cause an invalid version of the cursor to be shown -- and should the user click, the action won't take place.
- case GUICOMMANDMODE_CONVERT_TO_CARBOMB:
- currentlyValid = TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_CONVERT_OBJECT_TO_CARBOMB, obj, InGameUI::SELECTION_ANY );
- break;
- case GUICOMMANDMODE_HIJACK_VEHICLE:
- currentlyValid = TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_HIJACK_VEHICLE, obj, InGameUI::SELECTION_ANY );
- break;
- case GUICOMMANDMODE_SABOTAGE_BUILDING:
- currentlyValid = TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_SABOTAGE_BUILDING, obj, InGameUI::SELECTION_ANY );
- break;
- #ifdef ALLOW_SURRENDER
- case GUICOMMANDMODE_PICK_UP_PRISONER:
- currentlyValid = TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_PICK_UP_PRISONER, obj, InGameUI::SELECTION_ANY );
- break;
- #endif
- case GUI_COMMAND_SPECIAL_POWER_FROM_SHORTCUT:
- {
- Object* unit = ThePlayerList->getLocalPlayer()->findMostReadyShortcutSpecialPowerOfType( command->getSpecialPowerTemplate()->getSpecialPowerType() );
- if( unit )
- currentlyValid = TheInGameUI->canSelectedObjectsDoSpecialPower( command, obj, pos, InGameUI::SELECTION_ANY, command->getOptions(), unit );
- else
- currentlyValid = false;
- break;
- }
- case GUI_COMMAND_SPECIAL_POWER:
- currentlyValid = TheInGameUI->canSelectedObjectsDoSpecialPower( command, obj, pos, InGameUI::SELECTION_ANY, command->getOptions(), NULL );
- break;
- case GUI_COMMAND_FIRE_WEAPON:
- currentlyValid = TheInGameUI->canSelectedObjectsEffectivelyUseWeapon( command, obj, pos, InGameUI::SELECTION_ANY );
- break;
- case GUI_COMMAND_COMBATDROP:
- currentlyValid = !obj ? TRUE : TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_COMBATDROP_INTO, obj, InGameUI::SELECTION_ANY );
- break;
- }
- if( currentlyValid )
- {
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
- switch( command->getCommandType() )
- {
- case GUICOMMANDMODE_CONVERT_TO_CARBOMB:
- case GUICOMMANDMODE_HIJACK_VEHICLE:
- case GUICOMMANDMODE_SABOTAGE_BUILDING:
- msgType = createEnterMessage( draw, type );
- break;
- #ifdef ALLOW_SURRENDER
- case GUICOMMANDMODE_PICK_UP_PRISONER:
- msgType = issueAttackCommand( draw, type, command->getCommandType() );
- break;
- #endif
- case GUI_COMMAND_SPECIAL_POWER_FROM_SHORTCUT:
- {
- Object* unit = ThePlayerList->getLocalPlayer()->findMostReadyShortcutSpecialPowerOfType( command->getSpecialPowerTemplate()->getSpecialPowerType() );
- if( unit )
- msgType = issueSpecialPowerCommand( command, type, draw, pos, unit );
- break;
- }
- case GUI_COMMAND_SPECIAL_POWER://lorenzen
- msgType = issueSpecialPowerCommand( command, type, draw, pos, NULL );
- break;
- case GUI_COMMAND_FIRE_WEAPON:
- msgType = issueFireWeaponCommand( command, type, draw, pos );
- break;
- case GUI_COMMAND_COMBATDROP:
- msgType = issueCombatDropCommand( command, type, draw, pos );
- break;
- }
- // NULL out the GUI command if we're actually doing something
- if( type == DO_COMMAND )
- {
- TheInGameUI->setGUICommand( NULL );
- }
- }
- else
- {
- msgType = GameMessage::MSG_VALID_GUICOMMAND_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendObjectIDArgument( objectID );
- }
- }
- else // not currently valid
- {
- msgType = GameMessage::MSG_INVALID_GUICOMMAND_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendObjectIDArgument( objectID );
- }
- } // if a special power
- else if( command && (command->getCommandType() == GUI_COMMAND_SPECIAL_POWER_CONSTRUCT
- || command->getCommandType() == GUI_COMMAND_SPECIAL_POWER_CONSTRUCT_FROM_SHORTCUT) )
- {
- //We're using the build placement interface to determine where to build our special power item.
- //Because of that, we only care about DO_COMMAND. The context evaluation and hint feedback system
- //is already taken care of. But what we need to do is trigger the special power to actually build
- //the object and reset the timer.
- if( type == DO_COMMAND )
- {
- switch( command->getCommandType() )
- {
- case GUI_COMMAND_SPECIAL_POWER_FROM_SHORTCUT:
- {
- Object* unit = ThePlayerList->getLocalPlayer()->findMostReadyShortcutSpecialPowerOfType( command->getSpecialPowerTemplate()->getSpecialPowerType() );
- if( unit )
- msgType = issueSpecialPowerCommand( command, type, draw, pos, unit );
- break;
- }
- case GUI_COMMAND_SPECIAL_POWER://lorenzen
- msgType = issueSpecialPowerCommand( command, type, draw, pos, NULL );
- break;
- }
- }
- }
-
- // ********************************************************************************************
- else if( TheInGameUI->canSelectedObjectsOverrideSpecialPowerDestination( pos, InGameUI::SELECTION_ANY, SPECIAL_INVALID ) )
- {
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
- // do the command
- msgType = GameMessage::MSG_DO_SPECIAL_POWER_OVERRIDE_DESTINATION;
- if( type == DO_COMMAND )
- {
- GameMessage *gameMsg = TheMessageStream->appendMessage( msgType );
- gameMsg->appendLocationArgument( *pos );
- gameMsg->appendIntegerArgument( SPECIAL_INVALID );
- gameMsg->appendObjectIDArgument( INVALID_ID ); // no specific source
- } // end if
- } // end if
- else
- {
- // generate a hint message
- msgType = GameMessage::MSG_DO_SPECIAL_POWER_OVERRIDE_DESTINATION_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- } // end else
- }
-
- // ********************************************************************************************
- else if( draw && !TheInGameUI->isInForceAttackMode() &&
- TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_RESUME_CONSTRUCTION, obj, InGameUI::SELECTION_ANY ) )
- {
-
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
- // do the command
- msgType = GameMessage::MSG_RESUME_CONSTRUCTION;
- if( type == DO_COMMAND )
- {
- GameMessage *resumeMsg = TheMessageStream->appendMessage( msgType );
- resumeMsg->appendObjectIDArgument( obj->getID() );
- pickAndPlayUnitVoiceResponse( TheInGameUI->getAllSelectedDrawables(), GameMessage::MSG_RESUME_CONSTRUCTION );
- } // end if
- } // end if
- else
- {
- // generate a hint message
- msgType = GameMessage::MSG_RESUME_CONSTRUCTION_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendObjectIDArgument( obj->getID() );
- } // end else
- } // end else if
- // ********************************************************************************************
- else if( draw && !TheInGameUI->isInForceAttackMode() &&
- TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_DOCK_AT,
- obj,
- InGameUI::SELECTION_ALL ) )
- {
- //
- // The actual logic is simply to AIUpdate::dock with the target, the hint is the
- // only part that needs to be more specific.
- //
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
- // Give the dock command
- msgType = GameMessage::MSG_DOCK;
- if( type == DO_COMMAND )
- {
- GameMessage *dockMsg = TheMessageStream->appendMessage( msgType );
- dockMsg->appendObjectIDArgument( obj->getID() );
- // only make sounds if we really did the command messages
- pickAndPlayUnitVoiceResponse(TheInGameUI->getAllSelectedDrawables(), GameMessage::MSG_DOCK);
- } // end if
- }
- else
- {
- // make the hint
- msgType = GameMessage::MSG_DOCK_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendObjectIDArgument( obj->getID() );
- }
- }
- // ********************************************************************************************
- else if( draw && !TheInGameUI->isInForceAttackMode() &&
- TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_REPAIR_OBJECT, obj, InGameUI::SELECTION_ANY ) )
- {
-
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
- // do the command
- msgType = GameMessage::MSG_DO_REPAIR;
- if( type == DO_COMMAND )
- {
- GameMessage *healMsg = TheMessageStream->appendMessage( msgType );
- healMsg->appendObjectIDArgument( obj->getID() );
-
- pickAndPlayUnitVoiceResponse( TheInGameUI->getAllSelectedDrawables(), GameMessage::MSG_DO_REPAIR );
- } // end if
- } // end if
- else
- {
- // generate a hint message
- msgType = GameMessage::MSG_DO_REPAIR_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendObjectIDArgument( obj->getID() );
- } // end else
- } // end else if
- // ********************************************************************************************
- else if( draw && !TheInGameUI->isInForceAttackMode() &&
- TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_GET_REPAIRED_AT, obj, InGameUI::SELECTION_ANY ) )
- {
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
- // do the command
- msgType = GameMessage::MSG_GET_REPAIRED;
- if( type == DO_COMMAND )
- {
- GameMessage *healMsg = TheMessageStream->appendMessage( msgType );
- healMsg->appendObjectIDArgument( obj->getID() );
-
- pickAndPlayUnitVoiceResponse( TheInGameUI->getAllSelectedDrawables(), GameMessage::MSG_GET_REPAIRED );
- } // end if
- } // end if
- else
- {
- // generate a hint message
- msgType = GameMessage::MSG_GET_REPAIRED_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendObjectIDArgument( obj->getID() );
- } // end else
- } // end else if
- // ********************************************************************************************
- else if( draw && !TheInGameUI->isInForceAttackMode() &&
- TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_GET_HEALED_AT, obj, InGameUI::SELECTION_ANY ) )
- {
-
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
- // do the command
- msgType = GameMessage::MSG_GET_HEALED;
- if( type == DO_COMMAND )
- {
- GameMessage *healMsg = TheMessageStream->appendMessage( msgType );
- healMsg->appendObjectIDArgument( obj->getID() );
-
- pickAndPlayUnitVoiceResponse( TheInGameUI->getAllSelectedDrawables(), GameMessage::MSG_GET_HEALED );
- } // end if
- } // end if
- else
- {
- // generate hint message
- msgType = GameMessage::MSG_GET_HEALED_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType);
- hintMessage->appendObjectIDArgument( obj->getID() );
- } // end else
- } // end else if
- // ********************************************************************************************
- else if( draw && draw->getObject() && !TheInGameUI->isInForceAttackMode() &&
- TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_HIJACK_VEHICLE,
- draw->getObject(),
- InGameUI::SELECTION_ANY ) )
- {
-
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
- // Now, this just tricks the AI into making the hijacker run towards the target vehicle
- // I must add a test to keep him from actually entering an enemy vehicle (contained)... Lorenzen
- msgType = createEnterMessage( draw, type );
- } // end if
- else
- {
-
- msgType = GameMessage::MSG_HIJACK_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendObjectIDArgument( draw->getObject()->getID() );
- } // end else
- } // end else if
- // ********************************************************************************************
- else if( draw && !TheInGameUI->isInForceAttackMode() &&
- TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_CONVERT_OBJECT_TO_CARBOMB, obj, InGameUI::SELECTION_ANY ) )
- {
-
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
- // issue the command (convert to carbomb is nearly identical to enter)
- msgType = createEnterMessage( draw, type );
- } // end if
- else
- {
-
- msgType = GameMessage::MSG_CONVERT_TO_CARBOMB_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendObjectIDArgument( obj->getID() );
- } // end else
- }
- // ********************************************************************************************
- else if( draw && draw->getObject() && !TheInGameUI->isInForceAttackMode() &&
- TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_SABOTAGE_BUILDING,
- draw->getObject(),
- InGameUI::SELECTION_ANY ) )
- {
-
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
- msgType = createEnterMessage( draw, type );
- } // end if
- else
- {
- msgType = GameMessage::MSG_SABOTAGE_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendObjectIDArgument( draw->getObject()->getID() );
- } // end else
- } // end else if
- // ********************************************************************************************
- else if( draw && !TheInGameUI->isInForceAttackMode() && canSelectionSalvage(obj) )
- {
- GameMessage *msg;
-
- if( type == DO_COMMAND || type == EVALUATE_ONLY ) {
- msgType = GameMessage::MSG_DO_SALVAGE;
- if (type == DO_COMMAND) {
- msg = TheMessageStream->appendMessage(msgType);
- msg->appendLocationArgument(*obj->getPosition());
- pickAndPlayUnitVoiceResponse(TheInGameUI->getAllSelectedDrawables(), msgType);
- }
- } else {
- msgType = GameMessage::MSG_DO_SALVAGE_HINT;
- msg = TheMessageStream->appendMessage(msgType);
- msg->appendLocationArgument(*obj->getPosition());
- }
- } // end else if
- // ********************************************************************************************
- else if( draw && !TheInGameUI->isInForceAttackMode() &&
- TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_ENTER_OBJECT, obj, InGameUI::SELECTION_ANY, true ) )
- {
-
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
- // issue the command
- msgType = createEnterMessage( draw, type );
- } // end if
- else
- {
- msgType = GameMessage::MSG_ENTER_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendObjectIDArgument( obj->getID() );
- } // end else
- } // end else if
- // ********************************************************************************************
- else if( draw && (result = TheInGameUI->getCanSelectedObjectsAttack( InGameUI::ACTIONTYPE_ATTACK_OBJECT, obj, InGameUI::SELECTION_ANY, TheInGameUI->isInForceAttackMode() )) == ATTACKRESULT_POSSIBLE )
- {
-
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
-
- // issue the attack order
- msgType = issueAttackCommand( draw, type );
- } // end if
- else
- {
- // Generate an Attack hint
- msgType = GameMessage::MSG_DO_ATTACK_OBJECT_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendObjectIDArgument( obj->getID() );
- } // end else
- } // end else if
- // ********************************************************************************************
- else if( draw && result == ATTACKRESULT_POSSIBLE_AFTER_MOVING )
- {
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
-
- // issue the attack order
- msgType = issueAttackCommand( draw, type );
- } // end if
- else
- {
- // Generate an Attack hint
- msgType = GameMessage::MSG_DO_ATTACK_OBJECT_AFTER_MOVING_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendObjectIDArgument( obj->getID() );
- } // end else
- }
- // ********************************************************************************************
- else if( draw && TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_CAPTURE_BUILDING, obj, InGameUI::SELECTION_ANY ) )
- {
-
- //@TODO: Kris
- //PRELIMINARY CODE FOR HOOKING IN AUTO SPECIALS --- WILL BE REDONE!
- Object *source = TheInGameUI->getFirstSelectedDrawable()->getObject();
- const CommandSet *set = TheControlBar->findCommandSet( source->getCommandSetString() );
- if( set )
- {
- for( Int i = 0; i < MAX_COMMANDS_PER_SET; i++ )
- {
- // get command button
- const CommandButton *command = set->getCommandButton(i);
- if( command && command->getCommandType() == GUI_COMMAND_SPECIAL_POWER )
- {
- SpecialPowerType spType = command->getSpecialPowerTemplate()->getSpecialPowerType();
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
- if( spType == SPECIAL_BLACKLOTUS_CAPTURE_BUILDING ||
- spType == SPECIAL_INFANTRY_CAPTURE_BUILDING )
- {
- //Issue the capture building command
- msgType = issueSpecialPowerCommand( command, type, draw, pos, NULL );
- break;
- }
- }
- else if( spType == SPECIAL_BLACKLOTUS_CAPTURE_BUILDING )
- {
- //Issue the black lotus hack hint for capturing a building.
- msgType = GameMessage::MSG_HACK_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendObjectIDArgument( obj->getID() );
- }
- else if( spType == SPECIAL_INFANTRY_CAPTURE_BUILDING )
- {
- //Issue the infantry hint for capturing a building
- msgType = GameMessage::MSG_CAPTUREBUILDING_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendObjectIDArgument( obj->getID() );
- }
- }
- }
- }
- } // end else if
- // ********************************************************************************************
- else if( draw && TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_DISABLE_VEHICLE_VIA_HACKING, obj, InGameUI::SELECTION_ANY ) )
- {
-
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
- //@TODO: Kris
- //PRELIMINARY CODE FOR HOOKING IN AUTO SPECIALS --- WILL BE REDONE!
- Object *source = TheInGameUI->getFirstSelectedDrawable()->getObject();
- const CommandSet *set = TheControlBar->findCommandSet( source->getCommandSetString() );
- if( set )
- {
- for( Int i = 0; i < MAX_COMMANDS_PER_SET; i++ )
- {
- // get command button
- const CommandButton *command = set->getCommandButton(i);
- if( command && command->getCommandType() == GUI_COMMAND_SPECIAL_POWER )
- {
- SpecialPowerType spType = command->getSpecialPowerTemplate()->getSpecialPowerType();
- if( spType == SPECIAL_BLACKLOTUS_DISABLE_VEHICLE_HACK )
- {
- msgType = issueSpecialPowerCommand( command, type, draw, pos, NULL );
- break;
- }
- }
- }
- }
- }
- else
- {
- msgType = GameMessage::MSG_HACK_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendObjectIDArgument( obj->getID() );
- }
- } // end else if
- // ********************************************************************************************
- else if( draw && TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_STEAL_CASH_VIA_HACKING, obj, InGameUI::SELECTION_ANY ) )
- {
-
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
- //@TODO: Kris
- //PRELIMINARY CODE FOR HOOKING IN AUTO SPECIALS --- WILL BE REDONE!
- Object *source = TheInGameUI->getFirstSelectedDrawable()->getObject();
- const CommandSet *set = TheControlBar->findCommandSet( source->getCommandSetString() );
- if( set )
- {
- for( Int i = 0; i < MAX_COMMANDS_PER_SET; i++ )
- {
- // get command button
- const CommandButton *command = set->getCommandButton(i);
- if( command && command->getCommandType() == GUI_COMMAND_SPECIAL_POWER )
- {
- SpecialPowerType spType = command->getSpecialPowerTemplate()->getSpecialPowerType();
- if( spType == SPECIAL_BLACKLOTUS_STEAL_CASH_HACK )
- {
- msgType = issueSpecialPowerCommand( command, type, draw, pos, NULL );
- break;
- }
- }
- }
- }
- } // end if
- else
- {
- msgType = GameMessage::MSG_HACK_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendObjectIDArgument( obj->getID() );
- }
- } // end else if
- // ********************************************************************************************
- else if( draw && TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_DISABLE_BUILDING_VIA_HACKING, obj, InGameUI::SELECTION_ANY ) )
- {
-
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
- //@TODO: Kris
- //PRELIMINARY CODE FOR HOOKING IN AUTO SPECIALS --- WILL BE REDONE!
- Object *source = TheInGameUI->getFirstSelectedDrawable()->getObject();
- const CommandSet *set = TheControlBar->findCommandSet( source->getCommandSetString() );
- if( set )
- {
- for( Int i = 0; i < MAX_COMMANDS_PER_SET; i++ )
- {
- // get command button
- const CommandButton *command = set->getCommandButton(i);
- if( command && command->getCommandType() == GUI_COMMAND_SPECIAL_POWER )
- {
- SpecialPowerType spType = command->getSpecialPowerTemplate()->getSpecialPowerType();
- if( spType == SPECIAL_HACKER_DISABLE_BUILDING )
- {
- msgType = issueSpecialPowerCommand( command, type, draw, pos, NULL );
- break;
- }
- }
- }
- }
- } // end if
- else
- {
- msgType = GameMessage::MSG_HACK_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendObjectIDArgument( obj->getID() );
- }
- } // end else if
- #ifdef ALLOW_SURRENDER
- // ********************************************************************************************
- else if( draw && TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_PICK_UP_PRISONER, obj, InGameUI::SELECTION_ANY ) )
- {
-
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
- // issue the command
- msgType = issueAttackCommand( draw, type, GUICOMMANDMODE_PICK_UP_PRISONER );
-
- } // end if
- else
- {
-
- msgType = GameMessage::MSG_PICK_UP_PRISONER_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendObjectIDArgument( obj->getID() );
- } // end else
- } // end else if
- #endif
- // ********************************************************************************************
- else if ( pos && !draw && TheInGameUI->canSelectedObjectsDoAction( InGameUI::ACTIONTYPE_SET_RALLY_POINT, NULL, InGameUI::SELECTION_ALL, FALSE ))
- {
- msgType = GameMessage::MSG_SET_RALLY_POINT;
- if (type == DO_COMMAND) {
- const DrawableList *allSelectedDrawables = TheInGameUI->getAllSelectedDrawables();
-
- for (DrawableList::const_iterator it = allSelectedDrawables->begin(); it != allSelectedDrawables->end(); ++it) {
- Drawable *draw = (*it);
- if (draw && draw->getObject()) {
- GameMessage *newMsg = TheMessageStream->appendMessage(msgType);
- newMsg->appendObjectIDArgument(draw->getObject()->getID());
- newMsg->appendLocationArgument(*pos);
- }
- }
- } else if (type == DO_HINT) {
- msgType = GameMessage::MSG_SET_RALLY_POINT_HINT;
- hintMessage = TheMessageStream->appendMessage(msgType);
- hintMessage->appendLocationArgument(*pos);
- }
- }
- // ********************************************************************************************
- else if( draw && result == ATTACKRESULT_INVALID_SHOT )
- {
- msgType = GameMessage::MSG_IMPOSSIBLE_ATTACK_HINT;
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendLocationArgument( *pos );
- } // end else if
- // ********************************************************************************************
- else
- {
- //
- // NOTE: If you change this command evaluation function in what it will do
- // if there is nothing picked ... you might want to edit the logic of the
- // selection translator in that you can only select objects if there is
- // no "interesting" command to do with the picked drawable ... which is determined
- // by what we return in this function by default
- //
- //Before we issue a move order or hint, check to see if we can even move there!
- Bool validQuickPath = FALSE;
- // Make sure to only to the check if the shroud is CLEARED. If it is fogged or shrouded, SKIP THE CHECK. jba [3/11/2003]
- if( ThePartitionManager->getShroudStatusForPlayer( ThePlayerList->getLocalPlayer()->getPlayerIndex(), pos ) != CELLSHROUD_CLEAR )
- {
- //If it's in the shroud, pretend we can move there -- skip the check.
- validQuickPath = TRUE;
- }
- else
- {
- //Can we path there?
- const DrawableList *allSelectedDrawables = TheInGameUI->getAllSelectedDrawables();
- for( DrawableList::const_iterator it = allSelectedDrawables->begin(); it != allSelectedDrawables->end(); ++it )
- {
- Object *obj = (*it) ? (*it)->getObject() : NULL;
- AIUpdateInterface *ai = obj ? obj->getAI() : NULL;
- if( ai )
- {
- if ( ai->isQuickPathAvailable( pos ) )
- {
- validQuickPath = TRUE;
- break;
- }
- // Wait! there are some units that CAN moveTo positions that Quickpath will reject,
- // namely, Colonel Burton and the CombatBike. Both have CLIFF locomotors.
- // We must detect whether the position is valid for these, before just invalidating the cursor,
- // out of hand.
- if ( ai->hasLocomotorForSurface( LOCOMOTORSURFACE_CLIFF ) )
- {
- if ( TheTerrainLogic->isCliffCell( pos->x, pos->y ) )
- {
- validQuickPath = TRUE;// yeah, not really quick, but you know...
- break;
- }
- }
- }
- }
- }
- if( type == DO_COMMAND || type == EVALUATE_ONLY )
- {
- // issue command
- // Note: If draw is valid, then its one of ours and we don't have something more specific
- // to do. Therefore, lets not issue a move command, and instead we'll return that there
- // wasn't a command for us to perform.
-
- if ( draw == NULL )
- msgType = issueMoveToLocationCommand( pos, drawableInWay, type );
- } // end if
- else
- {
- if( !validQuickPath )
- {
- msgType = GameMessage::MSG_DO_INVALID_HINT;
- }
- else if( TheInGameUI->isInWaypointMode() )
- {
- //Waypoint mode
- msgType = GameMessage::MSG_ADD_WAYPOINT_HINT;
- }
- else if( TheInGameUI->isInAttackMoveToMode() )
- {
- //THIS CODE WILL NEVER EVER GET CALLED! -- it's a context command now (READ: rip code out)
- //Attack move
- msgType = GameMessage::MSG_DO_ATTACKMOVETO_HINT;
- }
- else
- {
- //Normal and forced move.
- msgType = GameMessage::MSG_DO_MOVETO_HINT;
- }
- hintMessage = TheMessageStream->appendMessage( msgType );
- hintMessage->appendLocationArgument( *pos );
- } // end else
- } // end else
- } // end if
- // return the message type
- return msgType;
- } // end evaluateContextCommand
- // ------------------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------------------
- //====================================================================================
- /**
- * The Command Translator translates mouse events into object command messages
- * such as move_to, attack, etc.
- */
- GameMessageDisposition CommandTranslator::translateGameMessage(const GameMessage *msg)
- {
- GameMessage::Type t = msg->getType();
- GameMessageDisposition disp = KEEP_MESSAGE;
- // We want to always be able to get to the options menu even during no input times and a clear game data message should always go through
- if (t != GameMessage::MSG_META_OPTIONS && t != GameMessage::MSG_CLEAR_GAME_DATA &&
- !TheInGameUI->getInputEnabled() && !isSystemMessage(msg))
- {
- return DESTROY_MESSAGE;
- }
- #if defined(_DEBUG) || defined(_INTERNAL)
- ExtentModType extentModType = EXTENTMOD_INVALID;
- Real extentModAmount = 0.0f;
- #endif
- switch (t)
- {
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_SELECT_MATCHING_UNITS:
- {
- TheInGameUI->selectUnitsMatchingCurrentSelection();
- disp = DESTROY_MESSAGE;
- break;
- }
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_SELECT_NEXT_UNIT:
- {
- /* because list is prepended, iterate through backwards */
-
- // if there is nothing on the screen, bail
- if( TheGameClient->firstDrawable() == NULL )
- break;
- // if nothing is selected
- Drawable *temp;
- if( TheInGameUI->getSelectCount() == 0 )
- {
- // get the last drawable
- for( temp = TheGameClient->firstDrawable(); temp->getNextDrawable() != NULL; temp = temp->getNextDrawable() )
- {
- }
- // temp is the last drawable
- for( temp; temp != NULL; temp = temp->getPrevDrawable() )
- {
- const Object *object = temp->getObject();
- // if you've reached the end of the list, don't select anything
- if( !object )
- {
- break;
- }
- else if( object && object->isMobile() && object->isLocallyControlled() && !object->isContained() && !object->isKindOf( KINDOF_NO_SELECT ) )
- {
- // create a new group.
- GameMessage *teamMsg = TheMessageStream->appendMessage( GameMessage::MSG_CREATE_SELECTED_GROUP );
- //New group or add to group? Passed in value is true if we are creating a new group.
- teamMsg->appendBooleanArgument( TRUE );
- teamMsg->appendObjectIDArgument( object->getID() );
- TheInGameUI->selectDrawable( temp );
- // center on the unit
- TheTacticalView->lookAt(temp->getPosition());
- break;
- }
- }
- }
- else
- {
- Drawable *newDrawable = NULL;
- Bool hack = FALSE;
- Drawable *selectedDrawable = TheInGameUI->getFirstSelectedDrawable();
- Object *selectedObject = selectedDrawable->getObject();
- if( selectedObject->isLocallyControlled() )
- {
- // find the previous selectable drawable
- temp = selectedDrawable->getPrevDrawable();
- //temp = selectedDrawable;
- for( ; temp != selectedDrawable; temp = temp->getPrevDrawable() )
- {
- if( hack == TRUE )
- {
- temp = temp->getNextDrawable();
- hack = FALSE;
- }
- // if temp is null, set it to the last drawable and loop back to selected drawable
- if( temp == NULL )
- {
- for(temp = selectedDrawable; temp->getNextDrawable() != NULL; temp = temp->getNextDrawable() )
- {
- }
- hack = TRUE;
- }
- // else search for a previous selectable drawable
- else
- {
- const Object *tempObject = temp->getObject();
- if( tempObject && tempObject->isMobile() && tempObject->isLocallyControlled() && !tempObject->isContained() && !tempObject->isKindOf( KINDOF_NO_SELECT ) )
- {
- newDrawable = temp;
- break;
- //temp = selectedDrawable; // same as break
- }
- }
- }
- //if there is another selectable unit, select it
- if(newDrawable != NULL )
- {
- //deselect other units
- TheInGameUI->deselectAllDrawables();
- // create a new group.
- GameMessage *teamMsg = TheMessageStream->appendMessage( GameMessage::MSG_CREATE_SELECTED_GROUP );
- //New group or add to group? Passed in value is true if we are creating a new group.
- teamMsg->appendBooleanArgument( TRUE );
- teamMsg->appendObjectIDArgument( newDrawable->getObject()->getID() );
- // select the unit
- TheInGameUI->selectDrawable( newDrawable );
- // center on the unit
- TheTacticalView->lookAt(newDrawable->getPosition());
- }
- }
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_SELECT_PREV_UNIT:
- {
- /* because list is prepended, iterate through forwards */
- // if there is nothing on the screen, bail
- if( TheGameClient->firstDrawable() == NULL )
- break;
- Drawable *temp;
- // if nothing is selected
- if( TheInGameUI->getSelectCount() == 0 )
- {
- // get the first drawable
- temp = TheGameClient->firstDrawable();
- for( temp; temp != NULL; temp = temp->getPrevDrawable() )
- {
- const Object *object = temp->getObject();
- // if you've reached the end of the list, don't select anything
- if( !object )
- {
- break;
- }
- else if( object && object->isMobile() && object->isLocallyControlled() && !object->isContained() && !object->isKindOf( KINDOF_NO_SELECT ) )
- {
- // create a new group.
- GameMessage *teamMsg = TheMessageStream->appendMessage( GameMessage::MSG_CREATE_SELECTED_GROUP );
- //New group or add to group? Passed in value is true if we are creating a new group.
- teamMsg->appendBooleanArgument( TRUE );
- teamMsg->appendObjectIDArgument( object->getID() );
-
- TheInGameUI->selectDrawable( temp );
- // center on the unit
- TheTacticalView->lookAt(temp->getPosition());
- break;
- }
- }
- }
- else
- {
- Drawable *newDrawable = NULL;
- TheGameClient->getDrawableList();
- Bool hack = FALSE; // takes care of when for loop skips firstdrawable
- Drawable *selectedDrawable = TheInGameUI->getFirstSelectedDrawable();
- Object *selectedObject = selectedDrawable->getObject();
- if( selectedObject->isLocallyControlled() )
- {
- // find the next selectable drawable
- temp = selectedDrawable->getNextDrawable();
- //temp = selectedDrawable;
- for( temp; temp != selectedDrawable; temp = temp->getNextDrawable() )
- {
- if( hack == TRUE )
- {
- temp = TheGameClient->firstDrawable();
- hack = FALSE;
- if( temp == selectedDrawable )
- {
- break;
- }
- }
- // if temp is null, set it to the first drawable and loop forward to selected drawable
- if( temp == NULL )
- {
- temp = TheGameClient->firstDrawable();
- hack = TRUE;
- const Object *tempObject = temp->getObject();
- // must take case of this case here or else the loop will break without getting newDrawable
- if( tempObject && temp->getNextDrawable() == selectedDrawable && !temp->isSelected()
- && tempObject->isMobile() && tempObject->isLocallyControlled() && !tempObject->isContained() && !tempObject->isKindOf( KINDOF_NO_SELECT ) )
- {
- newDrawable = temp;
- break;
- }
- }
- // else search for a next selectable drawable
- else
- {
- const Object *tempObject = temp->getObject();
- if( tempObject && !temp->isSelected() && tempObject->isMobile() && tempObject->isLocallyControlled() && !tempObject->isContained() )
- {
- newDrawable = temp;
- break;
- }
- }
- }
- //if there is another selectable unit, select it
- if(newDrawable != NULL )
- {
- //deselect other units
- TheInGameUI->deselectAllDrawables();
- // select the unit
-
- // create a new group.
- GameMessage *teamMsg = TheMessageStream->appendMessage( GameMessage::MSG_CREATE_SELECTED_GROUP );
- //New group or add to group? Passed in value is true if we are creating a new group.
- teamMsg->appendBooleanArgument( TRUE );
- teamMsg->appendObjectIDArgument( newDrawable->getObject()->getID() );
- TheInGameUI->selectDrawable( newDrawable );
- // center on the unit
- TheTacticalView->lookAt(newDrawable->getPosition());
- }
- }
- }
- disp = DESTROY_MESSAGE;
- break;
- } // end select previous unit
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_SELECT_NEXT_WORKER:
- {
- /* because list is prepended, iterate through backwards */
- // if there is nothing on the screen, bail
- if( TheGameClient->firstDrawable() == NULL )
- break;
- Drawable *temp;
- // if nothing is selected
- if( TheInGameUI->getSelectCount() == 0 )
- {
- // get the last drawable
- for( temp = TheGameClient->firstDrawable(); temp->getNextDrawable() != NULL; temp = temp->getNextDrawable() )
- {
- }
- // temp is the last drawable
- for( temp; temp != NULL; temp = temp->getPrevDrawable() )
- {
- const Object *object = temp->getObject();
- // if you've reached the end of the list, don't select anything
- if( !object )
- {
- break;
- }
- // make sure you select only workers
- else if( object && object->isLocallyControlled() && !object->isContained() && object->isKindOf(KINDOF_DOZER) )
- {
- // create a new group.
- GameMessage *teamMsg = TheMessageStream->appendMessage( GameMessage::MSG_CREATE_SELECTED_GROUP );
- //New group so pass in value true
- teamMsg->appendBooleanArgument( TRUE );
- teamMsg->appendObjectIDArgument( object->getID() );
- TheInGameUI->selectDrawable( temp );
- // play the units sound
- AudioEventRTS soundEvent = *temp->getTemplate()->getVoiceSelect();
- soundEvent.setObjectID(object->getID());
- TheAudio->addAudioEvent( &soundEvent );
- // center on the unit
- TheTacticalView->lookAt(temp->getPosition());
- break;
- }
- }
- }
- else
- {
- Drawable *newDrawable = NULL;
- Bool hack = FALSE;
- Drawable *selectedDrawable = TheInGameUI->getFirstSelectedDrawable();
- Object *selectedObject = selectedDrawable->getObject();
- if( selectedObject->isLocallyControlled() )
- {
- // find the previous selectable drawable
- temp = selectedDrawable->getPrevDrawable();
- //temp = selectedDrawable;
- for( ; temp != selectedDrawable; temp = temp->getPrevDrawable() )
- {
- if( hack == TRUE )
- {
- temp = temp->getNextDrawable();
- hack = FALSE;
- }
- // if temp is null, set it to the last drawable and loop back to selected drawable
- if( temp == NULL )
- {
- for(temp = selectedDrawable; temp->getNextDrawable() != NULL; temp = temp->getNextDrawable() )
- {
- }
- hack = TRUE;
- }
- // else search for a previous selectable drawable
- else
- {
- const Object *tempObject = temp->getObject();
- if( tempObject && tempObject->isLocallyControlled() && !tempObject->isContained() && tempObject->isKindOf( KINDOF_DOZER ) )
- {
- newDrawable = temp;
- break;
- //temp = selectedDrawable; // same as break
- }
- }
- }
- //if there is another selectable unit, select it
- if(newDrawable != NULL )
- {
- //deselect other units
- TheInGameUI->deselectAllDrawables();
- // select the unit
- // create a new group.
- GameMessage *teamMsg = TheMessageStream->appendMessage( GameMessage::MSG_CREATE_SELECTED_GROUP );
- //New group so pass in value true
- teamMsg->appendBooleanArgument( TRUE );
- teamMsg->appendObjectIDArgument( newDrawable->getObject()->getID() );
- TheInGameUI->selectDrawable( newDrawable );
- // center on the unit
- TheTacticalView->lookAt(newDrawable->getPosition());
- }
- }
- }
- disp = DESTROY_MESSAGE;
- break;
- } // end select next worker
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_SELECT_PREV_WORKER:
- {
- /* because list is prepended, iterate through forwards */
- // if there is nothing on the screen, bail
- if( TheGameClient->firstDrawable() == NULL )
- break;
- Drawable *temp;
- // if nothing is selected
- if( TheInGameUI->getSelectCount() == 0 )
- {
- // get the first drawable
- temp = TheGameClient->firstDrawable();
- for( temp; temp != NULL; temp = temp->getPrevDrawable() )
- {
- const Object *object = temp->getObject();
- // if you've reached the end of the list, don't select anything
- if( !object )
- {
- break;
- }
- else if( object && object->isMobile() && object->isLocallyControlled() && !object->isContained() && object->isKindOf( KINDOF_DOZER ))
- {
- // create a new group.
- GameMessage *teamMsg = TheMessageStream->appendMessage( GameMessage::MSG_CREATE_SELECTED_GROUP );
- //New group or add to group? Passed in value is true if we are creating a new group.
- teamMsg->appendBooleanArgument( TRUE );
- teamMsg->appendObjectIDArgument( object->getID() );
-
- TheInGameUI->selectDrawable( temp );
- // center on the unit
- TheTacticalView->lookAt(temp->getPosition());
- break;
- }
- }
- }
- else
- {
- Drawable *newDrawable = NULL;
- TheGameClient->getDrawableList();
- Bool hack = FALSE; // takes care of when for loop skips firstdrawable
- Drawable *selectedDrawable = TheInGameUI->getFirstSelectedDrawable();
- Object *selectedObject = selectedDrawable->getObject();
- if( selectedObject->isLocallyControlled() )
- {
- // find the next selectable drawable
- temp = selectedDrawable->getNextDrawable();
- //temp = selectedDrawable;
- for( temp; temp != selectedDrawable; temp = temp->getNextDrawable() )
- {
- if( hack == TRUE )
- {
- temp = TheGameClient->firstDrawable();
- hack = FALSE;
- if( temp == selectedDrawable )
- {
- break;
- }
- }
- // if temp is null, set it to the first drawable and loop forward to selected drawable
- if( temp == NULL )
- {
- temp = TheGameClient->firstDrawable();
- hack = TRUE;
- const Object *tempObject = temp->getObject();
- // must take case of this case here or else the loop will break without getting newDrawable
- if( tempObject && temp->getNextDrawable() == selectedDrawable && !temp->isSelected()
- && tempObject->isMobile() && tempObject->isLocallyControlled() && !tempObject->isContained() )
- {
- newDrawable = temp;
- break;
- }
- }
- // else search for a next selectable drawable
- else
- {
- const Object *tempObject = temp->getObject();
- if( tempObject && !temp->isSelected() && tempObject->isMobile()
- && tempObject->isLocallyControlled() && !tempObject->isContained() && tempObject->isKindOf( KINDOF_DOZER ) )
- {
- newDrawable = temp;
- break;
- }
- }
- }
- //if there is another selectable unit, select it
- if(newDrawable != NULL )
- {
- //deselect other units
- TheInGameUI->deselectAllDrawables();
- // select the unit
-
- // create a new group.
- GameMessage *teamMsg = TheMessageStream->appendMessage( GameMessage::MSG_CREATE_SELECTED_GROUP );
- //New group so passed in value true
- teamMsg->appendBooleanArgument( TRUE );
- teamMsg->appendObjectIDArgument( newDrawable->getObject()->getID() );
- TheInGameUI->selectDrawable( newDrawable );
- // center on the unit
- TheTacticalView->lookAt(newDrawable->getPosition());
- }
- }
- }
- disp = DESTROY_MESSAGE;
- break;
- } // end select previous worker
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_SELECT_HERO:
- {
- // if there is nothing on the screen, bail
- if( TheGameClient->firstDrawable() == NULL )
- break;
- Object *hero = iNeedAHero();
- if ( hero == NULL )
- break;
- if ( hero->isContained() )
- hero = hero->getContainedBy();
- Drawable *heroDraw = hero->getDrawable();
- if ( heroDraw == NULL )
- break;
- TheInGameUI->deselectAllDrawables();
- // create a new group.
- GameMessage *teamMsg = TheMessageStream->appendMessage( GameMessage::MSG_CREATE_SELECTED_GROUP );
-
- //New group so pass in value true
- teamMsg->appendBooleanArgument( TRUE );
- teamMsg->appendObjectIDArgument( hero->getID() );
- TheInGameUI->selectDrawable( heroDraw );
- // center on the unit
- TheTacticalView->lookAt(heroDraw->getPosition());
- disp = DESTROY_MESSAGE;
- break;
- }
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_VIEW_COMMAND_CENTER:
- viewCommandCenter();
- disp = DESTROY_MESSAGE;
- break;
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_VIEW_LAST_RADAR_EVENT:
- {
- // Player *player = ThePlayerList->getLocalPlayer();
- // if the local player has a radar, center on last event (if any)
- // Excuse me? You don't need radar for the spacebar. That's silly.
- // if( TheRadar->isRadarForced() || ( TheRadar->isRadarHidden() == false && player->hasRadar() ) )
- {
- Coord3D lastEvent;
- if( TheRadar->getLastEventLoc( &lastEvent ) )
- TheTacticalView->lookAt( &lastEvent );
- } // end if
- disp = DESTROY_MESSAGE;
- break;
- } // end view last radar event
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_SELECT_ALL:
- case GameMessage::MSG_META_SELECT_ALL_AIRCRAFT:
- {
- KindOfMaskType requiredKindofs;
- KindOfMaskType disqualifyingKindofs;
- disqualifyingKindofs.set(KINDOF_DOZER);
- disqualifyingKindofs.set(KINDOF_HARVESTER);
- disqualifyingKindofs.set(KINDOF_IGNORES_SELECT_ALL);
- Bool selectAircraft = FALSE;
-
- if( t == GameMessage::MSG_META_SELECT_ALL_AIRCRAFT )
- {
- requiredKindofs.set(KINDOF_AIRCRAFT);
- selectAircraft = TRUE;
- }
- //Kris: Patch 1.03. We need to deselect all the units if any of the units we have selected
- //are incompatible with the select all type we are triggering. This is a fix for the SCUDSTORM
- //exploit.
- const DrawableList *drawList = TheInGameUI->getAllSelectedDrawables();
- Drawable *draw;
- for( DrawableListCIt it = drawList->begin(); it != drawList->end(); ++it )
- {
- draw = *it;
- if( selectAircraft && (draw->isAnyKindOf( disqualifyingKindofs ) || !draw->isKindOf( KINDOF_AIRCRAFT )) )
- {
- TheInGameUI->deselectAllDrawables();
- break;
- }
- else if( !selectAircraft && (draw->isAnyKindOf( disqualifyingKindofs ) || draw->isKindOf( KINDOF_STRUCTURE )) )
- {
- TheInGameUI->deselectAllDrawables();
- break;
- }
- }
- TheInGameUI->selectAllUnitsByType(requiredKindofs, disqualifyingKindofs);
- disp = DESTROY_MESSAGE;
- break;
- /*
- TheInGameUI->deselectAllDrawables();
- GameMessage *teamMsg = TheMessageStream->appendMessage( GameMessage::MSG_CREATE_SELECTED_GROUP );
- // creating a new team so pass in true
- teamMsg->appendBooleanArgument( TRUE );
- // just loop through all the drawables in the world
- Drawable *draw = TheGameClient->firstDrawable();
- while( draw )
- {
- const Object *object = draw->getObject();
- //Only select the object if it is locally controlled and not contained by anything.
- KindOfMaskType disqualifyingKindofs;
- disqualifyingKindofs.set(KINDOF_DOZER);
- disqualifyingKindofs.set(KINDOF_HARVESTER);
- disqualifyingKindofs.set(KINDOF_IGNORES_SELECT_ALL);
- if( object
- && object->isMobile()
- && object->isLocallyControlled()
- && !object->isContained()
- && !object->isAnyKindOf( disqualifyingKindofs )
- && !object->isEffectivelyDead()
- && object->isMassSelectable()
- )
- {
- // enforce optional unit cap
- if (TheInGameUI->getMaxSelectCount() > 0 && TheInGameUI->getSelectCount() >= TheInGameUI->getMaxSelectCount())
- {
- if ( !TheInGameUI->getDisplayedMaxWarning() )
- {
- TheInGameUI->setDisplayedMaxWarning( TRUE );
- UnicodeString msg;
- msg.format(TheGameText->fetch("GUI:MaxSelectionSize").str(), TheInGameUI->getMaxSelectCount());
- TheInGameUI->message(msg);
- }
- }
- else
- {
- TheInGameUI->selectDrawable(draw);
- teamMsg->appendObjectIDArgument( draw->getObject()->getID() );
- TheInGameUI->setDisplayedMaxWarning( FALSE );
- }
- }
- draw = draw->getNextDrawable();
- }
- if( TheInGameUI->getSelectCount() )
- {
- UnicodeString message = TheGameText->fetch( "GUI:SelectedAcrossMap" );
- TheInGameUI->message( message );
- }
- disp = DESTROY_MESSAGE;
- break;
- */
- } // end select all
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_SCATTER:
- // This message always works on the currently selected team
- TheMessageStream->appendMessage(GameMessage::MSG_DO_SCATTER);
- disp = DESTROY_MESSAGE;
- break;
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_STOP:
- // This message always works on the currently selected team
- TheMessageStream->appendMessage(GameMessage::MSG_DO_STOP);
- disp = DESTROY_MESSAGE;
- break;
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_CREATE_FORMATION:
- // This message always works on the currently selected team
- TheMessageStream->appendMessage(GameMessage::MSG_CREATE_FORMATION);
- disp = DESTROY_MESSAGE;
- break;
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEPLOY:
- #ifdef _DEBUG
- DEBUG_ASSERTCRASH(FALSE, ("unimplemented meta command MSG_META_DEPLOY !"));
- #endif
- /// @todo srj implement me
- disp = DESTROY_MESSAGE;
- break;
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_FOLLOW:
- #ifdef _DEBUG
- DEBUG_ASSERTCRASH(FALSE, ("unimplemented meta command MSG_META_FOLLOW !"));
- #endif
- /// @todo srj implement me
- disp = DESTROY_MESSAGE;
- break;
- //-----------------------------------------------------------------------------------------
- /* MDC - no such thing as chat to players right now - not until we have a diplomacy screen
- case GameMessage::MSG_META_CHAT_PLAYERS:
- if (TheGameLogic->isInMultiplayerGame() && !TheGameLogic->isInReplayGame())
- {
- ToggleInGameChat();
- SetInGameChatType( INGAME_CHAT_PLAYERS );
- }
- disp = DESTROY_MESSAGE;
- break;
- */
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_CHAT_ALLIES:
- if (TheGameLogic->isInMultiplayerGame() && !TheGameLogic->isInReplayGame())
- {
- Player *localPlayer = ThePlayerList->getLocalPlayer();
- if (localPlayer && localPlayer->isPlayerActive() || !TheGlobalData->m_netMinPlayers)
- {
- ToggleInGameChat();
- SetInGameChatType( INGAME_CHAT_ALLIES );
- }
- }
- disp = DESTROY_MESSAGE;
- break;
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_CHAT_EVERYONE:
- if (TheGameLogic->isInMultiplayerGame() && !TheGameLogic->isInReplayGame())
- {
- Player *localPlayer = ThePlayerList->getLocalPlayer();
- if (localPlayer && localPlayer->isPlayerActive() || !TheGlobalData->m_netMinPlayers)
- {
- ToggleInGameChat();
- SetInGameChatType( INGAME_CHAT_EVERYONE );
- }
- }
- disp = DESTROY_MESSAGE;
- break;
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DIPLOMACY:
- if (TheGameLogic->isInGame() && !TheGameLogic->isInShellGame())
- {
- ToggleDiplomacy( FALSE );
- }
- else if( TheShell && TheShell->isShellActive() && TheGameSpyBuddyMessageQueue)
- GameSpyToggleOverlay(GSOVERLAY_BUDDY);
- disp = DESTROY_MESSAGE;
- break;
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_PLACE_BEACON:
- if (TheGameLogic->isInMultiplayerGame() && !TheGameLogic->isInReplayGame() &&
- ThePlayerList->getLocalPlayer()->isPlayerActive() &&
- (TheGlobalData->m_netMinPlayers==0 || TheGameInfo->isMultiPlayer()))
- {
- Int count;
- const ThingTemplate *thing = TheThingFactory->findTemplate( ThePlayerList->getLocalPlayer()->getPlayerTemplate()->getBeaconTemplate() );
- ThePlayerList->getLocalPlayer()->countObjectsByThingTemplate( 1, &thing, false, &count );
- DEBUG_LOG(("MSG_META_PLACE_BEACON - Player already has %d beacons active\n", count));
- if (count < TheMultiplayerSettings->getMaxBeaconsPerPlayer())
- {
- const CommandButton *commandButton = TheControlBar->findCommandButton( "Command_PlaceBeacon" );
- TheInGameUI->setGUICommand( commandButton );
- }
- }
- disp = DESTROY_MESSAGE;
- break;
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_REMOVE_BEACON:
- if (TheGameLogic->isInMultiplayerGame() && !TheGameLogic->isInReplayGame())
- {
- TheMessageStream->appendMessage( GameMessage::MSG_REMOVE_BEACON );
- }
- disp = DESTROY_MESSAGE;
- break;
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_OPTIONS:
-
- ToggleQuitMenu();
- disp = DESTROY_MESSAGE;
- break;
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_TOGGLE_LOWER_DETAILS:
- {
- if (TheGlobalData)
- {
- static Bool isLowDetails = FALSE;
- static Bool oldShadowVolumsValue = TRUE;
- static Bool oldLightMapValue = TRUE;
- static Bool oldCloudMap = TRUE;
- static Bool oldBehindBuildingMarkers = TRUE;
- static Int oldMaxParticleCount = 0;
- if(isLowDetails)
- {
- TheWritableGlobalData->m_useShadowVolumes = oldShadowVolumsValue;
- TheWritableGlobalData->m_useLightMap = oldLightMapValue;
- TheWritableGlobalData->m_useCloudMap = oldCloudMap;
- TheWritableGlobalData->m_maxParticleCount = oldMaxParticleCount;
- TheGameLogic->setShowBehindBuildingMarkers(oldBehindBuildingMarkers);
- if(TheInGameUI)
- TheInGameUI->message("GUI:ReturnGraphicsToPreviousSettings");
- }
- else
- {
- oldShadowVolumsValue = TheGlobalData->m_useShadowVolumes;
- TheWritableGlobalData->m_useShadowVolumes = FALSE;
- oldLightMapValue = TheGlobalData->m_useLightMap;
- TheWritableGlobalData->m_useLightMap = FALSE;
- oldCloudMap = TheGlobalData->m_useCloudMap;
- TheWritableGlobalData->m_useCloudMap = FALSE;
-
- oldBehindBuildingMarkers = TheGameLogic->getShowBehindBuildingMarkers();
- TheGameLogic->setShowBehindBuildingMarkers(FALSE);
- oldMaxParticleCount = TheGlobalData->m_maxParticleCount;
- TheWritableGlobalData->m_maxParticleCount = DROPPED_MAX_PARTICLE_COUNT;
-
- if(TheInGameUI)
- TheInGameUI->message("GUI:DetailsSetToLowest");
- }
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_TOGGLE_CONTROL_BAR:
- {
- if(TheShell->isShellActive())
- {
- WindowLayout *win = TheShell->top();
- if(win)
- {
- win->hide(!win->isHidden());
- }
- }
- else
- {
- if (!(TheRecorder && TheRecorder->getMode() == RECORDERMODETYPE_PLAYBACK))
- {
- Bool hide = false;
- if (TheWindowManager)
- {
- Int id = (Int)TheNameKeyGenerator->nameToKey(AsciiString("ControlBar.wnd:ControlBarParent"));
- GameWindow *window = TheWindowManager->winGetWindowFromId(NULL, id);
- if (window)
- hide = !window->winIsHidden();
- }
- ToggleControlBar();
- }
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_TOGGLE_ATTACKMOVE:
- TheInGameUI->toggleAttackMoveToMode( );
- break;
- case GameMessage::MSG_META_BEGIN_CAMERA_ROTATE_LEFT:
- DEBUG_ASSERTCRASH(!TheInGameUI->isCameraRotatingLeft(), ("Setting rotate camera left, but it's already set!"));
- TheInGameUI->setCameraRotateLeft( true );
- break;
- case GameMessage::MSG_META_END_CAMERA_ROTATE_LEFT:
- DEBUG_ASSERTCRASH(TheInGameUI->isCameraRotatingLeft(), ("Clearing rotate camera left, but it's already clear!"));
- TheInGameUI->setCameraRotateLeft( false );
- break;
- case GameMessage::MSG_META_BEGIN_CAMERA_ROTATE_RIGHT:
- DEBUG_ASSERTCRASH(!TheInGameUI->isCameraRotatingRight(), ("Setting rotate camera right, but it's already set!"));
- TheInGameUI->setCameraRotateRight( true );
- break;
- case GameMessage::MSG_META_END_CAMERA_ROTATE_RIGHT:
- DEBUG_ASSERTCRASH(TheInGameUI->isCameraRotatingRight(), ("Clearing rotate camera right, but it's already clear!"));
- TheInGameUI->setCameraRotateRight( false );
- break;
- case GameMessage::MSG_META_BEGIN_CAMERA_ZOOM_IN:
- DEBUG_ASSERTCRASH(!TheInGameUI->isCameraZoomingIn(), ("Setting zoom camera in, but it's already set!"));
- TheInGameUI->setCameraZoomIn( true );
- break;
- case GameMessage::MSG_META_END_CAMERA_ZOOM_IN:
- DEBUG_ASSERTCRASH(TheInGameUI->isCameraZoomingIn(), ("Clearing zoom camera in, but it's already clear!"));
- TheInGameUI->setCameraZoomIn( false );
- break;
- case GameMessage::MSG_META_BEGIN_CAMERA_ZOOM_OUT:
- DEBUG_ASSERTCRASH(!TheInGameUI->isCameraZoomingOut(), ("Setting zoom camera out, but it's already set!"));
- TheInGameUI->setCameraZoomOut( true );
- break;
- case GameMessage::MSG_META_END_CAMERA_ZOOM_OUT:
- DEBUG_ASSERTCRASH(TheInGameUI->isCameraZoomingOut(), ("Clearing zoom camera out, but it's already clear!"));
- TheInGameUI->setCameraZoomOut( false );
- break;
- case GameMessage::MSG_META_CAMERA_RESET:
- TheInGameUI->resetCamera();
- break;
- case GameMessage::MSG_META_TOGGLE_CAMERA_TRACKING_DRAWABLE:
- TheInGameUI->setCameraTrackingDrawable( true );
- break;
- //--------------------------------------------------------------------------------------
- case GameMessage::MSG_META_TOGGLE_FAST_FORWARD_REPLAY:
- {
- if( TheGlobalData )
- {
- #if !defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE)//may be defined in GameCommon.h
- if (TheGameLogic->isInReplayGame())
- #endif
- {
- TheWritableGlobalData->m_TiVOFastMode = 1 - TheGlobalData->m_TiVOFastMode;
- TheInGameUI->message( UnicodeString( L"m_TiVOFastMode: %s" ),
- TheGlobalData->m_TiVOFastMode ? L"ON" : L"OFF" );
- }
- } // end if
- disp = DESTROY_MESSAGE;
- break;
- } // end toggle special power delays
- #if defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE)//may be defined in GameCommon.h
- case GameMessage::MSG_CHEAT_RUNSCRIPT1:
- case GameMessage::MSG_CHEAT_RUNSCRIPT2:
- case GameMessage::MSG_CHEAT_RUNSCRIPT3:
- case GameMessage::MSG_CHEAT_RUNSCRIPT4:
- case GameMessage::MSG_CHEAT_RUNSCRIPT5:
- case GameMessage::MSG_CHEAT_RUNSCRIPT6:
- case GameMessage::MSG_CHEAT_RUNSCRIPT7:
- case GameMessage::MSG_CHEAT_RUNSCRIPT8:
- case GameMessage::MSG_CHEAT_RUNSCRIPT9:
- {
- if ( !TheGameLogic->isInMultiplayerGame() )
- {
- if( TheScriptEngine )
- {
- Int script = t - GameMessage::MSG_CHEAT_RUNSCRIPT1 + 1;
- AsciiString scriptName;
- scriptName.format("KEY_F%d", script);
- TheScriptEngine->runScript(scriptName);
- }
- disp = DESTROY_MESSAGE;
- }
- break;
- }
- //--------------------------------------------------------------------------------------
- case GameMessage::MSG_CHEAT_TOGGLE_SPECIAL_POWER_DELAYS:
- {
- if ( !TheGameLogic->isInMultiplayerGame() )
- {
- if( TheGlobalData )
- {
- TheWritableGlobalData->m_specialPowerUsesDelay = 1 - TheGlobalData->m_specialPowerUsesDelay;
- TheInGameUI->message( UnicodeString( L"Special Power (Superweapon) Delay: %s" ),
- TheGlobalData->m_specialPowerUsesDelay ? L"ON" : L"OFF" );
- } // end if
- disp = DESTROY_MESSAGE;
- }
- break;
- } // end toggle special power delays
- //--------------------------------------------------------------------------------------
- case GameMessage::MSG_CHEAT_SWITCH_TEAMS:
- {
- if ( !TheGameLogic->isInMultiplayerGame() )
- {
- if (TheGameLogic->isInGame())
- {
- Int idx;
- for (Int i = 0; i < ThePlayerList->getPlayerCount(); i++)
- {
- if (ThePlayerList->getNthPlayer(i) == ThePlayerList->getLocalPlayer())
- {
- idx = i;
- break;
- }
- }
- Int idxOrig = idx;
- do
- {
- ++idx;
- if (idx >= ThePlayerList->getPlayerCount())
- idx = 0;
- if (idx == idxOrig)
- break;
- } while (ThePlayerList->getNthPlayer(idx) == ThePlayerList->getNeutralPlayer());
-
- ThePlayerList->setLocalPlayer(ThePlayerList->getNthPlayer(idx));
- TheInGameUI->deselectAllDrawables();
- #ifdef DEBUG_FOG_MEMORY
- TheGhostObjectManager->setLocalPlayerIndex(idx);
- #endif
- ThePartitionManager->refreshShroudForLocalPlayer();
- TheControlBar->initSpecialPowershortcutBar(ThePlayerList->getLocalPlayer());
- TheControlBar->setControlBarSchemeByPlayer(ThePlayerList->getLocalPlayer());
- TheGameClient->updateFakeDrawables();
- }
- disp = DESTROY_MESSAGE;
- }
- break;
- }
- //--------------------------------------------------------------------------------------
- case GameMessage::MSG_CHEAT_KILL_SELECTION:
- {
- if ( !TheGameLogic->isInMultiplayerGame() )
- {
- // THIS CALLS THE STANDARD DEBUG MESSAGE, WHICH IS CALLED:
- TheMessageStream->appendMessage( GameMessage::MSG_DEBUG_KILL_SELECTION );
- disp = DESTROY_MESSAGE;
- }
- break;
- }
- case GameMessage::MSG_CHEAT_INSTANT_BUILD:
- {
- if ( !TheGameLogic->isInMultiplayerGame() )
- {
- // Doesn't make a valid network message
- Player *localPlayer = ThePlayerList->getLocalPlayer();
- localPlayer->toggleInstantBuild();
- disp = DESTROY_MESSAGE;
- }
- break;
- }
- case GameMessage::MSG_CHEAT_ADD_CASH:
- {
- if ( !TheGameLogic->isInMultiplayerGame() )
- {
- Player *localPlayer = ThePlayerList->getLocalPlayer();
- Money *money = localPlayer->getMoney();
- money->deposit( 10000 );
- }
- break;
- }
- case GameMessage::MSG_CHEAT_GIVE_ALL_SCIENCES:
- {
- if ( !TheGameLogic->isInMultiplayerGame() )
- {
- Player *player = ThePlayerList->getLocalPlayer();
- if (player)
- {
- // cheese festival: do NOT imitate this code. it is for debug purposes only.
- std::vector<AsciiString> v = TheScienceStore->friend_getScienceNames();
- for (int i = 0; i < v.size(); ++i)
- {
- ScienceType st = TheScienceStore->getScienceFromInternalName(v[i]);
- if (st != SCIENCE_INVALID && TheScienceStore->isScienceGrantable(st))
- {
- player->grantScience(st);
- }
- }
- }
- TheInGameUI->message( UnicodeString( L"Granting all sciences!" ));
- disp = DESTROY_MESSAGE;
- }
- break;
- }
- case GameMessage::MSG_CHEAT_GIVE_SCIENCEPURCHASEPOINTS:
- {
- if ( !TheGameLogic->isInMultiplayerGame() )
- {
- Player *player = ThePlayerList->getLocalPlayer();
- if (player)
- player->addSciencePurchasePoints(1);
- TheInGameUI->message( UnicodeString( L"Adding a SciencePurchasePoint" ));
- disp = DESTROY_MESSAGE;
- }
- break;
- }
- case GameMessage::MSG_CHEAT_SHOW_HEALTH:
- {
- if ( !TheGameLogic->isInMultiplayerGame() )
- {
- TheWritableGlobalData->m_showObjectHealth = 1 - TheGlobalData->m_showObjectHealth;
- TheInGameUI->message( UnicodeString( L"Object Health %s" ),
- TheGlobalData->m_showObjectHealth ? L"ON" : L"OFF" );
- }
- break;
-
- }
- case GameMessage::MSG_CHEAT_TOGGLE_MESSAGE_TEXT:
- {
- if ( !TheGameLogic->isInMultiplayerGame() )
- {
- // toggle the message state
- TheInGameUI->toggleMessages();
- // when messages get turned on, display a message
- if( TheInGameUI->isMessagesOn() )
- TheInGameUI->message( TheGameText->fetch( "GUI:MessagesOn" ) );
- disp = DESTROY_MESSAGE;
- }
- break;
- } // end clear message text
- #endif
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_BEGIN_FORCEMOVE:
- DEBUG_ASSERTCRASH(!TheInGameUI->isInForceMoveToMode(), ("forceMoveToMode mismatch"));
- TheInGameUI->setForceMoveMode( true );
- break;
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_END_FORCEMOVE:
- DEBUG_ASSERTCRASH(TheInGameUI->isInForceMoveToMode(), ("forceMoveToMode mismatch"));
- TheInGameUI->setForceMoveMode( false );
- break;
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_BEGIN_WAYPOINTS:
- // DEBUG_ASSERTCRASH( !TheInGameUI->isInWaypointMode(), ("Setting m_waypointMode but it's already set!") );
- TheInGameUI->setWaypointMode( true );
- break;
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_BEGIN_PREFER_SELECTION:
- TheInGameUI->setPreferSelectionMode( true );
- break;
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_END_PREFER_SELECTION:
- TheInGameUI->setPreferSelectionMode( false );
- break;
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_END_WAYPOINTS:
- // DEBUG_ASSERTCRASH( TheInGameUI->isInWaypointMode(), ("Clearing m_waypointMode but it's already clear!") );
- TheInGameUI->setWaypointMode( false );
- break;
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_BEGIN_FORCEATTACK:
- TheInGameUI->setForceAttackMode( true );
- break;
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_END_FORCEATTACK:
- TheInGameUI->setForceAttackMode( false );
- break;
- // --------------------------------------------------------------------------------------------
- case GameMessage::MSG_META_ALL_CHEER:
- {
- if ( TheGameLogic->isInMultiplayerGame() )
- {
- TheAudio->addAudioEvent(&TheAudio->getMiscAudio()->m_allCheerSound);
- disp = DESTROY_MESSAGE;
- TheMessageStream->appendMessage( GameMessage::MSG_DO_CHEER );
- }
- break;
- }
- // --------------------------------------------------------------------------------------------
- case GameMessage::MSG_META_TAKE_SCREENSHOT:
- {
- if (TheDisplay)
- TheDisplay->takeScreenShot();
- disp = DESTROY_MESSAGE;
- break;
- }
- // --------------------------------------------------------------------------------------------
- case GameMessage::MSG_CREATE_SELECTED_GROUP:
- case GameMessage::MSG_SELECT_TEAM0:
- case GameMessage::MSG_SELECT_TEAM1:
- case GameMessage::MSG_SELECT_TEAM2:
- case GameMessage::MSG_SELECT_TEAM3:
- case GameMessage::MSG_SELECT_TEAM4:
- case GameMessage::MSG_SELECT_TEAM5:
- case GameMessage::MSG_SELECT_TEAM6:
- case GameMessage::MSG_SELECT_TEAM7:
- case GameMessage::MSG_SELECT_TEAM8:
- case GameMessage::MSG_SELECT_TEAM9:
- {
- // weed out unit responses for things we don't own.
- DrawableList listOfUnits = *TheInGameUI->getAllSelectedDrawables();
- for (DrawableListIt it = listOfUnits.begin(); it != listOfUnits.end(); /* empty */) {
- Drawable *draw = *it;
- if (draw->getObject() && draw->getObject()->isLocallyControlled()) {
- // This thing can emit a unit response.
- ++it;
- continue;
- } else {
- // remove it.
- it = listOfUnits.erase(it);
- }
- }
- if (!listOfUnits.empty()) {
- pickAndPlayUnitVoiceResponse( &listOfUnits, GameMessage::MSG_CREATE_SELECTED_GROUP );
- }
- m_teamExists = true;
- break;
- }
- // --------------------------------------------------------------------------------------------
- case GameMessage::MSG_CREATE_SELECTED_GROUP_NO_SOUND:
- case GameMessage::MSG_ADD_TEAM0:
- case GameMessage::MSG_ADD_TEAM1:
- case GameMessage::MSG_ADD_TEAM2:
- case GameMessage::MSG_ADD_TEAM3:
- case GameMessage::MSG_ADD_TEAM4:
- case GameMessage::MSG_ADD_TEAM5:
- case GameMessage::MSG_ADD_TEAM6:
- case GameMessage::MSG_ADD_TEAM7:
- case GameMessage::MSG_ADD_TEAM8:
- case GameMessage::MSG_ADD_TEAM9:
- {
- m_teamExists = true;
- break;
- }
- // --------------------------------------------------------------------------------------------
- case GameMessage::MSG_DESTROY_SELECTED_GROUP:
- {
- m_teamExists = false;
- break;
- }
- // --------------------------------------------------------------------------------------------
- // An object is mouseover'd. A hint of a command may be generated if something is selected
- // --------------------------------------------------------------------------------------------
- case GameMessage::MSG_MOUSEOVER_DRAWABLE_HINT:
- {
- const CommandButton *command = TheInGameUI->getGUICommand();
- if( TheInGameUI->getSelectCount() > 0
- || (command && command->getCommandType() == GUI_COMMAND_SPECIAL_POWER_FROM_SHORTCUT) ) // If something is selected
- {
- /// @todo This as well as the one in GameMessage::MSG_DRAWABLE_PICKED below should possibly have a generalized CanAttack instead of simply checking isEnemyOf
- Drawable *draw = TheGameClient->findDrawableByID( msg->getArgument( 0 )->drawableID );
- if( draw )
- {
- //
- // given the drawable that we have moused over, pretend that we have actually
- // "picked" that drawable, depending on what we have selected, our mode,
- // and what "picked" is we would do a command ... but here we only will generate
- // the hint message, *not* the actual command
- //
- if (TheInGameUI->isInForceAttackMode()) {
- evaluateForceAttack(draw, draw->getPosition(), DO_HINT );
- } else {
- evaluateContextCommand( draw, draw->getPosition(), DO_HINT );
- }
- // Do not eat this message, as it itself has another purpose in HintSpy
- }
- }
- }
- break;
-
- //-----------------------------------------------------------------------------
- // Terrain is mouseover'd. A hint of a command may be generated if something is selected
- //
- case GameMessage::MSG_MOUSEOVER_LOCATION_HINT:
- {
- Coord3D position = msg->getArgument( 0 )->location;
- //
- // This message occurs whenever the mouse cursor moves off of a drawable, in which
- // case we want to turn off the pick hint.
- //
- if (TheInGameUI->isInForceAttackMode()) {
- evaluateForceAttack( NULL, &position, DO_HINT );
- } else {
- evaluateContextCommand( NULL, &position, DO_HINT );
- }
- // Do not eat this message, as it will do something itself at HintSpy
- break;
- } // end case GameMessage::MSG_MOUSEOVER_LOCATION_HINT
- //-----------------------------------------------------------------------------
- case GameMessage::MSG_RAW_MOUSE_RIGHT_BUTTON_DOWN:
- {
- // There are two ways in which we can ignore this as a deselect:
- // 1) 2-D position on screen
- // 2) Time has exceeded the time which we allow for this to be a click.
- m_mouseRightDragAnchor = msg->getArgument( 0 )->pixel;
- m_mouseRightDown = (UnsignedInt) msg->getArgument( 2 )->integer;
- break;
- }
- //-----------------------------------------------------------------------------
- case GameMessage::MSG_RAW_MOUSE_RIGHT_BUTTON_UP:
- {
- // register this event for determining if the click was fast or short enough not to be a drag
- m_mouseRightDragLift = msg->getArgument( 0 )->pixel;
- m_mouseRightUp = (UnsignedInt) msg->getArgument( 2 )->integer;
- //Kris: July 7, 2003. Added this code to deselect build placement mode when right clicked. This fixes
- //a bug where you couldn't cancel the sneak attack mode via right click. This only happened when you
- //didn't have anything selected which is possible via the shortcut bar. Normally, it would get deselected
- //via the deselect drawable code.
- if( TheMouse->isClick(&m_mouseRightDragAnchor, &m_mouseRightDragLift, m_mouseRightDown, m_mouseRightUp) )
- {
- TheInGameUI->placeBuildAvailable( NULL, NULL );
- }
- break;
- }
- //-----------------------------------------------------------------------------
- case GameMessage::MSG_MOUSE_RIGHT_DOUBLE_CLICK:
- {
- if( TheGlobalData->m_useAlternateMouse && TheGlobalData->m_doubleClickAttackMove )
- {
- // create the message and append arguments for a guard location
- GameMessage *newMsg = TheMessageStream->appendMessage( GameMessage::MSG_DO_GUARD_POSITION );
- Coord3D pos;
- TheTacticalView->screenToTerrain( &msg->getArgument( 0 )->pixel, &pos );
- newMsg->appendLocationArgument(pos);
- newMsg->appendIntegerArgument(GUARDMODE_NORMAL);
-
- ThePlayerList->getLocalPlayer()->getAcademyStats()->recordDoubleClickAttackMoveOrderGiven();
- TheInGameUI->triggerDoubleClickAttackMoveGuardHint();
- break;
- }
- //intentional fall through
- }
- case GameMessage::MSG_MOUSE_RIGHT_CLICK:
- {
- // right click is only actioned here if we're in alternate mouse mode
- if (TheGlobalData->m_useAlternateMouse
- && TheMouse->isClick(&m_mouseRightDragAnchor, &m_mouseRightDragLift, m_mouseRightDown, m_mouseRightUp))
- {
- Bool isPoint = (msg->getArgument(0)->pixelRegion.height() == 0 && msg->getArgument(0)->pixelRegion.width() == 0);
- // NOTE: RIGHT_CLICK is not transmitted if AREA_SELECTION or DRAWABLE_PICKED occurs.
- // If we see this msg, no object was clicked on, therefore clicked on ground.
- // Issue move command to all currently selected objects.
- // sanity
- if( TheTacticalView == NULL )
- break;
- // translate from screen coordinates to terrain coords
- Coord3D pos;
- TheTacticalView->screenToTerrain( &msg->getArgument( 0 )->pixel, &pos );
- const CommandButton *command = TheInGameUI->getGUICommand();
- Bool controllable = TheInGameUI->areSelectedObjectsControllable()
- || (command && command->getCommandType() == GUI_COMMAND_SPECIAL_POWER_FROM_SHORTCUT);
- if (isPoint && controllable)
- {
- UnsignedInt pickType = getPickTypesForContext( TheInGameUI->isInForceAttackMode() );
- Drawable *draw = TheTacticalView->pickDrawable(&msg->getArgument(0)->pixelRegion.lo,
- TheInGameUI->isInForceAttackMode(),
- (PickType) pickType);
- if (TheInGameUI->isInForceAttackMode()) {
- evaluateForceAttack( draw, &pos, DO_COMMAND );
- } else {
- evaluateContextCommand( draw, &pos, DO_COMMAND );
- }
- disp = DESTROY_MESSAGE;
- TheInGameUI->clearAttackMoveToMode();
- }
- }
- break;
- }
- //-----------------------------------------------------------------------------
- case GameMessage::MSG_MOUSE_LEFT_DOUBLE_CLICK:
- {
- if( !TheGlobalData->m_useAlternateMouse && TheGlobalData->m_doubleClickAttackMove )
- {
- // create the message and append arguments for a guard location
- GameMessage *newMsg = TheMessageStream->appendMessage( GameMessage::MSG_DO_GUARD_POSITION );
- Coord3D pos;
- TheTacticalView->screenToTerrain( &msg->getArgument( 0 )->pixel, &pos );
- newMsg->appendLocationArgument(pos);
- newMsg->appendIntegerArgument(GUARDMODE_NORMAL);
- ThePlayerList->getLocalPlayer()->getAcademyStats()->recordDoubleClickAttackMoveOrderGiven();
- TheInGameUI->triggerDoubleClickAttackMoveGuardHint();
- break;
- }
- //intentional fall through
- }
- case GameMessage::MSG_MOUSE_LEFT_CLICK:
- {
- Bool isPoint = (msg->getArgument(0)->pixelRegion.height() == 0 && msg->getArgument(0)->pixelRegion.width() == 0);
- // NOTE: LEFT_CLICK is not transmitted if AREA_SELECTION or DRAWABLE_PICKED occurs.
- // If we see this msg, no object was clicked on, therefore clicked on ground.
- // Issue move command to all currently selected objects.
- // sanity
- if( TheTacticalView == NULL )
- break;
- // translate from screen coordinates to terrain coords
- Coord3D pos;
- TheTacticalView->screenToTerrain( &msg->getArgument( 0 )->pixel, &pos );
- const CommandButton *command = TheInGameUI->getGUICommand();
- // maintain this as the list of GUI button initiated commands that fire with left click in alt mouse mode
- Bool isFiringGUICommand = (command && (command->getCommandType() == GUI_COMMAND_SPECIAL_POWER
- || command->getCommandType() == GUI_COMMAND_SPECIAL_POWER_FROM_SHORTCUT
- || command->getCommandType() == GUI_COMMAND_FIRE_WEAPON
- || command->getCommandType() == GUI_COMMAND_COMBATDROP
- || command->getCommandType() == GUICOMMANDMODE_HIJACK_VEHICLE
- || command->getCommandType() == GUICOMMANDMODE_CONVERT_TO_CARBOMB));
- // in alternate mouse mode, this left click is only actioned here if we're firing a gui command
- if ((TheGlobalData->m_useAlternateMouse) && (! isFiringGUICommand))
- break;
- Bool controllable = TheInGameUI->areSelectedObjectsControllable()
- || (command && command->getCommandType() == GUI_COMMAND_SPECIAL_POWER_FROM_SHORTCUT);
- if (isPoint && controllable)
- {
- UnsignedInt pickType = getPickTypesForContext( TheInGameUI->isInForceAttackMode() );
- Drawable *draw = TheTacticalView->pickDrawable(&msg->getArgument(0)->pixelRegion.lo,
- TheInGameUI->isInForceAttackMode(),
- (PickType) pickType);
- if (TheInGameUI->isInForceAttackMode()) {
- evaluateForceAttack( draw, &pos, DO_COMMAND );
- } else {
- evaluateContextCommand( draw, &pos, DO_COMMAND );
- }
- disp = DESTROY_MESSAGE;
- TheInGameUI->clearAttackMoveToMode();
- //issueMoveToLocationCommand( &pos, draw, DO_COMMAND );
- }
- break;
- } // end case GameMessage::MSG_MOUSE_LEFT_CLICK
- #ifdef ALLOW_ALT_F4
- case GameMessage::MSG_META_DEMO_INSTANT_QUIT:
- {
- if (TheGameLogic->isInGame())
- {
- if (TheRecorder->getMode() == RECORDERMODETYPE_RECORD)
- {
- TheRecorder->stopRecording();
- }
- TheGameLogic->clearGameData();
- }
- TheGameEngine->setQuitting(TRUE);
- disp = DESTROY_MESSAGE;
- break;
- }
- #endif
- //------------------------------------------------------------------------------- DEMO MESSAGES
- #if defined(_DEBUG) || defined(_INTERNAL)
- //------------------------------------------------------------------------- BEGIN DEMO MESSAGES
- //------------------------------------------------------------------------- BEGIN DEMO MESSAGES
- //------------------------------------------------------------------------- BEGIN DEMO MESSAGES
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_SWITCH_TEAMS:
- {
- if (TheGameLogic->isInGame())
- {
- Int idx;
- for (Int i = 0; i < ThePlayerList->getPlayerCount(); i++)
- {
- if (ThePlayerList->getNthPlayer(i) == ThePlayerList->getLocalPlayer())
- {
- idx = i;
- break;
- }
- }
- Int idxOrig = idx;
- do
- {
- ++idx;
- if (idx >= ThePlayerList->getPlayerCount())
- idx = 0;
- if (idx == idxOrig)
- {
- break;
- }
- } while (ThePlayerList->getNthPlayer(idx) == ThePlayerList->getNeutralPlayer());
-
- ThePlayerList->setLocalPlayer(ThePlayerList->getNthPlayer(idx));
- TheInGameUI->deselectAllDrawables();
- #ifdef DEBUG_FOG_MEMORY
- TheGhostObjectManager->setLocalPlayerIndex(idx);
- #endif
- ThePartitionManager->refreshShroudForLocalPlayer();
- TheControlBar->initSpecialPowershortcutBar(ThePlayerList->getLocalPlayer());
- TheControlBar->setControlBarSchemeByPlayer(ThePlayerList->getLocalPlayer());
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_SWITCH_TEAMS_BETWEEN_CHINA_USA:
- {
- Player *p = ThePlayerList->getLocalPlayer();
- AsciiString side;
- side.set(p->getSide());
- if(side.compareNoCase("America") == 0)
- {
- for (Int i = 0; i < ThePlayerList->getPlayerCount(); i++)
- {
- Player *pt = ThePlayerList->getNthPlayer(i);
- if(pt->getSide().compareNoCase("China") == 0)
- {
- ThePlayerList->setLocalPlayer(pt);
- TheInGameUI->deselectAllDrawables();
- ThePartitionManager->refreshShroudForLocalPlayer();
- TheControlBar->setControlBarSchemeByPlayer(ThePlayerList->getLocalPlayer());
- break;
- }
- }
- }
- if(side.compareNoCase("China") == 0)
- {
- for (Int i = 0; i < ThePlayerList->getPlayerCount(); i++)
- {
- Player *pt = ThePlayerList->getNthPlayer(i);
- if(pt->getSide().compareNoCase("America") == 0)
- {
- ThePlayerList->setLocalPlayer(pt);
- TheInGameUI->deselectAllDrawables();
- ThePartitionManager->refreshShroudForLocalPlayer();
- TheControlBar->setControlBarSchemeByPlayer(ThePlayerList->getLocalPlayer());
- break;
- }
- }
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_LOD_DECREASE:
- {
- TheGameClient->adjustLOD(-1);
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_LOD_INCREASE:
- {
- TheGameClient->adjustLOD(1);
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_HELP:
- {
- // for demo, they don't want the help menu showing up. I left this as a block comment because we
- // might want to add back in the help menu at some point in time.
- /*
- if (TheWindowManager && TheNameKeyGenerator)
- {
- GameWindow *motd = TheWindowManager->winGetWindowFromId(NULL, (Int)TheNameKeyGenerator->nameToKey(AsciiString("MOTD.wnd:MOTD")));
- if (motd)
- motd->winHide(!motd->winIsHidden());
- }*/
-
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_BEHIND_BUILDINGS:
- {
- if (TheGlobalData)
- {
- if(TheGameLogic->getShowBehindBuildingMarkers())
- {
- TheGameLogic->setShowBehindBuildingMarkers(FALSE);
- TheInGameUI->message("GUI:ShowBehindBuildings");
- }
- else
- {
- TheGameLogic->setShowBehindBuildingMarkers(TRUE);
- TheInGameUI->message("GUI:HideBehindBuildings");
- }
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_LETTERBOX:
- {
- if(TheShell->isShellActive())
- {
- WindowLayout *win = TheShell->top();
- if(win)
- {
- win->hide(!win->isHidden());
- }
- }
- else
- {
- Bool hide = false;
- if (TheWindowManager)
- {
- Int id = (Int)TheNameKeyGenerator->nameToKey(AsciiString("ControlBar.wnd:ControlBarParent"));
- GameWindow *window = TheWindowManager->winGetWindowFromId(NULL, id);
- if (window)
- hide = !window->winIsHidden();
- }
- if (hide)
- HideControlBar();
- else
- ShowControlBar(FALSE);
- TheDisplay->toggleLetterBox();
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_MESSAGE_TEXT:
- {
- // toggle the message state
- TheInGameUI->toggleMessages();
- // when messages get turned on, display a message
- if( TheInGameUI->isMessagesOn() )
- TheInGameUI->message( TheGameText->fetch( "GUI:MessagesOn" ) );
- disp = DESTROY_MESSAGE;
- break;
- } // end clear message text
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_MOTION_BLUR_ZOOM:
- { Int mode;
- if ((mode=TheTacticalView->getViewFilterType()) == FT_VIEW_MOTION_BLUR_FILTER)
- { //mode already set, turn it off
- TheTacticalView->setViewFilterMode(FM_NULL_MODE);
- TheTacticalView->setViewFilter(FT_NULL_FILTER);
- }
- else
- {
- static Bool saturate = false;
- FilterModes mode = FM_VIEW_MB_IN_AND_OUT_ALPHA;
- if (saturate) {
- mode = FM_VIEW_MB_IN_AND_OUT_SATURATE;
- }
- if (TheTacticalView->getCameraLock()!=0) {
- mode = FM_VIEW_MB_PAN_ALPHA;
- }
- saturate = !saturate;
- Coord3D curpos;
- TheTacticalView->getPosition(&curpos);
- curpos.x += 200;
- curpos.y += 200;
- TheTacticalView->setViewFilterPos(&curpos);
- TheTacticalView->setViewFilterMode(mode);
- TheTacticalView->setViewFilter(FT_VIEW_MOTION_BLUR_FILTER);
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_BW_VIEW:
- { //We're not testing BW mode anymore, so use this message for toggling wireframe mode.
- static mode=0;
- if (mode == 0)
- { //First turn on wireframe
- TheTacticalView->set3DWireFrameMode(TRUE);
- mode++;
- disp = DESTROY_MESSAGE;
- break;
- }
- if (mode == 1)
- {
- if ((TheTacticalView->getViewFilterType()) == FT_VIEW_CROSSFADE)
- { //mode already set, turn it off
- TheTacticalView->setViewFilterMode(FM_NULL_MODE);
- TheTacticalView->setViewFilter(FT_NULL_FILTER);
- TheTacticalView->setFadeParameters(0,-1);
- }
- else
- {
- TheScriptEngine->doFreezeTime();
- //TheTacticalView->setViewFilterMode(FM_VIEW_CROSSFADE_CIRCLE);
- TheTacticalView->setViewFilterMode(FM_VIEW_CROSSFADE_FB_MASK);
- TheTacticalView->setViewFilter(FT_VIEW_CROSSFADE);
- TheTacticalView->setFadeParameters(60,-1);
- TheTacticalView->set3DWireFrameMode(FALSE);
- mode++;
- }
- }
- else
- if (mode == 2)
- {
- TheScriptEngine->doUnfreezeTime();
- mode=0; //reset everything
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_RED_VIEW:
- {
- if ((TheTacticalView->getViewFilterType()) == FT_VIEW_BW_FILTER)
- { //mode already set, turn it off
- TheTacticalView->setViewFilterMode(FM_NULL_MODE);
- TheTacticalView->setViewFilter(FT_NULL_FILTER);
- TheTacticalView->setFadeParameters(30,-1);
- }
- else
- {
- TheTacticalView->setViewFilterMode(FM_VIEW_BW_RED_AND_WHITE);
- TheTacticalView->setViewFilter(FT_VIEW_BW_FILTER);
- TheTacticalView->setFadeParameters(30,1);
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_GREEN_VIEW:
- {
- if ((TheTacticalView->getViewFilterType()) == FT_VIEW_BW_FILTER)
- { //mode already set, turn it off
- TheTacticalView->setViewFilterMode(FM_NULL_MODE);
- TheTacticalView->setViewFilter(FT_NULL_FILTER);
- TheTacticalView->setFadeParameters(30,-1);
- }
- else
- {
- TheTacticalView->setViewFilterMode(FM_VIEW_BW_GREEN_AND_WHITE);
- TheTacticalView->setViewFilter(FT_VIEW_BW_FILTER);
- TheTacticalView->setFadeParameters(30,1);
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_CYCLE_LOD_LEVEL:
- {
- static Int level=DYNAMIC_GAME_LOD_VERY_HIGH;
- level--;
- if (level < DYNAMIC_GAME_LOD_LOW)
- level = DYNAMIC_GAME_LOD_VERY_HIGH;
- TheGameLODManager->setDynamicLODLevel((DynamicGameLODLevel)level);
- UnicodeString lodName;
- lodName.format(L"Dynamic Game Detail %hs",TheGameLODManager->getDynamicGameLODLevelName((DynamicGameLODLevel)level));
- TheInGameUI->message(lodName);
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEBUG_DUMP_ASSETS:
- {
- TheDisplay->dumpModelAssets("UsedMapAssets.txt");
- disp = DESTROY_MESSAGE;
- break;
- }
-
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_SHADOW_VOLUMES:
- {
- TheWritableGlobalData->m_useShadowVolumes = !TheGlobalData->m_useShadowVolumes;
- TheWritableGlobalData->m_useShadowDecals = !TheGlobalData->m_useShadowDecals;
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_FOGOFWAR:
- {
- TheWritableGlobalData->m_fogOfWarOn = !TheGlobalData->m_fogOfWarOn;
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_KILL_SELECTION:
- {
- TheMessageStream->appendMessage( GameMessage::MSG_DEBUG_KILL_SELECTION );
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_KILL_ALL_ENEMIES:
- {
- for (Drawable *d = TheGameClient->firstDrawable(); d; d = d->getNextDrawable())
- {
- Object* obj = d->getObject();
- if (obj && obj->getControllingPlayer() && obj->getControllingPlayer()->getRelationship(ThePlayerList->getLocalPlayer()->getDefaultTeam()) == ENEMIES)
- {
- obj->kill();
- }
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEBUG_GIVE_VETERANCY:
- case GameMessage::MSG_META_DEBUG_TAKE_VETERANCY:
- {
- if ( !TheGameLogic->isInMultiplayerGame() )
- {
- const DrawableList *list = TheInGameUI->getAllSelectedDrawables();
- for (DrawableListCIt it = list->begin(); it != list->end(); ++it)
- {
- Drawable *pDraw = *it;
- if (pDraw)
- {
- Object *pObject = pDraw->getObject();
- if (pObject)
- {
- ExperienceTracker *et = pObject->getExperienceTracker();
- if (et)
- {
- if (et->isTrainable())
- {
- VeterancyLevel oldVet = et->getVeterancyLevel();
- VeterancyLevel newVet = oldVet;
- if (t == GameMessage::MSG_META_DEBUG_GIVE_VETERANCY)
- {
- if (oldVet < LEVEL_LAST)
- {
- newVet = (VeterancyLevel)((Int)oldVet + 1);
- }
- }
- else
- {
- if (oldVet > LEVEL_FIRST)
- {
- newVet = (VeterancyLevel)((Int)oldVet - 1);
- }
- }
- et->setVeterancyLevel(newVet);
- }
- }
- }
- }
- }
- disp = DESTROY_MESSAGE;
- }
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEBUG_INCR_ANIM_SKATE_SPEED:
- {
- TheSkateDistOverride += 0.25f;
- TheInGameUI->message( UnicodeString( L"Skate Distance Override is now %f" ), TheSkateDistOverride );
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEBUG_DECR_ANIM_SKATE_SPEED:
- {
- TheSkateDistOverride -= 0.25f;
- TheInGameUI->message( UnicodeString( L"Skate Distance Override is now %f" ), TheSkateDistOverride );
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEBUG_CYCLE_EXTENT_TYPE:
- if (extentModType == EXTENTMOD_INVALID) extentModType = EXTENTMOD_TYPE;
- if (!extentModAmount) extentModAmount = 1.0f;
- case GameMessage::MSG_META_DEBUG_INCREASE_EXTENT_MAJOR:
- if (extentModType == EXTENTMOD_INVALID) extentModType = EXTENTMOD_MAJOR;
- if (!extentModAmount) extentModAmount = 1.0f;
- case GameMessage::MSG_META_DEBUG_INCREASE_EXTENT_MAJOR_BIG:
- if (extentModType == EXTENTMOD_INVALID) extentModType = EXTENTMOD_MAJOR;
- if (!extentModAmount) extentModAmount = EXTENT_BIG_CHANGE;
- case GameMessage::MSG_META_DEBUG_DECREASE_EXTENT_MAJOR:
- if (extentModType == EXTENTMOD_INVALID) extentModType = EXTENTMOD_MAJOR;
- if (!extentModAmount) extentModAmount = -1.0f;
- case GameMessage::MSG_META_DEBUG_DECREASE_EXTENT_MAJOR_BIG:
- if (extentModType == EXTENTMOD_INVALID) extentModType = EXTENTMOD_MAJOR;
- if (!extentModAmount) extentModAmount = -EXTENT_BIG_CHANGE;
- case GameMessage::MSG_META_DEBUG_INCREASE_EXTENT_MINOR:
- if (extentModType == EXTENTMOD_INVALID) extentModType = EXTENTMOD_MINOR;
- if (!extentModAmount) extentModAmount = 1.0f;
- case GameMessage::MSG_META_DEBUG_INCREASE_EXTENT_MINOR_BIG:
- if (extentModType == EXTENTMOD_INVALID) extentModType = EXTENTMOD_MINOR;
- if (!extentModAmount) extentModAmount = EXTENT_BIG_CHANGE;
- case GameMessage::MSG_META_DEBUG_DECREASE_EXTENT_MINOR:
- if (extentModType == EXTENTMOD_INVALID) extentModType = EXTENTMOD_MINOR;
- if (!extentModAmount) extentModAmount = -1.0f;
- case GameMessage::MSG_META_DEBUG_DECREASE_EXTENT_MINOR_BIG:
- if (extentModType == EXTENTMOD_INVALID) extentModType = EXTENTMOD_MINOR;
- if (!extentModAmount) extentModAmount = -EXTENT_BIG_CHANGE;
- case GameMessage::MSG_META_DEBUG_INCREASE_EXTENT_HEIGHT:
- if (extentModType == EXTENTMOD_INVALID) extentModType = EXTENTMOD_HEIGHT;
- if (!extentModAmount) extentModAmount = 1.0f;
- case GameMessage::MSG_META_DEBUG_INCREASE_EXTENT_HEIGHT_BIG:
- if (extentModType == EXTENTMOD_INVALID) extentModType = EXTENTMOD_HEIGHT;
- if (!extentModAmount) extentModAmount = EXTENT_BIG_CHANGE;
- case GameMessage::MSG_META_DEBUG_DECREASE_EXTENT_HEIGHT:
- if (extentModType == EXTENTMOD_INVALID) extentModType = EXTENTMOD_HEIGHT;
- if (!extentModAmount) extentModAmount = -1.0f;
- case GameMessage::MSG_META_DEBUG_DECREASE_EXTENT_HEIGHT_BIG:
- if (extentModType == EXTENTMOD_INVALID) extentModType = EXTENTMOD_HEIGHT;
- if (!extentModAmount) extentModAmount = -EXTENT_BIG_CHANGE;
- {
- const DrawableList *list = TheInGameUI->getAllSelectedDrawables();
- for (DrawableListCIt it = list->begin(); it != list->end(); ++it)
- {
- Drawable *pDraw = *it;
- if (pDraw)
- {
- Object *pObject = pDraw->getObject();
- if (pObject)
- {
- const GeometryInfo oldGeometry = pObject->getGeometryInfo();
-
- GeometryInfo newGeometry = oldGeometry;
- newGeometry.tweakExtents(extentModType, extentModAmount);
-
- AsciiString msg;
- msg.format("Extent %s --> %s %d %g",oldGeometry.getDescriptiveString().str(), newGeometry.getDescriptiveString().str(), extentModType, extentModAmount);
- UnicodeString umsg;
- umsg.translate(msg);
- TheInGameUI->message(umsg);
- DEBUG_LOG(("%ls\n", msg.str()));
- pObject->setGeometryInfo( newGeometry );
- }
- }
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_LOCK_CAMERA_TO_SELECTION:
- {
- ObjectID id = INVALID_ID;
- Drawable *d = NULL;
- for (d = TheGameClient->firstDrawable(); d; d = d->getNextDrawable())
- {
- if (d->isSelected() && d->getObject())
- {
- id = d->getObject()->getID();
- break;
- }
- }
- if (id != 0 && TheTacticalView->getCameraLock() == id)
- {
- if (TheTacticalView->getCameraLockDrawable())
- {
- id = INVALID_ID; // toggle it
- d=NULL;
- TheTacticalView->forceRedraw(); //reset camera to normal
- }
- }
- else
- {
- d = NULL;
- }
- TheTacticalView->setCameraLock(id);
- TheTacticalView->setCameraLockDrawable(d);
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_SOUND:
- {
- if (TheAudio->isOn(AudioAffect_Sound))
- {
- TheDisplay->stopMovie();
- TheInGameUI->stopMovie();
- TheAudio->setOn(false, AudioAffect_All);
- }
- else
- {
- TheAudio->setOn(true, AudioAffect_All);
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_TRACKMARKS:
- {
- TheWritableGlobalData->m_makeTrackMarks = !TheGlobalData->m_makeTrackMarks;
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_WATERPLANE:
- {
- TheWritableGlobalData->m_useWaterPlane = !TheGlobalData->m_useWaterPlane;
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TIME_OF_DAY:
- {
- TimeOfDay tod = TimeOfDay((Int) TheGlobalData->m_timeOfDay + 1);
- if (tod >= TIME_OF_DAY_COUNT)
- tod = TIME_OF_DAY_FIRST;
- if (TheWritableGlobalData->setTimeOfDay(tod))
- {
- TheGameClient->setTimeOfDay(TheGlobalData->m_timeOfDay);
- if (TheGlobalData->m_forceModelsToFollowTimeOfDay)
- {
- for (Object *obj = TheGameLogic->getFirstObject(); obj; obj = obj->getNextObject())
- {
- Drawable* d = obj->getDrawable();
- if (d)
- {
- // this just forces a refresh.
- ModelConditionFlags empty;
- d->clearAndSetModelConditionFlags(empty, empty);
- }
- }
- }
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_REMOVE_PREREQ:
- {
- // Doesn't make a valid network message
- Player *localPlayer = ThePlayerList->getLocalPlayer();
- localPlayer->toggleIgnorePrereqs();
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_INSTANT_BUILD:
- {
- // Doesn't make a valid network message
- Player *localPlayer = ThePlayerList->getLocalPlayer();
- localPlayer->toggleInstantBuild();
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_FREE_BUILD:
- {
- // Doesn't make a valid network message
- Player *localPlayer = ThePlayerList->getLocalPlayer();
- localPlayer->toggleFreeBuild();
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_RENDER:
- {
- TheWritableGlobalData->m_disableRender = !TheGlobalData->m_disableRender;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_ADD_CASH:
- {
- if ( !TheGameLogic->isInMultiplayerGame() )
- {
- Player *localPlayer = ThePlayerList->getLocalPlayer();
- Money *money = localPlayer->getMoney();
- money->deposit( 10000 );
- }
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_RUNSCRIPT1:
- case GameMessage::MSG_META_DEMO_RUNSCRIPT2:
- case GameMessage::MSG_META_DEMO_RUNSCRIPT3:
- case GameMessage::MSG_META_DEMO_RUNSCRIPT4:
- case GameMessage::MSG_META_DEMO_RUNSCRIPT5:
- case GameMessage::MSG_META_DEMO_RUNSCRIPT6:
- case GameMessage::MSG_META_DEMO_RUNSCRIPT7:
- case GameMessage::MSG_META_DEMO_RUNSCRIPT8:
- case GameMessage::MSG_META_DEMO_RUNSCRIPT9:
- {
- if( TheScriptEngine )
- {
- Int script = t - GameMessage::MSG_META_DEMO_RUNSCRIPT1 + 1;
- AsciiString scriptName;
- scriptName.format("KEY_F%d", script);
- TheScriptEngine->runScript(scriptName);
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_KILL_AREA_SELECTION:
- {
- for( int i=1; i<msg->getArgumentCount(); i++ )
- {
- Object *obj = TheGameLogic->findObjectByID( msg->getArgument( i )->objectID );
- if( obj )
- {
- obj->kill();
- }
- }
- }
- break;
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE1:
- case GameMessage::MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE2:
- case GameMessage::MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE3:
- case GameMessage::MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE4:
- case GameMessage::MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE5:
- case GameMessage::MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE6:
- case GameMessage::MSG_META_DEMO_NEXT_OBJECTIVE_MOVIE:
- {
- if (TheGameLogic->isInGame())
- {
- if (t == GameMessage::MSG_META_DEMO_NEXT_OBJECTIVE_MOVIE)
- {
- m_objective++;
- if (m_objective > 6)
- m_objective = 1;
- }
- else
- {
- m_objective = t - GameMessage::MSG_META_DEMO_PLAY_OBJECTIVE_MOVIE1 + 1;
- }
- AsciiString name;
- name.format("DemoObjective%02d", m_objective);
- TheInGameUI->playMovie(name);
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_MILITARY_SUBTITLES:
- {
-
- TheInGameUI->militarySubtitle("MSG:Testing", 10000); // use some innocuous string
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_MUSIC:
- {
- if (TheAudio->isMusicPlaying()) {
- TheAudio->stopAudio(AudioAffect_Music);
- TheInGameUI->message( UnicodeString( L"Stopping Music" ));
- } else {
- TheAudio->resumeAudio(AudioAffect_Music);
- TheInGameUI->message( UnicodeString( L"Resuming Music" ));
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_MUSIC_NEXT_TRACK:
- {
- TheAudio->nextMusicTrack();
- UnicodeString ustr;
- ustr.format(L"Playing Track: %hs", TheAudio->getMusicTrackName().str());
- TheInGameUI->message( ustr );
- disp = DESTROY_MESSAGE;
- break;
- }
-
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_MUSIC_PREV_TRACK:
- {
- TheAudio->prevMusicTrack();
- UnicodeString ustr;
- ustr.format(L"Playing Track: %hs", TheAudio->getMusicTrackName().str());
- TheInGameUI->message( ustr );
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- #ifdef PERF_TIMERS
- case GameMessage::MSG_META_DEMO_TOGGLE_METRICS:
- {
- TheWritableGlobalData->m_showMetrics = !TheGlobalData->m_showMetrics;
- if (TheGlobalData->m_showMetrics) {
- TheDisplay->setDebugDisplayCallback(StatMetricsDisplay);
- } else {
- TheDisplay->setDebugDisplayCallback(NULL);
- }
- break;
- }
- #endif // #ifdef PERF_TIMERS
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_AI_DEBUG:
- {
- TheWritableGlobalData->m_debugAI = (AIDebugOptions)((Int)TheGlobalData->m_debugAI + 1);
- if (TheGlobalData->m_debugAI >= AI_DEBUG_END)
- TheWritableGlobalData->m_debugAI=AI_DEBUG_NONE;
- UnicodeString line;
- line.format(L"Level %d", TheGlobalData->m_debugAI);
- TheInGameUI->message( UnicodeString( L"Debug AI Mode is %s" ), TheGlobalData->m_debugAI ? line.str() : L"OFF" );
- disp = DESTROY_MESSAGE;
- break;
- }
-
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_SUPPLY_CENTER_PLACEMENT:
- {
- TheWritableGlobalData->m_debugSupplyCenterPlacement = !TheWritableGlobalData->m_debugSupplyCenterPlacement;
- TheInGameUI->message( UnicodeString( L"Log SupplyCenter Placement is %s" ), TheGlobalData->m_debugSupplyCenterPlacement ? L"ON" : L"OFF" );
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_GIVE_SCIENCEPURCHASEPOINTS:
- {
- Player *player = ThePlayerList->getLocalPlayer();
- if (player)
- player->addSciencePurchasePoints(1);
- TheInGameUI->message( UnicodeString( L"Adding a SciencePurchasePoint" ));
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_GIVE_ALL_SCIENCES:
- {
- Player *player = ThePlayerList->getLocalPlayer();
- if (player)
- {
- // cheese festival: do NOT imitate this code. it is for debug purposes only.
- std::vector<AsciiString> v = TheScienceStore->friend_getScienceNames();
- for (int i = 0; i < v.size(); ++i)
- {
- ScienceType st = TheScienceStore->getScienceFromInternalName(v[i]);
- if (st != SCIENCE_INVALID && TheScienceStore->isScienceGrantable(st))
- {
- player->grantScience(st);
- }
- }
- }
- TheInGameUI->message( UnicodeString( L"Granting all sciences!" ));
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_GIVE_RANKLEVEL:
- {
- Player *player = ThePlayerList->getLocalPlayer();
- if (player)
- player->setRankLevel(player->getRankLevel() + 1);
- TheInGameUI->message( UnicodeString( L"Adding a RankLevel" ));
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TAKE_RANKLEVEL:
- {
- Player *player = ThePlayerList->getLocalPlayer();
- if (player)
- player->setRankLevel(player->getRankLevel() - 1);
- TheInGameUI->message( UnicodeString( L"Subtracting a RankLevel" ));
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_CAMERA_DEBUG:
- {
- TheWritableGlobalData->m_debugCamera = !TheGlobalData->m_debugCamera;
- TheInGameUI->message( UnicodeString( L"Debug Camera Mode is %s" ), TheGlobalData->m_debugCamera ? L"On" : L"OFF" );
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_NO_DRAW:
- {
- TheWritableGlobalData->m_noDraw = REAL_TO_INT(pow(2, 32) - 1);
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEBUG_DUMP_PLAYER_OBJECTS:
- case GameMessage::MSG_META_DEBUG_DUMP_ALL_PLAYER_OBJECTS:
- {
- AsciiString line;
- line.format("*******************************");
- TheScriptEngine->AppendDebugMessage(line, FALSE);
- line.format("Dumping player object counts");
- TheScriptEngine->AppendDebugMessage(line, FALSE);
- for (Int i=0; i<MAX_PLAYER_COUNT; ++i)
- {
- Player *pPlayer = ThePlayerList->getNthPlayer(i);
- if (!pPlayer || !pPlayer->getPlayerTemplate() || !pPlayer->getPlayerTemplate()->isPlayableSide())
- continue;
- Int numObjects = 0;
- pPlayer->iterateObjects( countObjects, &numObjects );
- line.format("Player %d (%ls) has %d non-dead objects", i, pPlayer->getPlayerDisplayName().str(), numObjects);
- TheScriptEngine->AppendDebugMessage(line, FALSE);
- if (numObjects && (numObjects <= 5 || t == GameMessage::MSG_META_DEBUG_DUMP_ALL_PLAYER_OBJECTS))
- {
- line = "Objects are:";
- TheScriptEngine->AppendDebugMessage(line, FALSE);
- pPlayer->iterateObjects( printObjects, NULL );
- }
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEBUG_TOGGLE_NETWORK:
- {
- if (TheNetwork != NULL) {
- TheNetwork->toggleNetworkOn();
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_PARTICLEDEBUG:
- {
- if (TheDisplay->getDebugDisplayCallback() == ParticleSystemDebugDisplay)
- TheDisplay->setDebugDisplayCallback(NULL);
- else
- TheDisplay->setDebugDisplayCallback(ParticleSystemDebugDisplay);
- disp = DESTROY_MESSAGE;
- break;
- }
-
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_VISIONDEBUG:
- {
- TheWritableGlobalData->m_debugVisibility = !TheGlobalData->m_debugVisibility;
- TheInGameUI->message( UnicodeString( L"Debug Vision Mode is %s" ), TheGlobalData->m_debugVisibility? L"On" : L"OFF" );
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_PROJECTILEDEBUG:
- {
- TheWritableGlobalData->m_debugProjectilePath = !TheGlobalData->m_debugProjectilePath;
- TheInGameUI->message( UnicodeString( L"Debug Projectile Path Mode is %s" ), TheGlobalData->m_debugProjectilePath? L"On" : L"OFF" );
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_THREATDEBUG:
- {
- TheWritableGlobalData->m_debugThreatMap = !TheGlobalData->m_debugThreatMap;
- if (TheGlobalData->m_debugThreatMap) {
- TheWritableGlobalData->m_debugCashValueMap = false;
- }
- TheInGameUI->message( UnicodeString( L"Debug Threat Map is %s" ), TheGlobalData->m_debugThreatMap? L"On" : L"OFF" );
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_CASHMAPDEBUG:
- {
- TheWritableGlobalData->m_debugCashValueMap = !TheGlobalData->m_debugCashValueMap ;
- if (TheGlobalData->m_debugCashValueMap) {
- TheWritableGlobalData->m_debugThreatMap = false;
- }
- TheInGameUI->message( UnicodeString( L"Debug Cash Value Map is %s" ), TheGlobalData->m_debugCashValueMap? L"On" : L"OFF" );
- disp = DESTROY_MESSAGE;
- break;
- }
-
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_GRAPHICALFRAMERATEBAR:
- {
- TheWritableGlobalData->m_debugShowGraphicalFramerate = !TheGlobalData->m_debugShowGraphicalFramerate;
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEBUG_SHOW_EXTENTS:
- TheWritableGlobalData->m_showCollisionExtents = 1 - TheGlobalData->m_showCollisionExtents;
- TheInGameUI->message( UnicodeString( L"Show Object Extents %s" ),
- TheGlobalData->m_showCollisionExtents ? L"ON" : L"OFF" );
- break;
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEBUG_SHOW_AUDIO_LOCATIONS:
- TheWritableGlobalData->m_showAudioLocations = 1 - TheGlobalData->m_showAudioLocations;
- TheInGameUI->message( UnicodeString( L"Show AudioLocations %s" ),
- TheGlobalData->m_showAudioLocations ? L"ON" : L"OFF" );
- break;
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEBUG_SHOW_HEALTH:
- {
- TheWritableGlobalData->m_showObjectHealth = 1 - TheGlobalData->m_showObjectHealth;
- TheInGameUI->message( UnicodeString( L"Object Health %s" ),
- TheGlobalData->m_showObjectHealth ? L"ON" : L"OFF" );
- break;
-
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_PLAY_CAMEO_MOVIE:
- {
- if (TheGameLogic->isInGame())
- {
- if(TheInGameUI->cameoVideoBuffer() == NULL)
- TheInGameUI->playCameoMovie("CameoMovie");
- else
- TheInGameUI->stopCameoMovie();
- }
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_ZOOM_LOCK:
- {
- if( TheTacticalView )
- {
- TheTacticalView->setZoomLimited( !TheTacticalView->isZoomLimited() );
- TheInGameUI->message( UnicodeString( L"Camera Zoom Limit: %s" ),
- TheTacticalView->isZoomLimited() ? L"ON" : L"OFF" );
- } // end if
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //---------------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_SPECIAL_POWER_DELAYS:
- {
- if( TheGlobalData )
- {
- TheWritableGlobalData->m_specialPowerUsesDelay = 1 - TheGlobalData->m_specialPowerUsesDelay;
- TheInGameUI->message( UnicodeString( L"Special Power (Superweapon) Delay: %s" ),
- TheGlobalData->m_specialPowerUsesDelay ? L"ON" : L"OFF" );
- } // end if
- disp = DESTROY_MESSAGE;
- break;
- } // end toggle special power delays
- #ifdef ALLOW_SURRENDER
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //---------------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TEST_SURRENDER:
- {
- GameMessage* msg = TheMessageStream->appendMessage( GameMessage::MSG_DO_SURRENDER );
- msg->appendObjectIDArgument(INVALID_ID); // zero means "surrender to anyone"
- msg->appendBooleanArgument(true);
- disp = DESTROY_MESSAGE;
- break;
- }
- #endif
- //------------------------------------------------------------------------------- DEMO MESSAGES
- // --------------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_BATTLE_CRY:
- {
- TheAudio->addAudioEvent(&TheAudio->getMiscAudio()->m_battleCrySound);
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- // --------------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_AVI:
- {
- if (TheDisplay)
- TheDisplay->toggleMovieCapture();
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------
- case GameMessage::MSG_META_DEBUG_VTUNE_ON:
- {
- TheScriptEngine->setEnableVTune(true);
- TheInGameUI->message( UnicodeString( L"VTune Gathering is ON" ));
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- // --------------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEBUG_VTUNE_OFF:
- {
- TheScriptEngine->setEnableVTune(false);
- TheInGameUI->message( UnicodeString( L"VTune Gathering is OFF" ));
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- // --------------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEBUG_TOGGLE_FEATHER_WATER:
- {
- //TheScriptEngine->setEnableVTune(false);
- //TheInGameUI->message( UnicodeString( L"VTune Gathering is OFF" ));
- --TheWritableGlobalData->m_featherWater;
- if (TheGlobalData->m_featherWater < 0)
- TheWritableGlobalData->m_featherWater = 5;
-
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------------- DEMO MESSAGES
- //-----------------------------------------------------------------------------
- case GameMessage::MSG_META_DEBUG_WIN:
- {
- TheScriptEngine->debugVictory();
- TheInGameUI->message( UnicodeString( L"Instant Win" ));
- disp = DESTROY_MESSAGE;
- break;
- }
- //------------------------------------------------------------------------DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_TOGGLE_DEBUG_STATS:
- {
- if (TheDisplay->getDebugDisplayCallback() == StatDebugDisplay)
- TheDisplay->setDebugDisplayCallback(NULL);
- else
- TheDisplay->setDebugDisplayCallback(StatDebugDisplay);
- disp = DESTROY_MESSAGE;
- break;
- }
-
- //------------------------------------------------------------------------DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEBUG_SLEEPY_UPDATE_PERFORMANCE:
- {
- TheInGameUI->message( UnicodeString(L"Number of Sleepy Modules: %d."), TheGameLogic->getNumberSleepyUpdates() );
- break;
- }
- //------------------------------------------------------------------------DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEBUG_OBJECT_ID_PERFORMANCE:
- {
- static __int64 startTime64;
- static __int64 endTime64,freq64;
- QueryPerformanceCounter((LARGE_INTEGER *)&startTime64);
- QueryPerformanceFrequency((LARGE_INTEGER *)&freq64);
- Int numberLookups = 10000;
- for( Int testindex = 1; testindex < numberLookups; testindex++ )
- {
- Object *objPtr = TheGameLogic->findObjectByID((ObjectID)testindex);
- objPtr++;
- }
- QueryPerformanceCounter((LARGE_INTEGER *)&endTime64);
- double timeToUpdate = ((double)(endTime64-startTime64) / (double)(freq64));
- TheInGameUI->message( UnicodeString(L"Time to run %d ObjectID lookups is %f. Next index is %d."), numberLookups, timeToUpdate, (Int)TheGameLogic->getObjectIDCounter() );
- QueryPerformanceCounter((LARGE_INTEGER *)&startTime64);
- QueryPerformanceFrequency((LARGE_INTEGER *)&freq64);
- numberLookups = 100000;
- for( testindex = 1; testindex < numberLookups; testindex++ )
- {
- Object *objPtr = TheGameLogic->findObjectByID((ObjectID)testindex);
- objPtr++;
- }
- QueryPerformanceCounter((LARGE_INTEGER *)&endTime64);
- timeToUpdate = ((double)(endTime64-startTime64) / (double)(freq64));
- TheInGameUI->message( UnicodeString(L"Time to run %d ObjectID lookups is %f. Next index is %d."), numberLookups, timeToUpdate, (Int)TheGameLogic->getObjectIDCounter() );
- QueryPerformanceCounter((LARGE_INTEGER *)&startTime64);
- QueryPerformanceFrequency((LARGE_INTEGER *)&freq64);
- numberLookups = 1000000;
- for( testindex = 1; testindex < numberLookups; testindex++ )
- {
- Object *objPtr = TheGameLogic->findObjectByID((ObjectID)testindex);
- objPtr++;
- }
- QueryPerformanceCounter((LARGE_INTEGER *)&endTime64);
- timeToUpdate = ((double)(endTime64-startTime64) / (double)(freq64));
- TheInGameUI->message( UnicodeString(L"Time to run %d ObjectID lookups is %f. Next index is %d."), numberLookups, timeToUpdate, (Int)TheGameLogic->getObjectIDCounter() );
- break;
- }
- //------------------------------------------------------------------------DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEBUG_DRAWABLE_ID_PERFORMANCE:
- {
- static __int64 startTime64;
- static __int64 endTime64,freq64;
- QueryPerformanceCounter((LARGE_INTEGER *)&startTime64);
- QueryPerformanceFrequency((LARGE_INTEGER *)&freq64);
- Int numberLookups = 10000;
- for( Int testindex = 1; testindex < numberLookups; testindex++ )
- {
- Drawable *drawPtr = TheGameClient->findDrawableByID((DrawableID)testindex);
- drawPtr++;
- }
- QueryPerformanceCounter((LARGE_INTEGER *)&endTime64);
- double timeToUpdate = ((double)(endTime64-startTime64) / (double)(freq64));
- TheInGameUI->message( UnicodeString(L"Time to run %d DrawableID lookups is %f. Next index is %d."), numberLookups, timeToUpdate, (Int)TheGameClient->getDrawableIDCounter() );
- QueryPerformanceCounter((LARGE_INTEGER *)&startTime64);
- QueryPerformanceFrequency((LARGE_INTEGER *)&freq64);
- numberLookups = 100000;
- for( testindex = 1; testindex < numberLookups; testindex++ )
- {
- Drawable *drawPtr = TheGameClient->findDrawableByID((DrawableID)testindex);
- drawPtr++;
- }
- QueryPerformanceCounter((LARGE_INTEGER *)&endTime64);
- timeToUpdate = ((double)(endTime64-startTime64) / (double)(freq64));
- TheInGameUI->message( UnicodeString(L"Time to run %d DrawableID lookups is %f. Next index is %d."), numberLookups, timeToUpdate, (Int)TheGameClient->getDrawableIDCounter() );
- QueryPerformanceCounter((LARGE_INTEGER *)&startTime64);
- QueryPerformanceFrequency((LARGE_INTEGER *)&freq64);
- numberLookups = 1000000;
- for( testindex = 1; testindex < numberLookups; testindex++ )
- {
- Drawable *drawPtr = TheGameClient->findDrawableByID((DrawableID)testindex);
- drawPtr++;
- }
- QueryPerformanceCounter((LARGE_INTEGER *)&endTime64);
- timeToUpdate = ((double)(endTime64-startTime64) / (double)(freq64));
- TheInGameUI->message( UnicodeString(L"Time to run %d DrawableID lookups is %f. Next index is %d."), numberLookups, timeToUpdate, (Int)TheGameClient->getDrawableIDCounter() );
- break;
- }
- //--------------------------------------------------------------------------- END DEMO MESSAGES
- //--------------------------------------------------------------------------- END DEMO MESSAGES
- //--------------------------------------------------------------------------- END DEMO MESSAGES
- #endif // #if defined(_DEBUG) || defined(_INTERNAL)
- //------------------------------------------------------------------------DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- #if defined(_INTERNAL) || defined(_DEBUG)
- case GameMessage::MSG_META_DEMO_TOGGLE_AUDIODEBUG:
- {
- if (TheDisplay->getDebugDisplayCallback() == AudioDebugDisplay)
- TheDisplay->setDebugDisplayCallback(NULL);
- else
- TheDisplay->setDebugDisplayCallback(AudioDebugDisplay);
- disp = DESTROY_MESSAGE;
- break;
- }
- #endif//defined(_INTERNAL) || defined(_DEBUG)
-
- #ifdef DUMP_PERF_STATS
- //------------------------------------------------------------------------DEMO MESSAGES
- //-----------------------------------------------------------------------------------------
- case GameMessage::MSG_META_DEMO_PERFORM_STATISTICAL_DUMP:
- //Dump performance statistics for this frame.
- TheWritableGlobalData->m_dumpPerformanceStatistics = TRUE;
- TheInGameUI->message( UnicodeString( L"Statistics dump made on frame: %d" ), TheGameLogic->getFrame() );
- break;
- #endif // DUMP_PERF_STATS
- } // end switch( msg->type )
-
- return disp;
- } // end CommandTranslator
- static Bool isSystemMessage( const GameMessage *msg )
- {
- if (!msg) {
- return false;
- }
- GameMessage::Type msgType = msg->getType();
- switch (msgType)
- {
- case GameMessage::MSG_DESTROY_SELECTED_GROUP:
- case GameMessage::MSG_LOGIC_CRC:
- case GameMessage::MSG_SET_REPLAY_CAMERA:
- case GameMessage::MSG_FRAME_TICK:
- return TRUE;
- }
- return FALSE;
- }
|