ScriptActions.cpp 260 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: ScriptActions.cpp /////////////////////////////////////////////////////////////////////////
  24. // The game scripting engine. Interprets scripts.
  25. // Author: John Ahlquist, Nov. 2001
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  28. #include "Common/AudioAffect.h"
  29. #include "Common/AudioHandleSpecialValues.h"
  30. #include "Common/GameAudio.h"
  31. #include "Common/GameEngine.h"
  32. #include "Common/MapObject.h" // For MAP_XY_FACTOR
  33. #include "Common/PartitionSolver.h"
  34. #include "Common/Player.h"
  35. #include "Common/PlayerList.h"
  36. #include "Common/PlayerTemplate.h"
  37. #include "Common/Radar.h" // For TheRadar
  38. #include "Common/SpecialPower.h"
  39. #include "Common/ThingFactory.h"
  40. #include "Common/ThingTemplate.h"
  41. #include "Common/Team.h"
  42. #include "Common/Upgrade.h"
  43. #include "GameClient/Anim2D.h"
  44. #include "GameClient/CampaignManager.h"
  45. #include "GameClient/CommandXlat.h"
  46. #include "GameClient/ControlBar.h"
  47. #include "GameClient/Drawable.h"
  48. #include "GameClient/Eva.h"
  49. #include "GameClient/GadgetStaticText.h"
  50. #include "GameClient/GameClient.h"
  51. #include "GameClient/GameText.h"
  52. #include "GameClient/GUICallbacks.h"
  53. #include "GameClient/InGameUI.h"
  54. #include "GameClient/LookAtXlat.h"
  55. #include "GameClient/MessageBox.h"
  56. #include "GameClient/Mouse.h"
  57. #include "GameClient/View.h"
  58. #include "GameClient/GlobalLanguage.h"
  59. #include "GameClient/Snow.h"
  60. #include "GameLogic/AI.h"
  61. #include "GameLogic/AISkirmishPlayer.h"
  62. #include "GameLogic/Locomotor.h"
  63. #include "GameLogic/Module/AIUpdate.h"
  64. #include "GameLogic/Module/CaveContain.h"
  65. #include "GameLogic/Module/CommandButtonHuntUpdate.h"
  66. #include "GameLogic/Module/ContainModule.h"
  67. #include "GameLogic/Module/DeliverPayloadAIUpdate.h"
  68. #include "GameLogic/Module/SpecialPowerModule.h"
  69. #include "GameLogic/Module/SupplyWarehouseDockUpdate.h"
  70. #include "GameLogic/Module/TransportContain.h"
  71. #include "GameLogic/Module/MobNexusContain.h"
  72. #include "GameLogic/Module/RailroadGuideAIUpdate.h"
  73. #include "GameLogic/Module/StickyBombUpdate.h"
  74. #include "GameLogic/ObjectTypes.h"
  75. #include "GameLogic/PartitionManager.h"
  76. #include "GameLogic/PolygonTrigger.h"
  77. #include "GameLogic/ScriptActions.h"
  78. #include "GameLogic/ScriptEngine.h"
  79. #include "GameLogic/Weapon.h"
  80. #include "GameLogic/VictoryConditions.h"
  81. #include "GameLogic/AIPathfind.h"
  82. #ifdef _INTERNAL
  83. // for occasional debugging...
  84. //#pragma optimize("", off)
  85. //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
  86. #endif
  87. // Kind of hacky, but we need to dance on the guts of the terrain.
  88. extern void oversizeTheTerrain(Int amount);
  89. //-------------------------------------------------------------------------------------------------
  90. //-------------------------------------------------------------------------------------------------
  91. // when you set controlling player or merge teams, we don't always update all the upgrade stuff
  92. // or the indicator color. this allows us to force the situation. (srj)
  93. static void updateTeamAndPlayerStuff( Object *obj, void *userData )
  94. {
  95. if (obj)
  96. {
  97. obj->updateUpgradeModules();
  98. // srj sez: apparently we have to do this too, since Team::setControllingPlayer
  99. // does not. Might make more sense to do it there, but am scared to at this point.
  100. Drawable* draw = obj->getDrawable();
  101. if (draw)
  102. {
  103. if (TheGlobalData->m_timeOfDay == TIME_OF_DAY_NIGHT)
  104. draw->setIndicatorColor(obj->getNightIndicatorColor());
  105. else
  106. draw->setIndicatorColor(obj->getIndicatorColor());
  107. }
  108. }
  109. }
  110. //-------------------------------------------------------------------------------------------------
  111. //-------------------------------------------------------------------------------------------------
  112. // STATICS ////////////////////////////////////////////////////////////////////////////////////////
  113. // DEFINES ////////////////////////////////////////////////////////////////////////////////////////
  114. #define REALLY_FAR (100000 * MAP_XY_FACTOR)
  115. // GLOBALS ////////////////////////////////////////////////////////////////////////////////////////
  116. ScriptActionsInterface *TheScriptActions = NULL;
  117. GameWindow *ScriptActions::m_messageWindow = NULL;
  118. //-------------------------------------------------------------------------------------------------
  119. //-------------------------------------------------------------------------------------------------
  120. ScriptActions::ScriptActions()
  121. {
  122. m_suppressNewWindows = FALSE;
  123. m_unnamedUnit = AsciiString::TheEmptyString;
  124. } // end ScriptActions
  125. //-------------------------------------------------------------------------------------------------
  126. //-------------------------------------------------------------------------------------------------
  127. ScriptActions::~ScriptActions()
  128. {
  129. reset(); // just in case.
  130. } // end ~ScriptActions
  131. //-------------------------------------------------------------------------------------------------
  132. /** Init */
  133. //-------------------------------------------------------------------------------------------------
  134. void ScriptActions::init( void )
  135. {
  136. reset();
  137. } // end init
  138. //-------------------------------------------------------------------------------------------------
  139. /** Reset */
  140. //-------------------------------------------------------------------------------------------------
  141. void ScriptActions::reset( void )
  142. {
  143. m_suppressNewWindows = FALSE;
  144. closeWindows(FALSE); // Close victory or defeat windows.
  145. } // end reset
  146. //-------------------------------------------------------------------------------------------------
  147. /** Update */
  148. //-------------------------------------------------------------------------------------------------
  149. void ScriptActions::update( void )
  150. {
  151. // Empty for now. jba.
  152. } // end update
  153. //-------------------------------------------------------------------------------------------------
  154. /** closeWindows */
  155. //-------------------------------------------------------------------------------------------------
  156. void ScriptActions::closeWindows( Bool suppressNewWindows )
  157. {
  158. m_suppressNewWindows = suppressNewWindows;
  159. if (m_messageWindow) {
  160. TheWindowManager->winDestroy(m_messageWindow);
  161. m_messageWindow = NULL;
  162. }
  163. }
  164. //-------------------------------------------------------------------------------------------------
  165. /** doQuickVictory */
  166. //-------------------------------------------------------------------------------------------------
  167. void ScriptActions::doQuickVictory( void )
  168. {
  169. closeWindows(FALSE);
  170. TheGameLogic->closeWindows();
  171. doDisableInput();
  172. if(TheCampaignManager)
  173. TheCampaignManager->SetVictorious(TRUE);
  174. TheScriptEngine->startQuickEndGameTimer();
  175. }
  176. //-------------------------------------------------------------------------------------------------
  177. /** doSetInfantryLightingOverride */
  178. //-------------------------------------------------------------------------------------------------
  179. void ScriptActions::doSetInfantryLightingOverride(Real setting)
  180. {
  181. DEBUG_ASSERTCRASH( (setting == -1.0f) || (setting > 0.0f), ("Invalid setting (%d) in Infantry Lighting Override script.", setting) );
  182. TheWritableGlobalData->m_scriptOverrideInfantryLightScale = setting;
  183. }
  184. //-------------------------------------------------------------------------------------------------
  185. /** doVictory */
  186. //-------------------------------------------------------------------------------------------------
  187. void ScriptActions::doVictory( void )
  188. {
  189. closeWindows(FALSE);
  190. TheGameLogic->closeWindows();
  191. doDisableInput();
  192. if (!m_suppressNewWindows)
  193. {
  194. const Player *localPlayer = ThePlayerList->getLocalPlayer();
  195. Bool showObserverWindow = localPlayer->isPlayerObserver() || TheScriptEngine->hasShownMPLocalDefeatWindow();
  196. if(showObserverWindow)
  197. m_messageWindow = TheWindowManager->winCreateFromScript("Menus/ObserverQuit.wnd");
  198. else
  199. {
  200. m_messageWindow = TheWindowManager->winCreateFromScript("Menus/Victorious.wnd");
  201. }
  202. }
  203. if(TheCampaignManager)
  204. TheCampaignManager->SetVictorious(TRUE);
  205. TheScriptEngine->startEndGameTimer();
  206. }
  207. //-------------------------------------------------------------------------------------------------
  208. /** doDefeat */
  209. //-------------------------------------------------------------------------------------------------
  210. void ScriptActions::doDefeat( void )
  211. {
  212. closeWindows(FALSE);
  213. TheGameLogic->closeWindows();
  214. doDisableInput();
  215. if (!m_suppressNewWindows)
  216. {
  217. const Player *localPlayer = ThePlayerList->getLocalPlayer();
  218. Bool showObserverWindow = localPlayer->isPlayerObserver() || TheScriptEngine->hasShownMPLocalDefeatWindow();
  219. if(showObserverWindow)
  220. m_messageWindow = TheWindowManager->winCreateFromScript("Menus/ObserverQuit.wnd");
  221. else
  222. {
  223. m_messageWindow = TheWindowManager->winCreateFromScript("Menus/Defeat.wnd");
  224. }
  225. }
  226. if(TheCampaignManager)
  227. TheCampaignManager->SetVictorious(FALSE);
  228. TheScriptEngine->startEndGameTimer();
  229. }
  230. //-------------------------------------------------------------------------------------------------
  231. /** doLocalDefeat */
  232. //-------------------------------------------------------------------------------------------------
  233. void ScriptActions::doLocalDefeat( void )
  234. {
  235. TheScriptEngine->markMPLocalDefeatWindowShown();
  236. closeWindows(FALSE);
  237. TheGameLogic->closeWindows();
  238. if (!m_suppressNewWindows)
  239. {
  240. if(!TheVictoryConditions->amIObserver())
  241. m_messageWindow = TheWindowManager->winCreateFromScript("Menus/LocalDefeat.wnd");
  242. }
  243. if(TheCampaignManager)
  244. TheCampaignManager->SetVictorious(FALSE);
  245. TheScriptEngine->startCloseWindowTimer();
  246. }
  247. //-------------------------------------------------------------------------------------------------
  248. /** changeObjectPanelFlagForSingleObject */
  249. //-------------------------------------------------------------------------------------------------
  250. void ScriptActions::changeObjectPanelFlagForSingleObject(Object *obj, const AsciiString& flagToChange, Bool newVal )
  251. {
  252. // Enabled flag
  253. if (flagToChange == TheObjectFlagsNames[0])
  254. {
  255. obj->setScriptStatus(OBJECT_STATUS_SCRIPT_DISABLED, !newVal);
  256. return;
  257. }
  258. // Powered flag
  259. if (flagToChange == TheObjectFlagsNames[1])
  260. {
  261. obj->setScriptStatus(OBJECT_STATUS_SCRIPT_UNPOWERED, !newVal);
  262. return;
  263. }
  264. // Indestructible flag
  265. if (flagToChange == TheObjectFlagsNames[2])
  266. {
  267. BodyModuleInterface* body = obj->getBodyModule();
  268. if (body) {
  269. body->setIndestructible(newVal);
  270. }
  271. return;
  272. }
  273. // Unsellable flag
  274. if (flagToChange == TheObjectFlagsNames[3])
  275. {
  276. obj->setScriptStatus(OBJECT_STATUS_SCRIPT_UNSELLABLE, newVal);
  277. return;
  278. }
  279. // Selectable flag
  280. if (flagToChange == TheObjectFlagsNames[4])
  281. {
  282. if (obj->isSelectable() != newVal) {
  283. obj->setSelectable(newVal);
  284. }
  285. return;
  286. }
  287. // AI Recruitable flag
  288. if (flagToChange == TheObjectFlagsNames[5])
  289. {
  290. if (obj->getAIUpdateInterface()) {
  291. obj->getAIUpdateInterface()->setIsRecruitable(newVal);
  292. }
  293. return;
  294. }
  295. // Player targetable flag
  296. if( flagToChange == TheObjectFlagsNames[6] )
  297. {
  298. obj->setScriptStatus( OBJECT_STATUS_SCRIPT_TARGETABLE, newVal );
  299. return;
  300. }
  301. }
  302. //-------------------------------------------------------------------------------------------------
  303. /** doDebugMessage */
  304. //-------------------------------------------------------------------------------------------------
  305. void ScriptActions::doDebugMessage(const AsciiString& msg, Bool pause )
  306. {
  307. TheScriptEngine->AppendDebugMessage(msg, pause);
  308. }
  309. //-------------------------------------------------------------------------------------------------
  310. /** doPlaySoundEffect */
  311. //-------------------------------------------------------------------------------------------------
  312. void ScriptActions::doPlaySoundEffect(const AsciiString& sound)
  313. {
  314. AudioEventRTS audioEvent(sound);
  315. audioEvent.setIsLogicalAudio(true);
  316. audioEvent.setPlayerIndex(ThePlayerList->getLocalPlayer()->getPlayerIndex());
  317. TheAudio->addAudioEvent( &audioEvent );
  318. }
  319. //-------------------------------------------------------------------------------------------------
  320. /** doPlaySoundEffectAt */
  321. //-------------------------------------------------------------------------------------------------
  322. void ScriptActions::doPlaySoundEffectAt(const AsciiString& sound, const AsciiString& waypoint)
  323. {
  324. Waypoint *way = TheTerrainLogic->getWaypointByName(waypoint);
  325. if (!way) {
  326. return;
  327. }
  328. AudioEventRTS audioEvent(sound, way->getLocation());
  329. audioEvent.setIsLogicalAudio(true);
  330. audioEvent.setPlayerIndex(ThePlayerList->getLocalPlayer()->getPlayerIndex());
  331. TheAudio->addAudioEvent( &audioEvent );
  332. }
  333. //-------------------------------------------------------------------------------------------------
  334. /** doEnableObjectSound */
  335. //-------------------------------------------------------------------------------------------------
  336. void ScriptActions::doEnableObjectSound(const AsciiString& objectName, Bool enable )
  337. {
  338. Object *object = TheScriptEngine->getUnitNamed(objectName);
  339. if (!object)
  340. {
  341. return;
  342. }
  343. Drawable *drawable = object->getDrawable();
  344. if ( !drawable )
  345. {
  346. return;
  347. }
  348. drawable->enableAmbientSoundFromScript( enable );
  349. }
  350. //-------------------------------------------------------------------------------------------------
  351. /** doDamageTeamMembers */
  352. //-------------------------------------------------------------------------------------------------
  353. void ScriptActions::doDamageTeamMembers(const AsciiString& team, Real amount)
  354. {
  355. Team *theTeam = TheScriptEngine->getTeamNamed( team );
  356. // The team is the team based on the name, and the calling team (if any) and the team that
  357. // triggered the condition. jba. :)
  358. if (theTeam) {
  359. theTeam->damageTeamMembers(amount);
  360. }
  361. }
  362. //-------------------------------------------------------------------------------------------------
  363. /** doMoveToWaypoint */
  364. //-------------------------------------------------------------------------------------------------
  365. void ScriptActions::doMoveToWaypoint(const AsciiString& team, const AsciiString& waypoint)
  366. {
  367. Team *theTeam = TheScriptEngine->getTeamNamed( team );
  368. // The team is the team based on the name, and the calling team (if any) and the team that
  369. // triggered the condition. jba. :)
  370. if (theTeam) {
  371. AIGroup* theGroup = TheAI->createGroup();
  372. if (!theGroup) {
  373. return;
  374. }
  375. theTeam->getTeamAsAIGroup(theGroup);
  376. Waypoint *way = TheTerrainLogic->getWaypointByName(waypoint);
  377. if (way) {
  378. Coord3D destination = *way->getLocation();
  379. //DEBUG_LOG(("Moving team to waypoint %f, %f, %f\n", destination.x, destination.y, destination.z));
  380. theGroup->groupMoveToPosition( &destination, false, CMD_FROM_SCRIPT );
  381. }
  382. }
  383. }
  384. //-------------------------------------------------------------------------------------------------
  385. /** doNamedMoveToWaypoint */
  386. //-------------------------------------------------------------------------------------------------
  387. void ScriptActions::doNamedMoveToWaypoint(const AsciiString& unit, const AsciiString& waypoint)
  388. {
  389. Object *theObj = TheScriptEngine->getUnitNamed( unit );
  390. if (theObj)
  391. {
  392. Waypoint *way = TheTerrainLogic->getWaypointByName(waypoint);
  393. if (!way) {
  394. return;
  395. }
  396. Coord3D destination = *way->getLocation();
  397. AIUpdateInterface *aiUpdate = theObj->getAIUpdateInterface();
  398. if (!aiUpdate) {
  399. return;
  400. }
  401. aiUpdate->clearWaypointQueue();
  402. theObj->leaveGroup();
  403. aiUpdate->chooseLocomotorSet( LOCOMOTORSET_NORMAL );
  404. aiUpdate->aiMoveToPosition( &destination, CMD_FROM_SCRIPT );
  405. }
  406. }
  407. //-------------------------------------------------------------------------------------------------
  408. /** doCameraFollowNamed */
  409. //-------------------------------------------------------------------------------------------------
  410. void ScriptActions::doCameraFollowNamed(const AsciiString& unit, Bool snapToUnit)
  411. {
  412. Object *theObj = TheScriptEngine->getUnitNamed( unit );
  413. if (theObj)
  414. {
  415. TheTacticalView->setCameraLock(theObj->getID());
  416. if (snapToUnit)
  417. TheTacticalView->snapToCameraLock();
  418. TheTacticalView->setSnapMode( View::LOCK_FOLLOW, 0.0f );
  419. }
  420. }
  421. //-------------------------------------------------------------------------------------------------
  422. /** doStopCameraFollowUnit */
  423. //-------------------------------------------------------------------------------------------------
  424. void ScriptActions::doStopCameraFollowUnit(void)
  425. {
  426. TheTacticalView->setCameraLock(INVALID_ID);
  427. }
  428. //-------------------------------------------------------------------------------------------------
  429. /** doSetTeamState */
  430. //-------------------------------------------------------------------------------------------------
  431. void ScriptActions::doSetTeamState(const AsciiString& team, const AsciiString& state)
  432. {
  433. Team *theTeam = TheScriptEngine->getTeamNamed( team );
  434. // The team is the team based on the name, and the calling team (if any) and the team that
  435. // triggered the condition. jba. :)
  436. if (theTeam) {
  437. theTeam->setState(state);
  438. }
  439. }
  440. /** doCreateReinforcements */
  441. //-------------------------------------------------------------------------------------------------
  442. void ScriptActions::doCreateReinforcements(const AsciiString& team, const AsciiString& waypoint)
  443. {
  444. TeamPrototype *theTeamProto = TheTeamFactory->findTeamPrototype( team );
  445. Coord3D destination;
  446. Bool needToMoveToDestination = false;
  447. //Validate the waypoint
  448. Waypoint *way = TheTerrainLogic->getWaypointByName(waypoint);
  449. if (way==NULL)
  450. {
  451. return;
  452. }
  453. destination = *way->getLocation();
  454. if (!theTeamProto) {
  455. DEBUG_LOG(("***WARNING - Team %s not found.\n", team));
  456. return;
  457. }
  458. const TeamTemplateInfo *pInfo = theTeamProto->getTemplateInfo();
  459. Coord3D origin = destination;
  460. way = TheTerrainLogic->getWaypointByName(pInfo->m_startReinforceWaypoint);
  461. if (way) {
  462. origin = *way->getLocation();
  463. if (origin.x != destination.x || origin.y != destination.y) {
  464. needToMoveToDestination = true;
  465. }
  466. }
  467. //Create the team (not the units inside team).
  468. Team *theTeam = TheTeamFactory->createInactiveTeam( team );
  469. if (theTeam==NULL) {
  470. return;
  471. }
  472. const ThingTemplate *transportTemplate;
  473. const ThingTemplate *unitTemplate;
  474. //Create the transport first (if applicable), so we can determine if it has paradrop capabilities.
  475. //If so, we'll be doing a lot of things differently!
  476. Object *transport=NULL;
  477. ContainModuleInterface *contain = NULL;
  478. transportTemplate = TheThingFactory->findTemplate( pInfo->m_transportUnitType );
  479. if( transportTemplate )
  480. {
  481. transport = TheThingFactory->newObject( transportTemplate, theTeam );
  482. transport->setPosition( &origin );
  483. transport->setOrientation( 0.0f );
  484. if( transport )
  485. {
  486. contain = transport->getContain();
  487. }
  488. }
  489. Int transportCount = 1;
  490. //Check to see if we have a transport, and if our transport has paradrop capabilities. If this is the
  491. //case, we'll need to create each unit inside "parachute containers".
  492. static NameKeyType key_DeliverPayloadAIUpdate = NAMEKEY("DeliverPayloadAIUpdate");
  493. DeliverPayloadAIUpdate *dp = NULL;
  494. if( transport )
  495. {
  496. dp = (DeliverPayloadAIUpdate*)transport->findUpdateModule(key_DeliverPayloadAIUpdate);
  497. }
  498. //Our tranport has a deliverPayload update module. This means it'll do airborned drops.
  499. const ThingTemplate* putInContainerTemplate = NULL;
  500. if( dp )
  501. {
  502. //Check to see if we are packaging our units
  503. putInContainerTemplate = dp->getPutInContainerTemplateViaModuleData();
  504. }
  505. //Now create the units that make up the team.
  506. Int i, j;
  507. for (i=0; i<pInfo->m_numUnitsInfo; i++)
  508. {
  509. // get thing template based from map object name
  510. unitTemplate = TheThingFactory->findTemplate(pInfo->m_unitsInfo[i].unitThingName);
  511. Coord3D pos = origin;
  512. if (unitTemplate && theTeam)
  513. {
  514. Object *obj = NULL;
  515. for (j=0; j<pInfo->m_unitsInfo[i].maxUnits; j++)
  516. {
  517. // create new object in the world
  518. obj = TheThingFactory->newObject( unitTemplate, theTeam );
  519. if( obj )
  520. {
  521. /// @todo - have better positioning for reinforcement units.
  522. pos.x = origin.x + 2.25*(j)*obj->getGeometryInfo().getMajorRadius();
  523. pos.z = TheTerrainLogic->getGroundHeight(pos.x, pos.y);
  524. obj->setPosition( &pos );
  525. obj->setOrientation(0.0f);
  526. } // end if
  527. }
  528. if (obj) pos.y += 2*obj->getGeometryInfo().getMajorRadius();
  529. }
  530. origin.y = pos.y;
  531. }
  532. origin = destination;
  533. if (pInfo->m_teamStartsFull)
  534. {
  535. // Have them load into transports in the team.
  536. EntriesVec vecOfUnits;
  537. SpacesVec vecOfTransports;
  538. for (DLINK_ITERATOR<Object> iter = theTeam->iterate_TeamMemberList(); !iter.done(); iter.advance())
  539. {
  540. Object *obj = iter.cur();
  541. if (!obj) {
  542. continue;
  543. }
  544. if (obj==transport) {
  545. continue; // Skip the one we created. The team loads into the transports on the team for team starts full. jba
  546. }
  547. if (obj->isKindOf(KINDOF_TRANSPORT))
  548. {
  549. ContainModuleInterface *contain = obj->getContain();
  550. if( contain )
  551. {
  552. vecOfTransports.push_back(std::make_pair(obj->getID(), ((TransportContain*)contain)->getContainMax()));
  553. }
  554. else
  555. {
  556. DEBUG_CRASH( ("doCreateReinforcement script -- transport doesn't have contain to hold guys.") );
  557. }
  558. }
  559. else
  560. {
  561. Int slots = obj->getTransportSlotCount();
  562. if (slots==0) slots = 0x7fffff; // 0 means lots.
  563. vecOfUnits.push_back(std::make_pair(obj->getID(), slots));
  564. }
  565. }
  566. // we've now built the necessary stuff. Partition the units.
  567. PartitionSolver partition(vecOfUnits, vecOfTransports, PREFER_FAST_SOLUTION);
  568. partition.solve();
  569. SolutionVec solution = partition.getSolution();
  570. for (int i = 0; i < solution.size(); ++i) {
  571. Object *unit = TheGameLogic->findObjectByID(solution[i].first);
  572. Object *trans = TheGameLogic->findObjectByID(solution[i].second);
  573. if (!unit || !trans) {
  574. continue;
  575. }
  576. ContainModuleInterface *contain = trans->getContain();
  577. if (contain)
  578. {
  579. contain->addToContain(unit);
  580. }
  581. }
  582. }
  583. contain = NULL;
  584. if( transport )
  585. {
  586. contain = transport->getContain();
  587. }
  588. if (contain)
  589. {
  590. for (DLINK_ITERATOR<Object> iter = theTeam->iterate_TeamMemberList(); !iter.done(); iter.advance())
  591. {
  592. Object *obj = iter.cur();
  593. if (!obj)
  594. {
  595. continue;
  596. }
  597. if (obj->getTemplate()->isEquivalentTo(transport->getTemplate()) )
  598. {
  599. // it's our transport.
  600. continue;
  601. }
  602. if (obj->getContainedBy() != NULL)
  603. {
  604. continue;
  605. }
  606. //Check to see if it's a valid transport for this unit, even if it's full.
  607. Coord3D pos = origin;
  608. pos.x += transportCount*transport->getGeometryInfo().getMajorRadius();
  609. pos.z = TheTerrainLogic->getGroundHeight(pos.x, pos.y);
  610. if (contain && contain->isValidContainerFor(obj, false))
  611. {
  612. //Now that we know it fits in the transport, check to see if it's full. If it is,
  613. //then we'll create a new transport.
  614. if (!contain->isValidContainerFor(obj, true))
  615. {
  616. // full, try building another.
  617. transport = TheThingFactory->newObject( transportTemplate, theTeam );
  618. transport->setPosition( &pos );
  619. transportCount++;
  620. transport->setOrientation(0.0f);
  621. if (transport)
  622. {
  623. contain = transport->getContain();
  624. }
  625. }
  626. //If our unit is going to be put in another container (such as infantry being contained by a parachute)
  627. //do so now.
  628. if( putInContainerTemplate )
  629. {
  630. Object* container = TheThingFactory->newObject( putInContainerTemplate, theTeam );
  631. container->setPosition( &pos );
  632. //Make sure this is valid.
  633. if( container->getContain() && container->getContain()->isValidContainerFor( obj, true ) )
  634. {
  635. container->getContain()->addToContain( obj );
  636. obj = container;
  637. }
  638. else
  639. {
  640. DEBUG_CRASH( ("doCreateReinforcements: PutInContainer %s is full, or not valid for the payload %s!", putInContainerTemplate->getName().str(), obj->getTemplate()->getName().str() ) );
  641. }
  642. }
  643. //Add our unit to the transport.
  644. contain->addToContain( obj );
  645. }
  646. }
  647. }
  648. if (theTeam)
  649. {
  650. if (transport)
  651. {
  652. for (DLINK_ITERATOR<Object> iter = theTeam->iterate_TeamMemberList(); !iter.done(); iter.advance())
  653. {
  654. Object *obj = iter.cur();
  655. if (!obj)
  656. {
  657. continue;
  658. }
  659. AIUpdateInterface *ai = obj->getAIUpdateInterface();
  660. if (obj->getTemplate()->isEquivalentTo(transport->getTemplate()) )
  661. {
  662. if( dp )
  663. {
  664. dp->deliverPayloadViaModuleData( &destination );
  665. }
  666. // it's our transport.
  667. else if( pInfo->m_transportsExit )
  668. {
  669. if( ai )
  670. {
  671. ai->chooseLocomotorSet( LOCOMOTORSET_NORMAL );
  672. ai->aiMoveToAndEvacuateAndExit(&destination, CMD_FROM_SCRIPT);
  673. }
  674. }
  675. else
  676. {
  677. if( ai )
  678. {
  679. ai->chooseLocomotorSet( LOCOMOTORSET_NORMAL );
  680. ai->aiMoveToAndEvacuate( &destination, CMD_FROM_SCRIPT );
  681. }
  682. }
  683. }
  684. else
  685. {
  686. // If there are any units that aren't transportable, move them to the goal.
  687. if( !obj->isDisabledByType( DISABLED_HELD ) )
  688. {
  689. if( ai )
  690. {
  691. ai->chooseLocomotorSet( LOCOMOTORSET_NORMAL );
  692. ai->aiMoveToPosition(&destination, CMD_FROM_SCRIPT);
  693. }
  694. }
  695. }
  696. }
  697. }
  698. else
  699. {
  700. theTeam->setActive();
  701. if (needToMoveToDestination)
  702. {
  703. AIGroup* theGroup = TheAI->createGroup();
  704. if (!theGroup)
  705. {
  706. return;
  707. }
  708. theTeam->getTeamAsAIGroup(theGroup);
  709. theGroup->groupMoveToPosition( &destination, false, CMD_FROM_SCRIPT );
  710. }
  711. }
  712. }
  713. }
  714. //-------------------------------------------------------------------------------------------------
  715. /** doMoveCameraTo */
  716. //-------------------------------------------------------------------------------------------------
  717. void ScriptActions::doMoveCameraTo(const AsciiString& waypoint, Real sec, Real cameraStutterSec, Real easeIn, Real easeOut)
  718. {
  719. for (Waypoint *way = TheTerrainLogic->getFirstWaypoint(); way; way = way->getNext()) {
  720. if (way->getName() == waypoint) {
  721. Coord3D destination = *way->getLocation();
  722. TheTacticalView->moveCameraTo(&destination, sec*1000, cameraStutterSec*1000, true, easeIn*1000.0f, easeOut*1000.0f);
  723. break;
  724. }
  725. }
  726. }
  727. //-------------------------------------------------------------------------------------------------
  728. /** doZoomCamera */
  729. //-------------------------------------------------------------------------------------------------
  730. void ScriptActions::doZoomCamera(Real zoom, Real sec, Real easeIn, Real easeOut)
  731. {
  732. TheTacticalView->zoomCamera(zoom, sec*1000.0f, easeIn*1000.0f, easeOut*1000.0f);
  733. }
  734. //-------------------------------------------------------------------------------------------------
  735. /** doPitchCamera */
  736. //-------------------------------------------------------------------------------------------------
  737. void ScriptActions::doPitchCamera(Real pitch, Real sec, Real easeIn, Real easeOut)
  738. {
  739. TheTacticalView->pitchCamera(pitch, sec*1000.0f, easeIn*1000.0f, easeOut*1000.0f);
  740. }
  741. //-------------------------------------------------------------------------------------------------
  742. /** doOversizeTheTerrain */
  743. //-------------------------------------------------------------------------------------------------
  744. void ScriptActions::doOversizeTheTerrain(Int amount)
  745. {
  746. oversizeTheTerrain(amount);
  747. Coord2D offset;
  748. offset.x = 0.0001f;
  749. offset.y = 0.0001f;
  750. TheTacticalView->scrollBy(&offset);
  751. offset.x = -0.0001f;
  752. offset.y = -0.0001f;
  753. TheTacticalView->scrollBy(&offset);
  754. }
  755. //-------------------------------------------------------------------------------------------------
  756. /** doSetupCamera */
  757. //-------------------------------------------------------------------------------------------------
  758. void ScriptActions::doSetupCamera(const AsciiString& waypoint, Real zoom, Real pitch, const AsciiString& lookAtWaypoint)
  759. {
  760. Waypoint *way = TheTerrainLogic->getWaypointByName(waypoint);
  761. if (way==NULL) return;
  762. Coord3D pos = *way->getLocation();
  763. Waypoint *lookat = TheTerrainLogic->getWaypointByName(lookAtWaypoint);
  764. if (lookat==NULL) return;
  765. Coord3D destination = *lookat->getLocation();
  766. TheTacticalView->moveCameraTo(&pos, 0, 0, true, 0.0f, 0.0f);
  767. TheTacticalView->cameraModLookToward(&destination);
  768. TheTacticalView->cameraModFinalPitch(pitch, 0.0f, 0.0f);
  769. TheTacticalView->cameraModFinalZoom(zoom, 0.0f, 0.0f);
  770. }
  771. //-------------------------------------------------------------------------------------------------
  772. /** doModCameraLookToward */
  773. //-------------------------------------------------------------------------------------------------
  774. void ScriptActions::doModCameraLookToward(const AsciiString& waypoint)
  775. {
  776. for (Waypoint *way = TheTerrainLogic->getFirstWaypoint(); way; way = way->getNext()) {
  777. if (way->getName() == waypoint) {
  778. Coord3D destination = *way->getLocation();
  779. TheTacticalView->cameraModLookToward(&destination);
  780. break;
  781. }
  782. }
  783. }
  784. //-------------------------------------------------------------------------------------------------
  785. /** doModCameraFinalLookToward */
  786. //-------------------------------------------------------------------------------------------------
  787. void ScriptActions::doModCameraFinalLookToward(const AsciiString& waypoint)
  788. {
  789. for (Waypoint *way = TheTerrainLogic->getFirstWaypoint(); way; way = way->getNext()) {
  790. if (way->getName() == waypoint) {
  791. Coord3D destination = *way->getLocation();
  792. TheTacticalView->cameraModFinalLookToward(&destination);
  793. break;
  794. }
  795. }
  796. }
  797. //-------------------------------------------------------------------------------------------------
  798. /** doModCameraMoveToSelection */
  799. //-------------------------------------------------------------------------------------------------
  800. void ScriptActions::doModCameraMoveToSelection(void)
  801. {
  802. Int count=0;
  803. Coord3D destination;
  804. destination.x=destination.y=destination.z = 0;
  805. for (Drawable *d = TheGameClient->firstDrawable(); d; d = d->getNextDrawable())
  806. {
  807. if (d->isSelected())
  808. {
  809. Coord3D pos = *d->getPosition();
  810. destination.x += pos.x;
  811. destination.y += pos.y;
  812. destination.z += pos.z;
  813. count++;
  814. }
  815. }
  816. if (count) {
  817. destination.z /= count;
  818. destination.x /= count;
  819. destination.y /= count;
  820. TheTacticalView->cameraModFinalMoveTo(&destination);
  821. }
  822. }
  823. //-------------------------------------------------------------------------------------------------
  824. /** doResetCamera */
  825. //-------------------------------------------------------------------------------------------------
  826. void ScriptActions::doResetCamera(const AsciiString& waypoint, Real sec, Real easeIn, Real easeOut)
  827. {
  828. for (Waypoint *way = TheTerrainLogic->getFirstWaypoint(); way; way = way->getNext()) {
  829. if (way->getName() == waypoint) {
  830. Coord3D destination = *way->getLocation();
  831. TheTacticalView->resetCamera(&destination, sec*1000, easeIn*1000.0f, easeOut*1000.0f);
  832. break;
  833. }
  834. }
  835. }
  836. //-------------------------------------------------------------------------------------------------
  837. /** doRotateCamera around the object we are looking at. */
  838. //-------------------------------------------------------------------------------------------------
  839. void ScriptActions::doRotateCamera(Real rotations, Real sec, Real easeIn, Real easeOut)
  840. {
  841. TheTacticalView->rotateCamera(rotations, sec*1000.0f, easeIn*1000.0f, easeOut*1000.0f);
  842. }
  843. //-------------------------------------------------------------------------------------------------
  844. /** doRotateCameraTowardObject */
  845. //-------------------------------------------------------------------------------------------------
  846. void ScriptActions::doRotateCameraTowardObject(const AsciiString& unitName, Real sec, Real holdSec, Real easeIn, Real easeOut)
  847. {
  848. const Object *unit = TheScriptEngine->getUnitNamed(unitName);
  849. if (!unit)
  850. return;
  851. TheTacticalView->rotateCameraTowardObject(unit->getID(), sec*1000.0f, holdSec*1000.0f, easeIn*1000.0f, easeOut*1000.0f);
  852. }
  853. //-------------------------------------------------------------------------------------------------
  854. /** doRotateCameraTowardWaypoint */
  855. //-------------------------------------------------------------------------------------------------
  856. void ScriptActions::doRotateCameraTowardWaypoint(const AsciiString& waypointName, Real sec, Real easeIn, Real easeOut, Bool reverseRotation)
  857. {
  858. Waypoint *way = TheTerrainLogic->getWaypointByName(waypointName);
  859. if (way==NULL) return;
  860. TheTacticalView->rotateCameraTowardPosition(way->getLocation(), sec*1000.0f, easeIn*1000.0f, easeOut*1000.0f, reverseRotation);
  861. }
  862. //-------------------------------------------------------------------------------------------------
  863. /** doMoveAlongWaypointPath */
  864. //-------------------------------------------------------------------------------------------------
  865. void ScriptActions::doMoveCameraAlongWaypointPath(const AsciiString& waypoint, Real sec, Real cameraStutterSec, Real easeIn, Real easeOut)
  866. {
  867. for (Waypoint *way = TheTerrainLogic->getFirstWaypoint(); way; way = way->getNext()) {
  868. if (way->getName() == waypoint) {
  869. TheTacticalView->moveCameraAlongWaypointPath(way, sec*1000, cameraStutterSec*1000, true, easeIn*1000.0f, easeOut*1000.0f);
  870. break;
  871. }
  872. }
  873. }
  874. //-------------------------------------------------------------------------------------------------
  875. /** doCreateObject */
  876. //-------------------------------------------------------------------------------------------------
  877. void ScriptActions::doCreateObject(const AsciiString& objectName, const AsciiString& thingName, const AsciiString& teamName, Coord3D *pos, Real angle )
  878. {
  879. Object* pOldObj = NULL;
  880. if (objectName != m_unnamedUnit) {
  881. pOldObj = TheScriptEngine->getUnitNamed(objectName);
  882. if (pOldObj && !pOldObj->isEffectivelyDead()) {
  883. AsciiString str = "WARNING - Object with name ";
  884. str.concat(objectName);
  885. str.concat(" already exists. Failed Create.");
  886. TheScriptEngine->AppendDebugMessage(str, false);
  887. // Unit by that name already exists
  888. return;
  889. }
  890. }
  891. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  892. // The team is the team based on the name, and the calling team (if any) and the team that
  893. // triggered the condition. jba. :)
  894. if (theTeam==NULL) {
  895. // We may need to create the team.
  896. theTeam = TheTeamFactory->createTeam( teamName );
  897. }
  898. if (!theTeam) {
  899. TheScriptEngine->AppendDebugMessage("***WARNING - Team not found:***", false);
  900. TheScriptEngine->AppendDebugMessage(teamName, true);
  901. DEBUG_LOG(("WARNING - Team %s not found.\n", teamName.str()));
  902. return;
  903. }
  904. const ThingTemplate *thingTemplate;
  905. // get thing template based from map object name
  906. thingTemplate = TheThingFactory->findTemplate(thingName);
  907. if (thingTemplate) {
  908. // create new object in the world
  909. Object *obj = TheThingFactory->newObject( thingTemplate, theTeam );
  910. if( obj )
  911. {
  912. if (objectName != m_unnamedUnit) {
  913. obj->setName(objectName);
  914. if (pOldObj || TheScriptEngine->didUnitExist(objectName)) {
  915. TheScriptEngine->transferObjectName(objectName, obj);
  916. } else {
  917. TheScriptEngine->addObjectToCache(obj);
  918. }
  919. }
  920. obj->setOrientation(angle);
  921. obj->setPosition( pos );
  922. if ( obj->isKindOf( KINDOF_BLAST_CRATER ) ) // since these footprints are permanent
  923. {
  924. TheTerrainLogic->createCraterInTerrain( obj );
  925. TheAI->pathfinder()->addObjectToPathfindMap( obj );
  926. }
  927. } // end if
  928. } else {
  929. DEBUG_LOG(("WARNING - ThingTemplate '%s' not found.\n", thingName.str()));
  930. }
  931. }
  932. //-------------------------------------------------------------------------------------------------
  933. /** doAttack */
  934. //-------------------------------------------------------------------------------------------------
  935. void ScriptActions::doAttack(const AsciiString& attackerName, const AsciiString& victimName)
  936. {
  937. Team *attackingTeam = TheScriptEngine->getTeamNamed( attackerName );
  938. // The team is the team based on the name, and the calling team (if any) and the team that
  939. // triggered the condition. jba. :)
  940. const Team *victimTeam = TheScriptEngine->getTeamNamed( victimName );
  941. // sanity
  942. if( attackingTeam == NULL || victimTeam == NULL )
  943. return;
  944. AIGroup *aiGroup = TheAI->createGroup();
  945. if (!aiGroup) {
  946. return;
  947. }
  948. attackingTeam->getTeamAsAIGroup(aiGroup);
  949. aiGroup->groupAttackTeam(victimTeam, NO_MAX_SHOTS_LIMIT, CMD_FROM_SCRIPT);
  950. }
  951. //-------------------------------------------------------------------------------------------------
  952. /** doNamedAttack */
  953. //-------------------------------------------------------------------------------------------------
  954. void ScriptActions::doNamedAttack(const AsciiString& attackerName, const AsciiString& victimName)
  955. {
  956. /// @todo Implement me (MSB)
  957. Object *attackingObj = TheScriptEngine->getUnitNamed( attackerName );
  958. Object *victimObj = TheScriptEngine->getUnitNamed( victimName );
  959. if (!attackingObj || !victimObj) {
  960. return;
  961. }
  962. // tell every member of attacking team to attack a random member of victim team
  963. {
  964. AIUpdateInterface *aiUpdate = attackingObj->getAIUpdateInterface();
  965. if (aiUpdate)
  966. {
  967. /// @todo Teams should have a method that returns the number of members in the team (MSB)
  968. attackingObj->leaveGroup();
  969. aiUpdate->chooseLocomotorSet(LOCOMOTORSET_NORMAL);
  970. aiUpdate->aiForceAttackObject( victimObj, NO_MAX_SHOTS_LIMIT, CMD_FROM_SCRIPT );
  971. }
  972. }
  973. }
  974. //-------------------------------------------------------------------------------------------------
  975. /** doBuildBuilding */
  976. //-------------------------------------------------------------------------------------------------
  977. void ScriptActions::doBuildBuilding(const AsciiString& buildingType)
  978. {
  979. // This action ALWAYS occur on the current player.
  980. Player *thePlayer = TheScriptEngine->getCurrentPlayer();
  981. if (thePlayer) {
  982. thePlayer->buildSpecificBuilding(buildingType);
  983. }
  984. }
  985. //-------------------------------------------------------------------------------------------------
  986. /** doBuildSupplyCenter */
  987. //-------------------------------------------------------------------------------------------------
  988. void ScriptActions::doBuildSupplyCenter(const AsciiString& player, const AsciiString& buildingType, Int cash)
  989. {
  990. Player* thePlayer = TheScriptEngine->getPlayerFromAsciiString(player);
  991. if (thePlayer) {
  992. thePlayer->buildBySupplies(cash, buildingType);
  993. }
  994. }
  995. //-------------------------------------------------------------------------------------------------
  996. /** doBuildObjectNearestTeam */
  997. //-------------------------------------------------------------------------------------------------
  998. void ScriptActions::doBuildObjectNearestTeam( const AsciiString& playerName, const AsciiString& buildingType, const AsciiString& teamName )
  999. {
  1000. Player *thePlayer = TheScriptEngine->getPlayerFromAsciiString( playerName );
  1001. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  1002. if( thePlayer && theTeam )
  1003. {
  1004. thePlayer->buildSpecificBuildingNearestTeam( buildingType, theTeam );
  1005. }
  1006. }
  1007. //-------------------------------------------------------------------------------------------------
  1008. /** doBuildUpgrade */
  1009. //-------------------------------------------------------------------------------------------------
  1010. void ScriptActions::doBuildUpgrade(const AsciiString& player, const AsciiString& upgrade)
  1011. {
  1012. Player* thePlayer = TheScriptEngine->getPlayerFromAsciiString(player);
  1013. if (thePlayer) {
  1014. thePlayer->buildUpgrade(upgrade);
  1015. }
  1016. }
  1017. //-------------------------------------------------------------------------------------------------
  1018. /** doBuildBaseDefense */
  1019. //-------------------------------------------------------------------------------------------------
  1020. void ScriptActions::doBuildBaseDefense(Bool flank)
  1021. {
  1022. // This action ALWAYS occur on the current player.
  1023. Player *thePlayer = TheScriptEngine->getCurrentPlayer();
  1024. if (thePlayer) {
  1025. thePlayer->buildBaseDefense(flank);
  1026. }
  1027. }
  1028. //-------------------------------------------------------------------------------------------------
  1029. /** doBuildBuilding */
  1030. //-------------------------------------------------------------------------------------------------
  1031. void ScriptActions::doBuildBaseStructure(const AsciiString& buildingType, Bool flank)
  1032. {
  1033. // This action ALWAYS occur on the current player.
  1034. Player *thePlayer = TheScriptEngine->getCurrentPlayer();
  1035. if (thePlayer) {
  1036. thePlayer->buildBaseDefenseStructure(buildingType, flank);
  1037. }
  1038. }
  1039. //-------------------------------------------------------------------------------------------------
  1040. /** createUnitOnTeamAt */
  1041. //-------------------------------------------------------------------------------------------------
  1042. void ScriptActions::createUnitOnTeamAt(const AsciiString& unitName, const AsciiString& objType, const AsciiString& teamName, const AsciiString& waypoint)
  1043. {
  1044. Object* pOldObj = TheScriptEngine->getUnitNamed(unitName);
  1045. if (pOldObj && !pOldObj->isEffectivelyDead()) {
  1046. AsciiString str = "WARNING - Object with name ";
  1047. str.concat(unitName);
  1048. str.concat(" already exists. Failed Create.");
  1049. TheScriptEngine->AppendDebugMessage(str, false);
  1050. // Unit by that name already exists
  1051. return;
  1052. }
  1053. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  1054. // The team is the team based on the name, and the calling team (if any) and the team that
  1055. // triggered the condition. jba. :)
  1056. if (theTeam==NULL) {
  1057. // We may need to create the team.
  1058. theTeam = TheTeamFactory->createTeam( teamName );
  1059. }
  1060. if (!theTeam) {
  1061. TheScriptEngine->AppendDebugMessage("***WARNING - Team not found:***", false);
  1062. TheScriptEngine->AppendDebugMessage(teamName, true);
  1063. DEBUG_LOG(("WARNING - Team %s not found.\n", teamName.str()));
  1064. return;
  1065. }
  1066. const ThingTemplate *thingTemplate;
  1067. // get thing template based from map object name
  1068. thingTemplate = TheThingFactory->findTemplate(objType);
  1069. if (thingTemplate) {
  1070. // create new object in the world
  1071. Object *obj = TheThingFactory->newObject( thingTemplate, theTeam );
  1072. if( obj )
  1073. {
  1074. if (unitName != m_unnamedUnit) {
  1075. obj->setName(unitName);
  1076. if (pOldObj || TheScriptEngine->didUnitExist(unitName)) {
  1077. TheScriptEngine->transferObjectName(unitName, obj);
  1078. } else {
  1079. TheScriptEngine->addObjectToCache(obj);
  1080. }
  1081. }
  1082. Waypoint *way = TheTerrainLogic->getWaypointByName( waypoint );
  1083. if (way)
  1084. {
  1085. Coord3D destination = *way->getLocation();
  1086. obj->setPosition(&destination);
  1087. }
  1088. } // end if
  1089. } else {
  1090. DEBUG_LOG(("WARNING - ThingTemplate '%s' not found.\n", objType.str()));
  1091. }
  1092. }
  1093. //-------------------------------------------------------------------------------------------------
  1094. /** updateNamedAttackPrioritySet */
  1095. //-------------------------------------------------------------------------------------------------
  1096. void ScriptActions::updateNamedAttackPrioritySet(const AsciiString& unitName, const AsciiString& attackPrioritySet)
  1097. {
  1098. Object *theSrcUnit = TheScriptEngine->getUnitNamed(unitName);
  1099. if (!theSrcUnit) {
  1100. return;
  1101. }
  1102. AIUpdateInterface *pInterface = theSrcUnit->getAIUpdateInterface();
  1103. if (!pInterface) {
  1104. return;
  1105. }
  1106. const AttackPriorityInfo *info = TheScriptEngine->getAttackInfo(attackPrioritySet);
  1107. pInterface->setAttackInfo(info);
  1108. }
  1109. //-------------------------------------------------------------------------------------------------
  1110. /** updateTeamAttackPrioritySet */
  1111. //-------------------------------------------------------------------------------------------------
  1112. void ScriptActions::updateTeamAttackPrioritySet(const AsciiString& teamName, const AsciiString& attackPrioritySet)
  1113. {
  1114. Team *team = TheScriptEngine->getTeamNamed(teamName);
  1115. if (!team) {
  1116. return;
  1117. }
  1118. const AttackPriorityInfo *info = TheScriptEngine->getAttackInfo(attackPrioritySet);
  1119. if (info->getName().isNotEmpty()) {
  1120. team->setAttackPriorityName(info->getName());
  1121. }
  1122. // Set team member's attack priority.
  1123. for (DLINK_ITERATOR<Object> iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance())
  1124. {
  1125. Object *obj = iter.cur();
  1126. AIUpdateInterface *ai = obj->getAIUpdateInterface();
  1127. if (!ai) {
  1128. continue;
  1129. }
  1130. ai->setAttackInfo(info);
  1131. }
  1132. }
  1133. //-------------------------------------------------------------------------------------------------
  1134. /** updateBaseConstructionSpeed */
  1135. //-------------------------------------------------------------------------------------------------
  1136. void ScriptActions::updateBaseConstructionSpeed(const AsciiString& playerName, Int delayInSeconds)
  1137. {
  1138. Player* thePlayer = TheScriptEngine->getPlayerFromAsciiString(playerName);
  1139. if (thePlayer) {
  1140. thePlayer->setTeamDelaySeconds(delayInSeconds);
  1141. }
  1142. }
  1143. //-------------------------------------------------------------------------------------------------
  1144. /** updateNamedSetAttitude */
  1145. //-------------------------------------------------------------------------------------------------
  1146. void ScriptActions::updateNamedSetAttitude(const AsciiString& unitName, Int attitude)
  1147. {
  1148. Object *theSrcUnit = TheScriptEngine->getUnitNamed(unitName);
  1149. if (!theSrcUnit) {
  1150. return;
  1151. }
  1152. AIUpdateInterface *pInterface = theSrcUnit->getAIUpdateInterface();
  1153. if (!pInterface) {
  1154. return;
  1155. }
  1156. pInterface->setAttitude((AttitudeType) attitude);
  1157. }
  1158. //-------------------------------------------------------------------------------------------------
  1159. /** updateTeamSetAttitude */
  1160. //-------------------------------------------------------------------------------------------------
  1161. void ScriptActions::updateTeamSetAttitude(const AsciiString& teamName, Int attitude)
  1162. {
  1163. Team *theSrcTeam = TheScriptEngine->getTeamNamed(teamName);
  1164. if (!theSrcTeam) {
  1165. return;
  1166. }
  1167. AIGroup *pAIGroup = TheAI->createGroup();
  1168. if (!pAIGroup) {
  1169. return;
  1170. }
  1171. theSrcTeam->getTeamAsAIGroup(pAIGroup);
  1172. pAIGroup->setAttitude((AttitudeType) attitude);
  1173. }
  1174. //-------------------------------------------------------------------------------------------------
  1175. /** doNamedSetRepulsor */
  1176. //-------------------------------------------------------------------------------------------------
  1177. void ScriptActions::doNamedSetRepulsor(const AsciiString& unitName, Bool repulsor)
  1178. {
  1179. Object *theSrcUnit = TheScriptEngine->getUnitNamed(unitName);
  1180. if (!theSrcUnit) {
  1181. return;
  1182. }
  1183. theSrcUnit->setStatus( MAKE_OBJECT_STATUS_MASK( OBJECT_STATUS_REPULSOR ), repulsor);
  1184. }
  1185. //-------------------------------------------------------------------------------------------------
  1186. /** doTeamSetRepulsor */
  1187. //-------------------------------------------------------------------------------------------------
  1188. void ScriptActions::doTeamSetRepulsor(const AsciiString& teamName, Bool repulsor)
  1189. {
  1190. Team *theSrcTeam = TheScriptEngine->getTeamNamed(teamName);
  1191. if (!theSrcTeam) {
  1192. return;
  1193. }
  1194. if (theSrcTeam)
  1195. {
  1196. for (DLINK_ITERATOR<Object> iter = theSrcTeam->iterate_TeamMemberList(); !iter.done(); iter.advance())
  1197. {
  1198. Object *obj = iter.cur();
  1199. if (!obj)
  1200. {
  1201. continue;
  1202. }
  1203. obj->setStatus( MAKE_OBJECT_STATUS_MASK( OBJECT_STATUS_REPULSOR ), repulsor );
  1204. }
  1205. }
  1206. }
  1207. //-------------------------------------------------------------------------------------------------
  1208. /** doNamedAttackArea */
  1209. //-------------------------------------------------------------------------------------------------
  1210. void ScriptActions::doNamedAttackArea(const AsciiString& unitName, const AsciiString& areaName)
  1211. {
  1212. Object *theSrcUnit = TheScriptEngine->getUnitNamed( unitName );
  1213. if (!theSrcUnit) {
  1214. return;
  1215. }
  1216. PolygonTrigger *pTrig = TheScriptEngine->getQualifiedTriggerAreaByName(areaName);
  1217. if (!pTrig) {
  1218. return;
  1219. }
  1220. AIUpdateInterface* aiUpdate = theSrcUnit->getAIUpdateInterface();
  1221. if( !aiUpdate )
  1222. {
  1223. return;
  1224. }
  1225. theSrcUnit->leaveGroup();
  1226. aiUpdate->chooseLocomotorSet(LOCOMOTORSET_NORMAL);
  1227. aiUpdate->aiAttackArea(pTrig, CMD_FROM_SCRIPT);
  1228. }
  1229. //-------------------------------------------------------------------------------------------------
  1230. /** doNamedAttackTeam */
  1231. //-------------------------------------------------------------------------------------------------
  1232. void ScriptActions::doNamedAttackTeam(const AsciiString& unitName, const AsciiString& teamName)
  1233. {
  1234. Object *theSrcUnit = TheScriptEngine->getUnitNamed( unitName );
  1235. if (!theSrcUnit) {
  1236. return;
  1237. }
  1238. const Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  1239. if (!theTeam) {
  1240. return;
  1241. }
  1242. AIUpdateInterface* aiUpdate = theSrcUnit->getAIUpdateInterface();
  1243. if (!aiUpdate) {
  1244. return;
  1245. }
  1246. theSrcUnit->leaveGroup();
  1247. aiUpdate->chooseLocomotorSet(LOCOMOTORSET_NORMAL);
  1248. aiUpdate->aiAttackTeam(theTeam, NO_MAX_SHOTS_LIMIT, CMD_FROM_SCRIPT);
  1249. }
  1250. //-------------------------------------------------------------------------------------------------
  1251. /** doTeamAttackArea */
  1252. //-------------------------------------------------------------------------------------------------
  1253. void ScriptActions::doTeamAttackArea(const AsciiString& teamName, const AsciiString& areaName)
  1254. {
  1255. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  1256. // The team is the team based on the name, and the calling team (if any) and the team that
  1257. // triggered the condition. jba. :)
  1258. if (!theTeam) {
  1259. return;
  1260. }
  1261. AIGroup* theGroup = TheAI->createGroup();
  1262. if (!theGroup) {
  1263. return;
  1264. }
  1265. theTeam->getTeamAsAIGroup(theGroup);
  1266. PolygonTrigger *pTrig = TheScriptEngine->getQualifiedTriggerAreaByName(areaName);
  1267. if (!pTrig) {
  1268. return;
  1269. }
  1270. theGroup->groupAttackArea(pTrig, CMD_FROM_SCRIPT);
  1271. }
  1272. //-------------------------------------------------------------------------------------------------
  1273. /** doTeamAttackNamed */
  1274. //-------------------------------------------------------------------------------------------------
  1275. void ScriptActions::doTeamAttackNamed(const AsciiString& teamName, const AsciiString& unitName)
  1276. {
  1277. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  1278. // The team is the team based on the name, and the calling team (if any) and the team that
  1279. // triggered the condition. jba. :)
  1280. if (!theTeam) {
  1281. return;
  1282. }
  1283. Object *theVictim = TheScriptEngine->getUnitNamed( unitName );
  1284. if (!theVictim) {
  1285. return;
  1286. }
  1287. AIGroup* theGroup = TheAI->createGroup();
  1288. if (!theGroup) {
  1289. return;
  1290. }
  1291. theTeam->getTeamAsAIGroup(theGroup);
  1292. theGroup->groupAttackObject(theVictim, NO_MAX_SHOTS_LIMIT, CMD_FROM_SCRIPT);
  1293. }
  1294. //-------------------------------------------------------------------------------------------------
  1295. /** doLoadAllTransports */
  1296. //-------------------------------------------------------------------------------------------------
  1297. void ScriptActions::doLoadAllTransports(const AsciiString& teamName)
  1298. {
  1299. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  1300. // The team is the team based on the name, and the calling team (if any) and the team that
  1301. // triggered the condition. jba. :)
  1302. if (!theTeam) {
  1303. return;
  1304. }
  1305. EntriesVec vecOfUnits;
  1306. SpacesVec vecOfTransports;
  1307. for (DLINK_ITERATOR<Object> iter = theTeam->iterate_TeamMemberList(); !iter.done(); iter.advance())
  1308. {
  1309. Object *obj = iter.cur();
  1310. if (!obj) {
  1311. continue;
  1312. }
  1313. if( obj->isKindOf(KINDOF_TRANSPORT) )
  1314. {
  1315. ContainModuleInterface *contain = obj->getContain();
  1316. if( contain )
  1317. {
  1318. vecOfTransports.push_back(std::make_pair(obj->getID(), ((TransportContain*)obj->getContain())->getContainMax()));
  1319. }
  1320. else
  1321. {
  1322. DEBUG_CRASH( ("doLoadAllTransports script -- transport doesn't have a container!") );
  1323. }
  1324. }
  1325. else
  1326. {
  1327. vecOfUnits.push_back(std::make_pair(obj->getID(), obj->getTransportSlotCount()));
  1328. }
  1329. }
  1330. // we've now built the necessary stuff. Partition the units.
  1331. PartitionSolver partition(vecOfUnits, vecOfTransports, PREFER_FAST_SOLUTION);
  1332. partition.solve();
  1333. SolutionVec solution = partition.getSolution();
  1334. for (int i = 0; i < solution.size(); ++i) {
  1335. Object *unit = TheGameLogic->findObjectByID(solution[i].first);
  1336. Object *trans = TheGameLogic->findObjectByID(solution[i].second);
  1337. if (!unit || !trans) {
  1338. continue;
  1339. }
  1340. if( unit->getAIUpdateInterface() )
  1341. {
  1342. unit->getAIUpdateInterface()->chooseLocomotorSet(LOCOMOTORSET_NORMAL);
  1343. unit->getAIUpdateInterface()->aiEnter(trans, CMD_FROM_SCRIPT);
  1344. }
  1345. }
  1346. }
  1347. //-------------------------------------------------------------------------------------------------
  1348. /** doNamedEnterNamed */
  1349. //-------------------------------------------------------------------------------------------------
  1350. void ScriptActions::doNamedEnterNamed(const AsciiString& unitSrcName, const AsciiString& unitDestName)
  1351. {
  1352. Object *theSrcUnit = TheScriptEngine->getUnitNamed( unitSrcName );
  1353. if (!theSrcUnit) {
  1354. return;
  1355. }
  1356. Object *theTransport = TheScriptEngine->getUnitNamed( unitDestName );
  1357. if (!theTransport) {
  1358. return;
  1359. }
  1360. AIUpdateInterface* aiUpdate = theSrcUnit->getAIUpdateInterface();
  1361. if (!aiUpdate) {
  1362. return;
  1363. }
  1364. theSrcUnit->leaveGroup();
  1365. aiUpdate->chooseLocomotorSet(LOCOMOTORSET_NORMAL);
  1366. aiUpdate->aiEnter(theTransport, CMD_FROM_SCRIPT);
  1367. }
  1368. //-------------------------------------------------------------------------------------------------
  1369. /** doTeamEnterNamed */
  1370. //-------------------------------------------------------------------------------------------------
  1371. void ScriptActions::doTeamEnterNamed(const AsciiString& teamName, const AsciiString& unitDestName)
  1372. {
  1373. Team *theSrcTeam = TheScriptEngine->getTeamNamed( teamName );
  1374. if (!theSrcTeam) {
  1375. return;
  1376. }
  1377. Object *theTransport = TheScriptEngine->getUnitNamed( unitDestName );
  1378. if (!theTransport) {
  1379. return;
  1380. }
  1381. AIGroup* theGroup = TheAI->createGroup();
  1382. theSrcTeam->getTeamAsAIGroup(theGroup);
  1383. theGroup->groupEnter(theTransport, CMD_FROM_SCRIPT);
  1384. }
  1385. //-------------------------------------------------------------------------------------------------
  1386. /** doNamedExitAll */
  1387. //-------------------------------------------------------------------------------------------------
  1388. void ScriptActions::doNamedExitAll(const AsciiString& unitName)
  1389. {
  1390. Object *theTransport = TheScriptEngine->getUnitNamed( unitName );
  1391. if (!theTransport) {
  1392. return;
  1393. }
  1394. AIUpdateInterface* aiUpdate = theTransport->getAIUpdateInterface();
  1395. if (!aiUpdate) {
  1396. return;
  1397. }
  1398. theTransport->leaveGroup();
  1399. aiUpdate->chooseLocomotorSet(LOCOMOTORSET_NORMAL);
  1400. aiUpdate->aiEvacuate( FALSE, CMD_FROM_SCRIPT );
  1401. }
  1402. //-------------------------------------------------------------------------------------------------
  1403. /** doTeamExitAll */
  1404. //-------------------------------------------------------------------------------------------------
  1405. void ScriptActions::doTeamExitAll(const AsciiString& teamName)
  1406. {
  1407. Team *theTeamOfTransports = TheScriptEngine->getTeamNamed( teamName );
  1408. if (!theTeamOfTransports) {
  1409. return;
  1410. }
  1411. AIGroup* theGroup = TheAI->createGroup();
  1412. theTeamOfTransports->getTeamAsAIGroup(theGroup);
  1413. theGroup->groupEvacuate( CMD_FROM_SCRIPT );
  1414. }
  1415. //-------------------------------------------------------------------------------------------------
  1416. /** doNamedSetGarrisonEvacDisposition */
  1417. //-------------------------------------------------------------------------------------------------
  1418. void ScriptActions::doNamedSetGarrisonEvacDisposition(const AsciiString& unitName, UnsignedInt disp )
  1419. {
  1420. Object *theUnit = TheScriptEngine->getUnitNamed( unitName );
  1421. if (!theUnit) {
  1422. return;
  1423. }
  1424. ContainModuleInterface *contain = theUnit->getContain();
  1425. if( contain )
  1426. contain->setEvacDisposition( (EvacDisposition)disp );
  1427. // should be safe to cast any-old int to this enum,
  1428. // since only 1(EVAC_TO_LEFT) and 2(EVAC_TO_RIGHT) differ from default case
  1429. }
  1430. //-------------------------------------------------------------------------------------------------
  1431. /** doNamedFollowWaypoints */
  1432. //-------------------------------------------------------------------------------------------------
  1433. void ScriptActions::doNamedFollowWaypoints(const AsciiString& unitName, const AsciiString& waypointPathLabel)
  1434. {
  1435. Object *theUnit = TheScriptEngine->getUnitNamed( unitName );
  1436. if (!theUnit) {
  1437. return;
  1438. }
  1439. Coord3D pos = *theUnit->getPosition();
  1440. AIUpdateInterface* aiUpdate = theUnit->getAIUpdateInterface();
  1441. if (!aiUpdate) {
  1442. return;
  1443. }
  1444. Waypoint *way = TheTerrainLogic->getClosestWaypointOnPath( &pos, waypointPathLabel );
  1445. if (!way) {
  1446. return;
  1447. }
  1448. DEBUG_ASSERTLOG(TheTerrainLogic->isPurposeOfPath(way, waypointPathLabel), ("***Wrong waypoint purpose. Make jba fix this.\n"));
  1449. theUnit->leaveGroup();
  1450. aiUpdate->chooseLocomotorSet(LOCOMOTORSET_NORMAL);
  1451. aiUpdate->aiFollowWaypointPath(way, CMD_FROM_SCRIPT);
  1452. }
  1453. //-------------------------------------------------------------------------------------------------
  1454. /** doNamedFollowWaypointsExact */
  1455. //-------------------------------------------------------------------------------------------------
  1456. void ScriptActions::doNamedFollowWaypointsExact(const AsciiString& unitName, const AsciiString& waypointPathLabel)
  1457. {
  1458. Object *theUnit = TheScriptEngine->getUnitNamed( unitName );
  1459. if (!theUnit) {
  1460. return;
  1461. }
  1462. Coord3D pos = *theUnit->getPosition();
  1463. AIUpdateInterface* aiUpdate = theUnit->getAIUpdateInterface();
  1464. if (!aiUpdate) {
  1465. return;
  1466. }
  1467. Waypoint *way = TheTerrainLogic->getClosestWaypointOnPath( &pos, waypointPathLabel );
  1468. if (!way) {
  1469. return;
  1470. }
  1471. DEBUG_ASSERTLOG(TheTerrainLogic->isPurposeOfPath(way, waypointPathLabel), ("***Wrong waypoint purpose. Make jba fix this.\n"));
  1472. theUnit->leaveGroup();
  1473. aiUpdate->chooseLocomotorSet(LOCOMOTORSET_NORMAL);
  1474. aiUpdate->aiFollowWaypointPathExact(way, CMD_FROM_SCRIPT);
  1475. }
  1476. //-------------------------------------------------------------------------------------------------
  1477. /** doTeamFollowSkirmishApproachPath */
  1478. //-------------------------------------------------------------------------------------------------
  1479. void ScriptActions::doTeamFollowSkirmishApproachPath(const AsciiString& teamName, const AsciiString& waypointPathLabel, Bool asTeam)
  1480. {
  1481. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  1482. if (!theTeam) {
  1483. return;
  1484. }
  1485. AIGroup* theGroup = TheAI->createGroup();
  1486. if (!theGroup) {
  1487. return;
  1488. }
  1489. theTeam->getTeamAsAIGroup(theGroup);
  1490. Int count = 0;
  1491. Coord3D pos;
  1492. pos.x=pos.y=pos.z=0;
  1493. Object *firstUnit=NULL;
  1494. // Get the center point for the team
  1495. for (DLINK_ITERATOR<Object> iter = theTeam->iterate_TeamMemberList(); !iter.done(); iter.advance())
  1496. {
  1497. Object *obj = iter.cur();
  1498. Coord3D objPos = *obj->getPosition();
  1499. pos.x += objPos.x;
  1500. pos.y += objPos.y;
  1501. pos.z += objPos.z; // Not actually used by getClosestWaypointOnPath, but hey, might as well be correct.
  1502. count++;
  1503. if (firstUnit==NULL) {
  1504. firstUnit = obj;
  1505. }
  1506. }
  1507. if (count==0) return; // empty team.
  1508. pos.x /= count;
  1509. pos.y /= count;
  1510. pos.z /= count;
  1511. Player *enemyPlayer = TheScriptEngine->getSkirmishEnemyPlayer();
  1512. if (enemyPlayer==NULL) return;
  1513. Int mpNdx = enemyPlayer->getMpStartIndex()+1;
  1514. AsciiString pathLabel;
  1515. pathLabel.format("%s%d", waypointPathLabel.str(), mpNdx);
  1516. Waypoint *way = TheTerrainLogic->getClosestWaypointOnPath( &pos, pathLabel );
  1517. if (!way) {
  1518. return;
  1519. }
  1520. Player *aiPlayer = TheScriptEngine->getCurrentPlayer();
  1521. if (aiPlayer && firstUnit) {
  1522. aiPlayer->checkBridges(firstUnit, way);
  1523. }
  1524. DEBUG_ASSERTLOG(TheTerrainLogic->isPurposeOfPath(way, pathLabel), ("***Wrong waypoint purpose. Make jba fix this.\n"));
  1525. if (asTeam)
  1526. {
  1527. theGroup->groupFollowWaypointPathAsTeam(way, CMD_FROM_SCRIPT);
  1528. } else {
  1529. theGroup->groupFollowWaypointPath(way, CMD_FROM_SCRIPT);
  1530. }
  1531. }
  1532. //-------------------------------------------------------------------------------------------------
  1533. /** doTeamFollowSkirmishApproachPath */
  1534. //-------------------------------------------------------------------------------------------------
  1535. void ScriptActions::doTeamMoveToSkirmishApproachPath(const AsciiString& teamName, const AsciiString& waypointPathLabel)
  1536. {
  1537. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  1538. if (!theTeam) {
  1539. return;
  1540. }
  1541. AIGroup* theGroup = TheAI->createGroup();
  1542. if (!theGroup) {
  1543. return;
  1544. }
  1545. theTeam->getTeamAsAIGroup(theGroup);
  1546. Int count = 0;
  1547. Coord3D pos;
  1548. pos.x=pos.y=pos.z=0;
  1549. // Get the center point for the team
  1550. for (DLINK_ITERATOR<Object> iter = theTeam->iterate_TeamMemberList(); !iter.done(); iter.advance())
  1551. {
  1552. Object *obj = iter.cur();
  1553. Coord3D objPos = *obj->getPosition();
  1554. pos.x += objPos.x;
  1555. pos.y += objPos.y;
  1556. pos.z += objPos.z; // Not actually used by getClosestWaypointOnPath, but hey, might as well be correct.
  1557. count++;
  1558. }
  1559. if (count==0) return; // empty team.
  1560. pos.x /= count;
  1561. pos.y /= count;
  1562. pos.z /= count;
  1563. Player *enemyPlayer = TheScriptEngine->getSkirmishEnemyPlayer();
  1564. if (enemyPlayer==NULL) return;
  1565. Int mpNdx = enemyPlayer->getMpStartIndex()+1;
  1566. AsciiString pathLabel;
  1567. pathLabel.format("%s%d", waypointPathLabel.str(), mpNdx);
  1568. Waypoint *way = TheTerrainLogic->getClosestWaypointOnPath( &pos, pathLabel );
  1569. if (!way) {
  1570. return;
  1571. }
  1572. DEBUG_ASSERTLOG(TheTerrainLogic->isPurposeOfPath(way, pathLabel), ("***Wrong waypoint purpose. Make jba fix this.\n"));
  1573. theGroup->groupMoveToPosition(way->getLocation(), false, CMD_FROM_SCRIPT);
  1574. }
  1575. //-------------------------------------------------------------------------------------------------
  1576. /** doTeamFollowWaypoints */
  1577. //-------------------------------------------------------------------------------------------------
  1578. void ScriptActions::doTeamFollowWaypoints(const AsciiString& teamName, const AsciiString& waypointPathLabel, Bool asTeam)
  1579. {
  1580. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  1581. if (!theTeam) {
  1582. return;
  1583. }
  1584. AIGroup* theGroup = TheAI->createGroup();
  1585. if (!theGroup) {
  1586. return;
  1587. }
  1588. theTeam->getTeamAsAIGroup(theGroup);
  1589. Int count = 0;
  1590. Coord3D pos;
  1591. pos.x=pos.y=pos.z=0;
  1592. // Get the center point for the team
  1593. for (DLINK_ITERATOR<Object> iter = theTeam->iterate_TeamMemberList(); !iter.done(); iter.advance())
  1594. {
  1595. Object *obj = iter.cur();
  1596. Coord3D objPos = *obj->getPosition();
  1597. pos.x += objPos.x;
  1598. pos.y += objPos.y;
  1599. pos.z += objPos.z; // Not actually used by getClosestWaypointOnPath, but hey, might as well be correct.
  1600. count++;
  1601. }
  1602. if (count==0) return; // empty team.
  1603. pos.x /= count;
  1604. pos.y /= count;
  1605. pos.z /= count;
  1606. Waypoint *way = TheTerrainLogic->getClosestWaypointOnPath( &pos, waypointPathLabel );
  1607. if (!way) {
  1608. return;
  1609. }
  1610. DEBUG_ASSERTLOG(TheTerrainLogic->isPurposeOfPath(way, waypointPathLabel), ("***Wrong waypoint purpose. Make jba fix this.\n"));
  1611. if (asTeam)
  1612. {
  1613. theGroup->groupFollowWaypointPathAsTeam(way, CMD_FROM_SCRIPT);
  1614. } else {
  1615. theGroup->groupFollowWaypointPath(way, CMD_FROM_SCRIPT);
  1616. }
  1617. }
  1618. //-------------------------------------------------------------------------------------------------
  1619. /** doTeamFollowWaypointsExact */
  1620. //-------------------------------------------------------------------------------------------------
  1621. void ScriptActions::doTeamFollowWaypointsExact(const AsciiString& teamName, const AsciiString& waypointPathLabel, Bool asTeam)
  1622. {
  1623. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  1624. if (!theTeam) {
  1625. return;
  1626. }
  1627. AIGroup* theGroup = TheAI->createGroup();
  1628. if (!theGroup) {
  1629. return;
  1630. }
  1631. theTeam->getTeamAsAIGroup(theGroup);
  1632. Int count = 0;
  1633. Coord3D pos;
  1634. pos.x=pos.y=pos.z=0;
  1635. // Get the center point for the team
  1636. for (DLINK_ITERATOR<Object> iter = theTeam->iterate_TeamMemberList(); !iter.done(); iter.advance())
  1637. {
  1638. Object *obj = iter.cur();
  1639. Coord3D objPos = *obj->getPosition();
  1640. pos.x += objPos.x;
  1641. pos.y += objPos.y;
  1642. pos.z += objPos.z; // Not actually used by getClosestWaypointOnPath, but hey, might as well be correct.
  1643. count++;
  1644. }
  1645. if (count==0) return; // empty team.
  1646. pos.x /= count;
  1647. pos.y /= count;
  1648. pos.z /= count;
  1649. Waypoint *way = TheTerrainLogic->getClosestWaypointOnPath( &pos, waypointPathLabel );
  1650. if (!way) {
  1651. return;
  1652. }
  1653. DEBUG_ASSERTLOG(TheTerrainLogic->isPurposeOfPath(way, waypointPathLabel), ("***Wrong waypoint purpose. Make jba fix this.\n"));
  1654. if (asTeam)
  1655. {
  1656. theGroup->groupFollowWaypointPathAsTeamExact(way, CMD_FROM_SCRIPT);
  1657. } else {
  1658. theGroup->groupFollowWaypointPathExact(way, CMD_FROM_SCRIPT);
  1659. }
  1660. }
  1661. //-------------------------------------------------------------------------------------------------
  1662. /** doNamedGuard */
  1663. //-------------------------------------------------------------------------------------------------
  1664. void ScriptActions::doNamedGuard(const AsciiString& unitName)
  1665. {
  1666. Object *theUnit = TheScriptEngine->getUnitNamed( unitName );
  1667. if (!theUnit) {
  1668. return;
  1669. }
  1670. AIUpdateInterface* aiUpdate = theUnit->getAIUpdateInterface();
  1671. if (!aiUpdate) {
  1672. return;
  1673. }
  1674. theUnit->leaveGroup();
  1675. Coord3D position = *theUnit->getPosition();
  1676. aiUpdate->chooseLocomotorSet(LOCOMOTORSET_NORMAL);
  1677. aiUpdate->aiGuardPosition(&position, GUARDMODE_NORMAL, CMD_FROM_SCRIPT);
  1678. }
  1679. //-------------------------------------------------------------------------------------------------
  1680. /** doTeamGuard */
  1681. //-------------------------------------------------------------------------------------------------
  1682. void ScriptActions::doTeamGuard(const AsciiString& teamName)
  1683. {
  1684. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  1685. if (!theTeam) {
  1686. return;
  1687. }
  1688. // Have all the members of the team guard at their current pos.
  1689. for (DLINK_ITERATOR<Object> iter = theTeam->iterate_TeamMemberList(); !iter.done(); iter.advance())
  1690. {
  1691. Object *obj = iter.cur();
  1692. AIUpdateInterface *ai = obj->getAIUpdateInterface();
  1693. if (!ai) {
  1694. continue;
  1695. }
  1696. Coord3D pos = *obj->getPosition();
  1697. ai->aiGuardPosition(&pos, GUARDMODE_NORMAL, CMD_FROM_SCRIPT);
  1698. }
  1699. }
  1700. //-------------------------------------------------------------------------------------------------
  1701. /** doTeamGuardPosition */
  1702. //-------------------------------------------------------------------------------------------------
  1703. void ScriptActions::doTeamGuardPosition(const AsciiString& teamName, const AsciiString& waypointName)
  1704. {
  1705. Waypoint *way = TheTerrainLogic->getWaypointByName(waypointName);
  1706. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  1707. if (!theTeam || !way) {
  1708. return;
  1709. }
  1710. AIGroup* theGroup = TheAI->createGroup();
  1711. if (!theGroup) {
  1712. return;
  1713. }
  1714. theTeam->getTeamAsAIGroup(theGroup);
  1715. Coord3D position = *way->getLocation();
  1716. theGroup->groupGuardPosition( &position, GUARDMODE_NORMAL, CMD_FROM_SCRIPT );
  1717. }
  1718. //-------------------------------------------------------------------------------------------------
  1719. /** doTeamGuardObject */
  1720. //-------------------------------------------------------------------------------------------------
  1721. void ScriptActions::doTeamGuardObject(const AsciiString& teamName, const AsciiString& unitName)
  1722. {
  1723. Object *theUnit = TheScriptEngine->getUnitNamed( unitName );
  1724. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  1725. if (!theTeam || !theUnit) {
  1726. return;
  1727. }
  1728. AIGroup* theGroup = TheAI->createGroup();
  1729. if (!theGroup) {
  1730. return;
  1731. }
  1732. theTeam->getTeamAsAIGroup(theGroup);
  1733. theGroup->groupGuardObject( theUnit, GUARDMODE_NORMAL, CMD_FROM_SCRIPT );
  1734. }
  1735. //-------------------------------------------------------------------------------------------------
  1736. /** doTeamGuardArea */
  1737. //-------------------------------------------------------------------------------------------------
  1738. void ScriptActions::doTeamGuardArea(const AsciiString& teamName, const AsciiString& areaName)
  1739. {
  1740. PolygonTrigger *pTrig = TheScriptEngine->getQualifiedTriggerAreaByName(areaName);
  1741. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  1742. if (!theTeam || !pTrig) {
  1743. return;
  1744. }
  1745. AIGroup* theGroup = TheAI->createGroup();
  1746. if (!theGroup) {
  1747. return;
  1748. }
  1749. theTeam->getTeamAsAIGroup(theGroup);
  1750. theGroup->groupGuardArea( pTrig, GUARDMODE_NORMAL, CMD_FROM_SCRIPT );
  1751. }
  1752. //-------------------------------------------------------------------------------------------------
  1753. /** doNamedHunt */
  1754. //-------------------------------------------------------------------------------------------------
  1755. void ScriptActions::doNamedHunt(const AsciiString& unitName)
  1756. {
  1757. Object *theUnit = TheScriptEngine->getUnitNamed( unitName );
  1758. if (!theUnit) {
  1759. return;
  1760. }
  1761. AIUpdateInterface* aiUpdate = theUnit->getAIUpdateInterface();
  1762. if (!aiUpdate) {
  1763. return;
  1764. }
  1765. aiUpdate->chooseLocomotorSet(LOCOMOTORSET_NORMAL);
  1766. aiUpdate->aiHunt( CMD_FROM_SCRIPT );
  1767. }
  1768. //-------------------------------------------------------------------------------------------------
  1769. /** doTeamHunt */
  1770. //-------------------------------------------------------------------------------------------------
  1771. void ScriptActions::doTeamHunt(const AsciiString& teamName)
  1772. {
  1773. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  1774. if (!theTeam) {
  1775. return;
  1776. }
  1777. AIGroup* theGroup = TheAI->createGroup();
  1778. if (!theGroup) {
  1779. return;
  1780. }
  1781. theTeam->getTeamAsAIGroup(theGroup);
  1782. theGroup->groupHunt( CMD_FROM_SCRIPT );
  1783. }
  1784. //-------------------------------------------------------------------------------------------------
  1785. /** doTeamHunt */
  1786. //-------------------------------------------------------------------------------------------------
  1787. void ScriptActions::doTeamHuntWithCommandButton(const AsciiString& teamName, const AsciiString& ability)
  1788. {
  1789. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  1790. if (!theTeam) {
  1791. return;
  1792. }
  1793. const CommandButton *commandButton = TheControlBar->findCommandButton( ability );
  1794. if( !commandButton )
  1795. {
  1796. return;
  1797. }
  1798. switch( commandButton->getCommandType() )
  1799. {
  1800. case GUI_COMMAND_SPECIAL_POWER:
  1801. if( commandButton->getSpecialPowerTemplate() )
  1802. {
  1803. if (BitTest( commandButton->getOptions(), COMMAND_OPTION_NEED_OBJECT_TARGET ))
  1804. {
  1805. // OK, we can hunt with a power that targets an object.
  1806. break;
  1807. }
  1808. AsciiString msg = "ERROR-Team hunt with command button - cannot hunt with ability ";
  1809. msg.concat(ability);
  1810. TheScriptEngine->AppendDebugMessage(msg, false);
  1811. return;
  1812. }
  1813. return;
  1814. case GUI_COMMAND_SWITCH_WEAPON:
  1815. case GUI_COMMAND_FIRE_WEAPON:
  1816. {
  1817. // ok, we can hunt with a weapon.
  1818. break;
  1819. }
  1820. case GUICOMMANDMODE_HIJACK_VEHICLE:
  1821. case GUICOMMANDMODE_CONVERT_TO_CARBOMB:
  1822. case GUICOMMANDMODE_SABOTAGE_BUILDING:
  1823. //Various enter type hunts.
  1824. break;
  1825. case GUI_COMMAND_OBJECT_UPGRADE:
  1826. case GUI_COMMAND_PLAYER_UPGRADE:
  1827. case GUI_COMMAND_DOZER_CONSTRUCT:
  1828. case GUI_COMMAND_DOZER_CONSTRUCT_CANCEL:
  1829. case GUI_COMMAND_UNIT_BUILD:
  1830. case GUI_COMMAND_CANCEL_UNIT_BUILD:
  1831. case GUI_COMMAND_CANCEL_UPGRADE:
  1832. case GUI_COMMAND_ATTACK_MOVE:
  1833. case GUI_COMMAND_GUARD:
  1834. case GUI_COMMAND_GUARD_WITHOUT_PURSUIT:
  1835. case GUI_COMMAND_GUARD_FLYING_UNITS_ONLY:
  1836. case GUI_COMMAND_WAYPOINTS:
  1837. case GUI_COMMAND_EXIT_CONTAINER:
  1838. case GUI_COMMAND_EVACUATE:
  1839. case GUI_COMMAND_EXECUTE_RAILED_TRANSPORT:
  1840. case GUI_COMMAND_BEACON_DELETE:
  1841. case GUI_COMMAND_SET_RALLY_POINT:
  1842. case GUI_COMMAND_SELL:
  1843. case GUI_COMMAND_HACK_INTERNET:
  1844. case GUI_COMMAND_TOGGLE_OVERCHARGE:
  1845. #ifdef ALLOW_SURRENDER
  1846. case GUI_COMMAND_POW_RETURN_TO_PRISON:
  1847. #endif
  1848. #ifdef ALLOW_SURRENDER
  1849. case GUICOMMANDMODE_PICK_UP_PRISONER:
  1850. #endif
  1851. default:
  1852. {
  1853. AsciiString msg = "ERROR-Team hunt with command button - cannot hunt with ability ";
  1854. msg.concat(ability);
  1855. TheScriptEngine->AppendDebugMessage(msg, false);
  1856. return;
  1857. }
  1858. break;
  1859. }
  1860. // Have all the members of the team do the command button.
  1861. for (DLINK_ITERATOR<Object> iter = theTeam->iterate_TeamMemberList(); !iter.done(); iter.advance())
  1862. {
  1863. Object *obj = iter.cur();
  1864. AIUpdateInterface *ai = obj->getAIUpdateInterface();
  1865. if (!ai) {
  1866. continue;
  1867. }
  1868. Bool foundCommand = false;
  1869. const CommandSet *commandSet = TheControlBar->findCommandSet( obj->getCommandSetString( ) );
  1870. if( commandSet )
  1871. {
  1872. for( int i = 0; i < MAX_COMMANDS_PER_SET; i++ )
  1873. {
  1874. const CommandButton *aCommandButton = commandSet->getCommandButton(i);
  1875. if( commandButton == aCommandButton )
  1876. {
  1877. //We found the matching command button so now order the unit to do what the button wants.
  1878. foundCommand = true;
  1879. break;
  1880. }
  1881. }
  1882. }
  1883. if (!foundCommand) {
  1884. AsciiString msg = "Error - Team hunt with command button - unit type '";
  1885. msg.concat(obj->getTemplate()->getName().str());
  1886. msg.concat("' is not valid for ability ");
  1887. msg.concat(ability);
  1888. TheScriptEngine->AppendDebugMessage(msg, false);
  1889. continue;
  1890. }
  1891. switch( commandButton->getCommandType() )
  1892. {
  1893. case GUI_COMMAND_FIRE_WEAPON:
  1894. case GUI_COMMAND_SWITCH_WEAPON:
  1895. case GUI_COMMAND_SPECIAL_POWER:
  1896. case GUICOMMANDMODE_HIJACK_VEHICLE:
  1897. case GUICOMMANDMODE_CONVERT_TO_CARBOMB:
  1898. case GUICOMMANDMODE_SABOTAGE_BUILDING:
  1899. {
  1900. static NameKeyType key_CommandButtonHuntUpdate = NAMEKEY("CommandButtonHuntUpdate");
  1901. CommandButtonHuntUpdate* huntUpdate = (CommandButtonHuntUpdate*)obj->findUpdateModule(key_CommandButtonHuntUpdate);
  1902. if( huntUpdate )
  1903. {
  1904. huntUpdate->setCommandButton(ability);
  1905. } else {
  1906. AsciiString msg = "Error - Team hunt with command button - unit type '";
  1907. msg.concat(obj->getTemplate()->getName().str());
  1908. msg.concat("' requires CommandButtonHuntUpdate in .ini definition to hunt with ");
  1909. msg.concat(ability);
  1910. TheScriptEngine->AppendDebugMessage(msg, false);
  1911. } // end if
  1912. }
  1913. break;
  1914. }
  1915. }
  1916. }
  1917. //-------------------------------------------------------------------------------------------------
  1918. /** doTeamHunt */
  1919. //-------------------------------------------------------------------------------------------------
  1920. void ScriptActions::doPlayerHunt(const AsciiString& playerName)
  1921. {
  1922. Player* pPlayer = TheScriptEngine->getPlayerFromAsciiString(playerName);
  1923. if (!pPlayer) {
  1924. return;
  1925. }
  1926. pPlayer->setUnitsShouldHunt(true, CMD_FROM_SCRIPT);
  1927. }
  1928. //-------------------------------------------------------------------------------------------------
  1929. /** doPlayerSellEverything */
  1930. //-------------------------------------------------------------------------------------------------
  1931. void ScriptActions::doPlayerSellEverything(const AsciiString& playerName)
  1932. {
  1933. Player* pPlayer = TheScriptEngine->getPlayerFromAsciiString(playerName);
  1934. if (!pPlayer) {
  1935. return;
  1936. }
  1937. pPlayer->sellEverythingUnderTheSun();
  1938. }
  1939. //-------------------------------------------------------------------------------------------------
  1940. /** doPlayerDisableBaseConstruction */
  1941. //-------------------------------------------------------------------------------------------------
  1942. void ScriptActions::doPlayerDisableBaseConstruction(const AsciiString& playerName)
  1943. {
  1944. Player* pPlayer = TheScriptEngine->getPlayerFromAsciiString(playerName);
  1945. if (!pPlayer) {
  1946. return;
  1947. }
  1948. pPlayer->setCanBuildBase(false);
  1949. }
  1950. //-------------------------------------------------------------------------------------------------
  1951. /** doPlayerDisableFactories */
  1952. //-------------------------------------------------------------------------------------------------
  1953. void ScriptActions::doPlayerDisableFactories(const AsciiString& playerName, const AsciiString& objectName)
  1954. {
  1955. Player* pPlayer = TheScriptEngine->getPlayerFromAsciiString(playerName);
  1956. if (!pPlayer) {
  1957. return;
  1958. }
  1959. pPlayer->setObjectsEnabled(objectName, false);
  1960. }
  1961. //-------------------------------------------------------------------------------------------------
  1962. /** doPlayerDisableUnitConstruction */
  1963. //-------------------------------------------------------------------------------------------------
  1964. void ScriptActions::doPlayerDisableUnitConstruction(const AsciiString& playerName)
  1965. {
  1966. Player* pPlayer = TheScriptEngine->getPlayerFromAsciiString(playerName);
  1967. if (!pPlayer) {
  1968. return;
  1969. }
  1970. pPlayer->setCanBuildUnits(false);
  1971. }
  1972. //-------------------------------------------------------------------------------------------------
  1973. /** doPlayerEnableBaseConstruction */
  1974. //-------------------------------------------------------------------------------------------------
  1975. void ScriptActions::doPlayerEnableBaseConstruction(const AsciiString& playerName)
  1976. {
  1977. Player* pPlayer = TheScriptEngine->getPlayerFromAsciiString(playerName);
  1978. if (!pPlayer) {
  1979. return;
  1980. }
  1981. pPlayer->setCanBuildBase(true);
  1982. }
  1983. //-------------------------------------------------------------------------------------------------
  1984. /** doPlayerEnableFactories */
  1985. //-------------------------------------------------------------------------------------------------
  1986. void ScriptActions::doPlayerEnableFactories(const AsciiString& playerName, const AsciiString& objectName)
  1987. {
  1988. Player* pPlayer = TheScriptEngine->getPlayerFromAsciiString(playerName);
  1989. if (!pPlayer) {
  1990. return;
  1991. }
  1992. pPlayer->setObjectsEnabled(objectName, true);
  1993. }
  1994. //-------------------------------------------------------------------------------------------------
  1995. /** doPlayerRepairStructure */
  1996. //-------------------------------------------------------------------------------------------------
  1997. void ScriptActions::doPlayerRepairStructure(const AsciiString& playerName, const AsciiString& structureName)
  1998. {
  1999. Player* pPlayer = TheScriptEngine->getPlayerFromAsciiString(playerName);
  2000. if (!pPlayer) {
  2001. return;
  2002. }
  2003. Object *pStructure = TheScriptEngine->getUnitNamed(structureName);
  2004. if (!pStructure) {
  2005. return;
  2006. }
  2007. pPlayer->repairStructure(pStructure->getID());
  2008. }
  2009. //-------------------------------------------------------------------------------------------------
  2010. /** doPlayerEnableUnitConstruction */
  2011. //-------------------------------------------------------------------------------------------------
  2012. void ScriptActions::doPlayerEnableUnitConstruction(const AsciiString& playerName)
  2013. {
  2014. Player* pPlayer = TheScriptEngine->getPlayerFromAsciiString(playerName);
  2015. if (!pPlayer) {
  2016. return;
  2017. }
  2018. pPlayer->setCanBuildUnits(true);
  2019. }
  2020. //-------------------------------------------------------------------------------------------------
  2021. /** doCameraMoveHome */
  2022. //-------------------------------------------------------------------------------------------------
  2023. void ScriptActions::doCameraMoveHome(void)
  2024. {
  2025. }
  2026. //-------------------------------------------------------------------------------------------------
  2027. /** doBuildTeam */
  2028. //-------------------------------------------------------------------------------------------------
  2029. void ScriptActions::doBuildTeam(const AsciiString& teamName)
  2030. {
  2031. TeamPrototype *theTeamProto = TheTeamFactory->findTeamPrototype( teamName );
  2032. if (theTeamProto) {
  2033. Player *player = theTeamProto->getControllingPlayer();
  2034. if (player) {
  2035. player->buildSpecificTeam(theTeamProto);
  2036. }
  2037. }
  2038. }
  2039. //-------------------------------------------------------------------------------------------------
  2040. /** doRecruitTeam */
  2041. //-------------------------------------------------------------------------------------------------
  2042. void ScriptActions::doRecruitTeam(const AsciiString& teamName, Real recruitRadius)
  2043. {
  2044. TeamPrototype *theTeamProto = TheTeamFactory->findTeamPrototype( teamName );
  2045. if (theTeamProto) {
  2046. Player *player = theTeamProto->getControllingPlayer();
  2047. if (player) {
  2048. player->recruitSpecificTeam(theTeamProto, recruitRadius);
  2049. }
  2050. }
  2051. }
  2052. //-------------------------------------------------------------------------------------------------
  2053. /** doNamedDamage */
  2054. //-------------------------------------------------------------------------------------------------
  2055. void ScriptActions::doNamedDamage(const AsciiString& unitName, Int damageAmt)
  2056. {
  2057. Object *pUnit = TheScriptEngine->getUnitNamed(unitName);
  2058. if (!pUnit) {
  2059. return;
  2060. }
  2061. DamageInfo damageInfo;
  2062. damageInfo.in.m_damageType = DAMAGE_UNRESISTABLE;
  2063. damageInfo.in.m_deathType = DEATH_NORMAL;
  2064. damageInfo.in.m_sourceID = INVALID_ID;
  2065. damageInfo.in.m_amount = damageAmt;
  2066. pUnit->attemptDamage( &damageInfo );
  2067. }
  2068. //-------------------------------------------------------------------------------------------------
  2069. /** doNamedDelete */
  2070. //-------------------------------------------------------------------------------------------------
  2071. void ScriptActions::doNamedDelete(const AsciiString& unitName)
  2072. {
  2073. Object *theUnit = TheScriptEngine->getUnitNamed( unitName );
  2074. if (!theUnit) {
  2075. return;
  2076. }
  2077. TheGameLogic->destroyObject(theUnit);
  2078. }
  2079. //-------------------------------------------------------------------------------------------------
  2080. /** doTeamDelete */
  2081. //-------------------------------------------------------------------------------------------------
  2082. void ScriptActions::doTeamDelete(const AsciiString& teamName, Bool ignoreDead)
  2083. {
  2084. Team *team = TheScriptEngine->getTeamNamed(teamName);
  2085. if (!team) {
  2086. return;
  2087. }
  2088. team->deleteTeam(ignoreDead);
  2089. }
  2090. //-------------------------------------------------------------------------------------------------
  2091. /** doTeamWander */
  2092. //-------------------------------------------------------------------------------------------------
  2093. void ScriptActions::doTeamWander(const AsciiString& teamName, const AsciiString& waypointPathLabel)
  2094. {
  2095. Team *team = TheScriptEngine->getTeamNamed(teamName);
  2096. if (!team) {
  2097. return;
  2098. }
  2099. // Have all the members of the team wander.
  2100. for (DLINK_ITERATOR<Object> iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance())
  2101. {
  2102. Object *obj = iter.cur();
  2103. AIUpdateInterface *ai = obj->getAIUpdateInterface();
  2104. if (!ai) {
  2105. continue;
  2106. }
  2107. Coord3D pos = *obj->getPosition();
  2108. Waypoint *way = TheTerrainLogic->getClosestWaypointOnPath( &pos, waypointPathLabel );
  2109. if (!way) {
  2110. return;
  2111. }
  2112. ai->chooseLocomotorSet(LOCOMOTORSET_WANDER);
  2113. ai->aiWander(way, CMD_FROM_SCRIPT);
  2114. }
  2115. }
  2116. //-------------------------------------------------------------------------------------------------
  2117. /** doTeamIncreasePriority */
  2118. //-------------------------------------------------------------------------------------------------
  2119. void ScriptActions::doTeamIncreasePriority(const AsciiString& teamName)
  2120. {
  2121. Team *team = TheScriptEngine->getTeamNamed(teamName);
  2122. if (!team) {
  2123. return;
  2124. }
  2125. const TeamPrototype *theTeamProto = team->getPrototype();
  2126. if (!theTeamProto) {
  2127. return;
  2128. }
  2129. theTeamProto->increaseAIPriorityForSuccess();
  2130. AsciiString msg;
  2131. msg.format("Team '%s' priority increased to %d for success.", teamName.str(), theTeamProto->getTemplateInfo()->m_productionPriority);
  2132. TheScriptEngine->AppendDebugMessage(msg, false);
  2133. }
  2134. //-------------------------------------------------------------------------------------------------
  2135. /** doTeamDecreasePriority */
  2136. //-------------------------------------------------------------------------------------------------
  2137. void ScriptActions::doTeamDecreasePriority(const AsciiString& teamName)
  2138. {
  2139. Team *team = TheScriptEngine->getTeamNamed(teamName);
  2140. if (!team) {
  2141. return;
  2142. }
  2143. const TeamPrototype *theTeamProto = team->getPrototype();
  2144. if (!theTeamProto) {
  2145. return;
  2146. }
  2147. theTeamProto->decreaseAIPriorityForFailure();
  2148. AsciiString msg;
  2149. msg.format("Team '%s' priority decreased to %d for failure.", teamName.str(), theTeamProto->getTemplateInfo()->m_productionPriority);
  2150. TheScriptEngine->AppendDebugMessage(msg, false);
  2151. }
  2152. //-------------------------------------------------------------------------------------------------
  2153. /** doTeamWanderInPlace */
  2154. //-------------------------------------------------------------------------------------------------
  2155. void ScriptActions::doTeamWanderInPlace(const AsciiString& teamName)
  2156. {
  2157. Team *team = TheScriptEngine->getTeamNamed(teamName);
  2158. if (!team) {
  2159. return;
  2160. }
  2161. // Have all the members of the team wander.
  2162. for (DLINK_ITERATOR<Object> iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance())
  2163. {
  2164. Object *obj = iter.cur();
  2165. AIUpdateInterface *ai = obj->getAIUpdateInterface();
  2166. if (!ai) {
  2167. continue;
  2168. }
  2169. ai->chooseLocomotorSet(LOCOMOTORSET_WANDER);
  2170. ai->aiWanderInPlace(CMD_FROM_SCRIPT);
  2171. }
  2172. }
  2173. //-------------------------------------------------------------------------------------------------
  2174. /** doTeamPanic */
  2175. //-------------------------------------------------------------------------------------------------
  2176. void ScriptActions::doTeamPanic(const AsciiString& teamName, const AsciiString& waypointPathLabel)
  2177. {
  2178. Team *team = TheScriptEngine->getTeamNamed(teamName);
  2179. if (!team) {
  2180. return;
  2181. }
  2182. // Get the center point for the team
  2183. for (DLINK_ITERATOR<Object> iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance())
  2184. {
  2185. Object *obj = iter.cur();
  2186. AIUpdateInterface *ai = obj->getAIUpdateInterface();
  2187. if (!ai) {
  2188. continue;
  2189. }
  2190. Coord3D pos = *obj->getPosition();
  2191. Waypoint *way = TheTerrainLogic->getClosestWaypointOnPath( &pos, waypointPathLabel );
  2192. if (!way) {
  2193. return;
  2194. }
  2195. ai->chooseLocomotorSet(LOCOMOTORSET_PANIC);
  2196. ai->aiPanic(way, CMD_FROM_SCRIPT);
  2197. }
  2198. }
  2199. //-------------------------------------------------------------------------------------------------
  2200. /** doNamedKill */
  2201. //-------------------------------------------------------------------------------------------------
  2202. void ScriptActions::doNamedKill(const AsciiString& unitName)
  2203. {
  2204. Object *pUnit = TheScriptEngine->getUnitNamed(unitName);
  2205. if (!pUnit) {
  2206. return;
  2207. }
  2208. pUnit->kill();
  2209. }
  2210. //-------------------------------------------------------------------------------------------------
  2211. /** doTeamKill */
  2212. //-------------------------------------------------------------------------------------------------
  2213. void ScriptActions::doTeamKill(const AsciiString& teamName)
  2214. {
  2215. Team *team = TheScriptEngine->getTeamNamed(teamName);
  2216. if (!team) {
  2217. return;
  2218. }
  2219. team->killTeam();
  2220. }
  2221. //-------------------------------------------------------------------------------------------------
  2222. /** doPlayerKill */
  2223. //-------------------------------------------------------------------------------------------------
  2224. void ScriptActions::doPlayerKill(const AsciiString& playerName)
  2225. {
  2226. Player* pPlayer = TheScriptEngine->getPlayerFromAsciiString(playerName);
  2227. if (!pPlayer) {
  2228. return;
  2229. }
  2230. pPlayer->killPlayer();
  2231. }
  2232. //-------------------------------------------------------------------------------------------------
  2233. /** doDisplayText */
  2234. //-------------------------------------------------------------------------------------------------
  2235. void ScriptActions::doDisplayText(const AsciiString& displayText)
  2236. {
  2237. TheInGameUI->message(displayText);
  2238. }
  2239. //-------------------------------------------------------------------------------------------------
  2240. /** doInGamePopupMessage */
  2241. //-------------------------------------------------------------------------------------------------
  2242. void ScriptActions::doInGamePopupMessage( const AsciiString& message, Int x, Int y, Int width, Bool pause )
  2243. {
  2244. TheInGameUI->popupMessage(message, x,y,width, pause, FALSE);
  2245. }
  2246. //-------------------------------------------------------------------------------------------------
  2247. /** doDisplayCinematicText */
  2248. //-------------------------------------------------------------------------------------------------
  2249. void ScriptActions::doDisplayCinematicText(const AsciiString& displayText, const AsciiString& fontType, Int timeInSeconds)
  2250. {
  2251. // set the text
  2252. UnicodeString uStr = TheGameText->fetch( displayText );
  2253. AsciiString aStr;
  2254. aStr.translate( uStr );
  2255. TheDisplay->setCinematicText( aStr );
  2256. // Gets the font info from parsing through fontType
  2257. // get the font name
  2258. AsciiString fontName = AsciiString::TheEmptyString;
  2259. char buf[256];
  2260. char *c;
  2261. strcpy(buf, fontType.str());
  2262. for( c = buf; c != '\0'; *c++ )
  2263. {
  2264. if( *c != ' ' && *c++ != '-' )
  2265. fontName.concat(c);
  2266. else
  2267. break;
  2268. }
  2269. while( *c != ':' )
  2270. *c++;
  2271. *c++; // eat through " - Size:"
  2272. // get font size
  2273. AsciiString fontSize = AsciiString::TheEmptyString;
  2274. for( ; *c != '\0'; *c++ )
  2275. {
  2276. if( *c != '\0' && *c != ' ' )
  2277. {
  2278. fontSize.concat( *c );
  2279. }
  2280. else
  2281. {
  2282. break;
  2283. }
  2284. }
  2285. Int size = atoi( fontSize.str() );
  2286. // get font fold
  2287. Bool bold = FALSE;
  2288. if( fontType.endsWith( "[Bold]" ) )
  2289. bold = TRUE;
  2290. // phew, now set as new font
  2291. GameFont *font = TheFontLibrary->getFont( fontName,
  2292. TheGlobalLanguageData->adjustFontSize(size), bold );
  2293. TheDisplay->setCinematicFont( font );
  2294. // set time
  2295. Int frames = LOGICFRAMES_PER_SECOND * timeInSeconds;
  2296. TheDisplay->setCinematicTextFrames( frames );
  2297. }
  2298. //-------------------------------------------------------------------------------------------------
  2299. /** doCameoFlash */
  2300. //-------------------------------------------------------------------------------------------------
  2301. void ScriptActions::doCameoFlash(const AsciiString& name, Int timeInSeconds)
  2302. {
  2303. const CommandButton *button;
  2304. //sanity
  2305. button = TheControlBar->findCommandButton( name );
  2306. if( button == NULL )
  2307. {
  2308. DEBUG_CRASH(( "ScriptActions::doCameoFlash can't find AsciiString cameoflash" ));
  2309. }
  2310. Int frames = LOGICFRAMES_PER_SECOND * timeInSeconds;
  2311. // every time the framecount % 20 == 0, controlbar:: update will do Cameo Flash
  2312. Int count = frames / DRAWABLE_FRAMES_PER_FLASH;
  2313. // make sure count is even, so the cameo will return to its original state
  2314. if( count % 2 == 1 )
  2315. count++;
  2316. button->setFlashCount(count);
  2317. TheControlBar->setFlash( TRUE );
  2318. }
  2319. //-------------------------------------------------------------------------------------------------
  2320. /** doNamedCustomColor */
  2321. //-------------------------------------------------------------------------------------------------
  2322. void ScriptActions::doNamedCustomColor(const AsciiString& unitName, Color c)
  2323. {
  2324. //sanity
  2325. Object *obj = TheScriptEngine->getUnitNamed( unitName );
  2326. if ( !obj )
  2327. {
  2328. return;
  2329. }
  2330. obj->setCustomIndicatorColor(c);
  2331. }
  2332. //-------------------------------------------------------------------------------------------------
  2333. /** doNamedFlash */
  2334. //-------------------------------------------------------------------------------------------------
  2335. void ScriptActions::doNamedFlash(const AsciiString& unitName, Int timeInSeconds, const RGBColor *color)
  2336. {
  2337. /** This is called the first time this unit is told by the script to flash. timeInSeconds will tell the drawable
  2338. how long to flash for. Sets drawable to start flashing but only allows drawable's update to
  2339. call the actual flash method */
  2340. //sanity
  2341. Object *obj = TheScriptEngine->getUnitNamed( unitName );
  2342. if ( !obj )
  2343. {
  2344. return;
  2345. }
  2346. Drawable *drawable = obj->getDrawable();
  2347. if( !drawable )
  2348. {
  2349. return;
  2350. }
  2351. if( timeInSeconds > 0 )
  2352. {
  2353. // set count for drawable, but do not flash, allow drawable update to handle it
  2354. /* The designer specifies how long he wants the unit to flash for. We will
  2355. convert this number into a count of how many times to call the doNamedFlash method */
  2356. Int frames = LOGICFRAMES_PER_SECOND * timeInSeconds;
  2357. // every time the framecount % 20 == 0, drawable::update will call doNamedFlash
  2358. Int count = frames / DRAWABLE_FRAMES_PER_FLASH;
  2359. Color flashy = (color == NULL) ? obj->getIndicatorColor() : color->getAsInt();
  2360. drawable->setFlashColor( flashy );
  2361. drawable->setFlashCount( count );
  2362. return;
  2363. }
  2364. }
  2365. //-------------------------------------------------------------------------------------------------
  2366. /** doTeamFlash */
  2367. //-------------------------------------------------------------------------------------------------
  2368. void ScriptActions::doTeamFlash(const AsciiString& teamName, Int timeInSeconds, const RGBColor *color)
  2369. {
  2370. Team *team = TheScriptEngine->getTeamNamed( teamName );
  2371. if (team == NULL || !team->hasAnyObjects())
  2372. return;
  2373. DLINK_ITERATOR<Object> iter = team->iterate_TeamMemberList();
  2374. while( !iter.done() ) {
  2375. Object *nextObj = iter.cur();
  2376. Object *obj = nextObj;
  2377. if (!obj) {
  2378. break;
  2379. }
  2380. iter.advance();
  2381. Drawable *draw = obj->getDrawable();
  2382. if( !draw )
  2383. break;
  2384. Int frames = LOGICFRAMES_PER_SECOND * timeInSeconds;
  2385. Int count = frames / DRAWABLE_FRAMES_PER_FLASH;
  2386. Color flashy = (color == NULL) ? obj->getIndicatorColor() : color->getAsInt();
  2387. draw->setFlashColor( flashy );
  2388. draw->setFlashCount( count );
  2389. }
  2390. }
  2391. #define ARBITRARY_BUFFER_SIZE 128
  2392. //-------------------------------------------------------------------------------------------------
  2393. /** doMoviePlayFullScreen */
  2394. //-------------------------------------------------------------------------------------------------
  2395. void ScriptActions::doMoviePlayFullScreen(const AsciiString& movieName)
  2396. {
  2397. TheDisplay->playMovie(movieName);
  2398. }
  2399. //-------------------------------------------------------------------------------------------------
  2400. /** doMoviePlayRadar */
  2401. //-------------------------------------------------------------------------------------------------
  2402. void ScriptActions::doMoviePlayRadar(const AsciiString& movieName)
  2403. {
  2404. TheInGameUI->playMovie(movieName);
  2405. }
  2406. //-------------------------------------------------------------------------------------------------
  2407. /** doSoundPlayFromNamed */
  2408. //-------------------------------------------------------------------------------------------------
  2409. void ScriptActions::doSoundPlayFromNamed(const AsciiString& soundName, const AsciiString& unitName)
  2410. {
  2411. Object *pUnit = TheScriptEngine->getUnitNamed(unitName);
  2412. if (!pUnit) {
  2413. return;
  2414. }
  2415. AudioEventRTS sfx(soundName, pUnit->getID());
  2416. sfx.setIsLogicalAudio(true);
  2417. TheAudio->addAudioEvent(&sfx);
  2418. }
  2419. //-------------------------------------------------------------------------------------------------
  2420. /** doSpeechPlay */
  2421. //-------------------------------------------------------------------------------------------------
  2422. enum
  2423. {
  2424. SUBTITLE_DURATION = 8000
  2425. };
  2426. void ScriptActions::doSpeechPlay(const AsciiString& speechName, Bool allowOverlap)
  2427. {
  2428. AudioEventRTS speech(speechName);
  2429. speech.setIsLogicalAudio(true);
  2430. speech.setPlayerIndex(ThePlayerList->getLocalPlayer()->getPlayerIndex());
  2431. speech.setUninterruptable(!allowOverlap);
  2432. TheAudio->addAudioEvent(&speech);
  2433. AsciiString subtitleLabel("DIALOGEVENT:");
  2434. subtitleLabel.concat(speechName);
  2435. subtitleLabel.concat("Subtitle");
  2436. // Found is important, because a failure will return a valid "Missing: 'Label'" string.
  2437. Bool found = FALSE;
  2438. UnicodeString subtitle = TheGameText->fetch(subtitleLabel, &found);
  2439. if( found && !subtitle.isEmpty() && subtitle.getCharAt(0) != '*')
  2440. {
  2441. // Foreign versions can specify region specifc subtitle strings if they want.
  2442. // English will have strings with / for easy translation, but they don't want to display.
  2443. TheInGameUI->militarySubtitle( subtitleLabel, SUBTITLE_DURATION );
  2444. }
  2445. }
  2446. //-------------------------------------------------------------------------------------------------
  2447. /** doPlayerTransferAssetsToPlayer */
  2448. //-------------------------------------------------------------------------------------------------
  2449. void ScriptActions::doPlayerTransferAssetsToPlayer(const AsciiString& playerSrcName, const AsciiString& playerDstName)
  2450. {
  2451. Player *pPlayerDest = TheScriptEngine->getPlayerFromAsciiString(playerDstName);
  2452. Player *pPlayerSrc = TheScriptEngine->getPlayerFromAsciiString(playerSrcName);
  2453. if (!pPlayerDest || !pPlayerSrc) {
  2454. return;
  2455. }
  2456. pPlayerDest->transferAssetsFromThat(pPlayerSrc);
  2457. }
  2458. //-------------------------------------------------------------------------------------------------
  2459. /** doNamedTransferAssetsToPlayer */
  2460. //-------------------------------------------------------------------------------------------------
  2461. void ScriptActions::doNamedTransferAssetsToPlayer(const AsciiString& unitName, const AsciiString& playerDstName)
  2462. {
  2463. Object *pObj = TheScriptEngine->getUnitNamed(unitName);
  2464. Player *pPlayer = TheScriptEngine->getPlayerFromAsciiString(playerDstName);
  2465. if (!pObj || !pPlayer) {
  2466. return;
  2467. }
  2468. Team *playerTeam = pPlayer->getDefaultTeam();
  2469. if (!playerTeam) {
  2470. return;
  2471. }
  2472. pObj->setTeam(playerTeam);
  2473. updateTeamAndPlayerStuff(pObj, NULL);
  2474. }
  2475. //-------------------------------------------------------------------------------------------------
  2476. /** excludePlayerFromScoreScreen */
  2477. //-------------------------------------------------------------------------------------------------
  2478. void ScriptActions::excludePlayerFromScoreScreen(const AsciiString& playerName)
  2479. {
  2480. Player *pPlayer = TheScriptEngine->getPlayerFromAsciiString(playerName);
  2481. if (pPlayer == NULL) {
  2482. return;
  2483. }
  2484. pPlayer->setListInScoreScreen(FALSE);
  2485. }
  2486. //-------------------------------------------------------------------------------------------------
  2487. /** excludePlayerFromScoreScreen */
  2488. //-------------------------------------------------------------------------------------------------
  2489. void ScriptActions::enableScoring(Bool score)
  2490. {
  2491. TheGameLogic->enableScoring(score);
  2492. }
  2493. //-------------------------------------------------------------------------------------------------
  2494. /** updatePlayerRelationTowardPlayer */
  2495. //-------------------------------------------------------------------------------------------------
  2496. void ScriptActions::updatePlayerRelationTowardPlayer(const AsciiString& playerSrcName, Int relationType, const AsciiString& playerDstName)
  2497. {
  2498. Player *pPlayerDest = TheScriptEngine->getPlayerFromAsciiString(playerDstName);
  2499. Player *pPlayerSrc = TheScriptEngine->getPlayerFromAsciiString(playerSrcName);
  2500. if (!pPlayerDest || !pPlayerSrc) {
  2501. return;
  2502. }
  2503. pPlayerSrc->setPlayerRelationship(pPlayerDest, (Relationship) relationType);
  2504. }
  2505. //-------------------------------------------------------------------------------------------------
  2506. /** doRadarCreateEvent */
  2507. //-------------------------------------------------------------------------------------------------
  2508. void ScriptActions::doRadarCreateEvent(Coord3D *pos, Int eventType)
  2509. {
  2510. TheRadar->createEvent(pos, (RadarEventType)eventType);
  2511. }
  2512. //-------------------------------------------------------------------------------------------------
  2513. /** doObjectRadarCreateEvent */
  2514. //-------------------------------------------------------------------------------------------------
  2515. void ScriptActions::doObjectRadarCreateEvent(const AsciiString& unitName, Int eventType)
  2516. {
  2517. // get the building
  2518. Object *theBuilding = TheScriptEngine->getUnitNamed( unitName );
  2519. if (!theBuilding)
  2520. return;
  2521. // get building's position
  2522. const Coord3D *pos = theBuilding->getPosition();
  2523. if (!pos)
  2524. return;
  2525. // create event
  2526. TheRadar->createEvent(pos, (RadarEventType)eventType);
  2527. }
  2528. //-------------------------------------------------------------------------------------------------
  2529. /** doTeamRadarCreateEvent */
  2530. //-------------------------------------------------------------------------------------------------
  2531. void ScriptActions::doTeamRadarCreateEvent(const AsciiString& teamName, Int eventType)
  2532. {
  2533. // get the team
  2534. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  2535. if (!theTeam)
  2536. return;
  2537. if (!theTeam->hasAnyUnits())
  2538. return;
  2539. // get team's position
  2540. const Coord3D *pos = theTeam->getEstimateTeamPosition();
  2541. if (!pos)
  2542. return;
  2543. // create event
  2544. TheRadar->createEvent(pos, (RadarEventType)eventType);
  2545. }
  2546. //-------------------------------------------------------------------------------------------------
  2547. /** doRadarDisable */
  2548. //-------------------------------------------------------------------------------------------------
  2549. void ScriptActions::doRadarDisable(void)
  2550. {
  2551. TheRadar->hide(true);
  2552. }
  2553. //-------------------------------------------------------------------------------------------------
  2554. /** doRadarEnable */
  2555. //-------------------------------------------------------------------------------------------------
  2556. void ScriptActions::doRadarEnable(void)
  2557. {
  2558. TheRadar->hide(false);
  2559. }
  2560. //-------------------------------------------------------------------------------------------------
  2561. /** doCameraMotionBlurJump - zoom in at the current location, jump to waypoint, and zoom out.*/
  2562. //-------------------------------------------------------------------------------------------------
  2563. void ScriptActions::doCameraMotionBlurJump(const AsciiString& waypointName, Bool saturate)
  2564. {
  2565. Waypoint *way = TheTerrainLogic->getWaypointByName(waypointName);
  2566. if (!way) {
  2567. return;
  2568. }
  2569. Bool passed = FALSE; //assume all filters were applied correctly.
  2570. Coord3D pos = *way->getLocation();
  2571. if (TheTacticalView->setViewFilter(FT_VIEW_MOTION_BLUR_FILTER))
  2572. {
  2573. passed = TRUE;
  2574. if (saturate) {
  2575. if (!TheTacticalView->setViewFilterMode(FM_VIEW_MB_IN_AND_OUT_SATURATE))
  2576. { //failed to set filter so restore default state
  2577. TheTacticalView->setViewFilter(FT_NULL_FILTER);
  2578. passed = FALSE;
  2579. }
  2580. } else {
  2581. if (!TheTacticalView->setViewFilterMode(FM_VIEW_MB_IN_AND_OUT_ALPHA))
  2582. { //failed to set filter so restore default state
  2583. TheTacticalView->setViewFilter(FT_NULL_FILTER);
  2584. passed = FALSE;
  2585. };
  2586. }
  2587. if (passed)
  2588. TheTacticalView->setViewFilterPos(&pos);
  2589. }
  2590. if (!passed)
  2591. { //if we failed to apply the filter, we still need to get the camera to the target
  2592. //so do it another way:
  2593. TheTacticalView->lookAt(&pos);
  2594. }
  2595. }
  2596. //-------------------------------------------------------------------------------------------------
  2597. /** doCameraMotionBlurJump - zoom in at the current location, jump to waypoint, and zoom out.*/
  2598. //-------------------------------------------------------------------------------------------------
  2599. void ScriptActions::doCameraMotionBlur(Bool zoomIn, Bool saturate)
  2600. {
  2601. if (TheTacticalView->setViewFilter(FT_VIEW_MOTION_BLUR_FILTER))
  2602. {
  2603. enum FilterModes mode;
  2604. if (saturate) {
  2605. if (zoomIn) {
  2606. mode = FM_VIEW_MB_IN_SATURATE;
  2607. } else {
  2608. mode = FM_VIEW_MB_OUT_SATURATE;
  2609. }
  2610. } else {
  2611. if (zoomIn) {
  2612. mode = FM_VIEW_MB_IN_ALPHA;
  2613. } else {
  2614. mode = FM_VIEW_MB_OUT_ALPHA;
  2615. }
  2616. }
  2617. if (!TheTacticalView->setViewFilterMode(mode))
  2618. { //failed to set the filter so restore everything to normal
  2619. TheTacticalView->setViewFilter(FT_NULL_FILTER);
  2620. }
  2621. }
  2622. }
  2623. static PlayerMaskType getHumanPlayerMask( void )
  2624. {
  2625. PlayerMaskType mask;
  2626. for (Int i=0; i<ThePlayerList->getPlayerCount(); ++i)
  2627. {
  2628. const Player *player = ThePlayerList->getNthPlayer(i);
  2629. if (player->getPlayerType() == PLAYER_HUMAN)
  2630. mask &= player->getPlayerMask();
  2631. }
  2632. //DEBUG_LOG(("getHumanPlayerMask(): mask was %4.4X\n", mask));
  2633. return mask;
  2634. }
  2635. //-------------------------------------------------------------------------------------------------
  2636. /** doRevealMapAtWaypoint */
  2637. //-------------------------------------------------------------------------------------------------
  2638. void ScriptActions::doRevealMapAtWaypoint(const AsciiString& waypointName, Real radiusToReveal, const AsciiString& playerName)
  2639. {
  2640. Waypoint *way = TheTerrainLogic->getWaypointByName(waypointName);
  2641. if (!way) {
  2642. return;
  2643. }
  2644. Player* player = TheScriptEngine->getPlayerFromAsciiString(playerName);
  2645. PlayerMaskType playerMask;
  2646. if (player && playerName.isNotEmpty())
  2647. playerMask = player->getPlayerMask();
  2648. else
  2649. playerMask = getHumanPlayerMask();
  2650. Real positionX = way->getLocation()->x;
  2651. Real positionY = way->getLocation()->y;
  2652. // A reveal script is a quick look. That way a Radar Jammer will still function correctly.
  2653. ThePartitionManager->doShroudReveal(positionX, positionY, radiusToReveal, playerMask);
  2654. ThePartitionManager->undoShroudReveal(positionX, positionY, radiusToReveal, playerMask);
  2655. }
  2656. //-------------------------------------------------------------------------------------------------
  2657. /** doRevealMapAtWaypoint */
  2658. //-------------------------------------------------------------------------------------------------
  2659. void ScriptActions::doShroudMapAtWaypoint(const AsciiString& waypointName, Real radiusToShroud, const AsciiString& playerName)
  2660. {
  2661. Waypoint *way = TheTerrainLogic->getWaypointByName(waypointName);
  2662. if (!way) {
  2663. return;
  2664. }
  2665. Player* player = TheScriptEngine->getPlayerFromAsciiString(playerName);
  2666. PlayerMaskType playerMask;
  2667. if (player && playerName.isNotEmpty())
  2668. playerMask = player->getPlayerMask();
  2669. else
  2670. playerMask = getHumanPlayerMask();
  2671. Real positionX = way->getLocation()->x;
  2672. Real positionY = way->getLocation()->y;
  2673. // Likewise, this script does a dollop of shroud. Not permanent active shroud
  2674. ThePartitionManager->doShroudCover(positionX, positionY, radiusToShroud, playerMask);
  2675. ThePartitionManager->undoShroudCover(positionX, positionY, radiusToShroud, playerMask);
  2676. }
  2677. //-------------------------------------------------------------------------------------------------
  2678. /** doRevealMapEntire */
  2679. //-------------------------------------------------------------------------------------------------
  2680. void ScriptActions::doRevealMapEntire(const AsciiString& playerName)
  2681. {
  2682. DEBUG_LOG(("ScriptActions::doRevealMapEntire() for player named '%s'\n", playerName.str()));
  2683. Player* player = TheScriptEngine->getPlayerFromAsciiString(playerName);
  2684. if (player && playerName.isNotEmpty())
  2685. {
  2686. DEBUG_LOG(("ScriptActions::doRevealMapEntire() for player named '%ls' in position %d\n", player->getPlayerDisplayName().str(), player->getPlayerIndex()));
  2687. ThePartitionManager->revealMapForPlayer( player->getPlayerIndex() );
  2688. }
  2689. else
  2690. {
  2691. DEBUG_LOG(("ScriptActions::doRevealMapEntire() - no player, so doing all human players\n"));
  2692. for (Int i=0; i<ThePlayerList->getPlayerCount(); ++i)
  2693. {
  2694. Player *player = ThePlayerList->getNthPlayer(i);
  2695. if (player->getPlayerType() == PLAYER_HUMAN)
  2696. {
  2697. DEBUG_LOG(("ScriptActions::doRevealMapEntire() for player %d\n", i));
  2698. ThePartitionManager->revealMapForPlayer( i );
  2699. }
  2700. }
  2701. }
  2702. }
  2703. void ScriptActions::doRevealMapEntirePermanently( Bool reveal, const AsciiString& playerName )
  2704. {
  2705. Player* player = TheScriptEngine->getPlayerFromAsciiString(playerName);
  2706. if (player && playerName.isNotEmpty())
  2707. {
  2708. if( reveal )
  2709. ThePartitionManager->revealMapForPlayerPermanently( player->getPlayerIndex() );
  2710. else
  2711. ThePartitionManager->undoRevealMapForPlayerPermanently( player->getPlayerIndex() );
  2712. }
  2713. else
  2714. {
  2715. for (Int i=0; i<ThePlayerList->getPlayerCount(); ++i)
  2716. {
  2717. Player *player = ThePlayerList->getNthPlayer(i);
  2718. if (player->getPlayerType() == PLAYER_HUMAN)
  2719. {
  2720. DEBUG_LOG(("ScriptActions::doRevealMapEntirePermanently() for player %d\n", i));
  2721. if( reveal )
  2722. ThePartitionManager->revealMapForPlayerPermanently( i );
  2723. else
  2724. ThePartitionManager->undoRevealMapForPlayerPermanently( i );
  2725. }
  2726. }
  2727. }
  2728. }
  2729. //-------------------------------------------------------------------------------------------------
  2730. /** doShroudMapEntire */
  2731. //-------------------------------------------------------------------------------------------------
  2732. void ScriptActions::doShroudMapEntire(const AsciiString& playerName)
  2733. {
  2734. Player* player = TheScriptEngine->getPlayerFromAsciiString(playerName);
  2735. if (player && playerName.isNotEmpty())
  2736. {
  2737. ThePartitionManager->shroudMapForPlayer( player->getPlayerIndex() );
  2738. }
  2739. else
  2740. {
  2741. for (Int i=0; i<ThePlayerList->getPlayerCount(); ++i)
  2742. {
  2743. Player *player = ThePlayerList->getNthPlayer(i);
  2744. if (player->getPlayerType() == PLAYER_HUMAN)
  2745. {
  2746. DEBUG_LOG(("ScriptActions::doShroudMapEntire() for player %d\n", i));
  2747. ThePartitionManager->shroudMapForPlayer( i );
  2748. }
  2749. }
  2750. }
  2751. }
  2752. //-------------------------------------------------------------------------------------------------
  2753. /** doTeamAvailableForRecruitment */
  2754. //-------------------------------------------------------------------------------------------------
  2755. void ScriptActions::doTeamAvailableForRecruitment(const AsciiString& teamName, Bool availability)
  2756. {
  2757. Team *theTeam = TheScriptEngine->getTeamNamed(teamName);
  2758. if (!theTeam) {
  2759. return;
  2760. }
  2761. theTeam->setRecruitable(availability);
  2762. }
  2763. //-------------------------------------------------------------------------------------------------
  2764. /** doCollectNearbyForTeam */
  2765. //-------------------------------------------------------------------------------------------------
  2766. void ScriptActions::doCollectNearbyForTeam(const AsciiString& teamName)
  2767. {
  2768. DEBUG_CRASH(("You would think this has been implemented, but you'd be wrong. (doCollectNearbyForTeam)"));
  2769. }
  2770. //-------------------------------------------------------------------------------------------------
  2771. /** doMergeTeamIntoTeam */
  2772. //-------------------------------------------------------------------------------------------------
  2773. void ScriptActions::doMergeTeamIntoTeam(const AsciiString& teamSrcName, const AsciiString& teamDestName)
  2774. {
  2775. Team *teamSrc = TheScriptEngine->getTeamNamed(teamSrcName);
  2776. Team *teamDest = TheScriptEngine->getTeamNamed(teamDestName);
  2777. if (teamDest==NULL) {
  2778. teamDest = TheTeamFactory->findTeam( teamDestName );
  2779. }
  2780. if (!teamSrc || !teamDest) {
  2781. return;
  2782. }
  2783. // Bool done = FALSE;
  2784. DLINK_ITERATOR<Object> iter = teamSrc->iterate_TeamMemberList();
  2785. Object *nextObj = iter.cur();
  2786. while (!iter.done()) {
  2787. Object *obj = nextObj;
  2788. if (!obj) {
  2789. break;
  2790. }
  2791. // this has to be done here, setting the team will screw up the iterator. total bummer dude. jkmcd
  2792. nextObj = iter.cur();
  2793. iter.advance();
  2794. obj->setTeam(teamDest);
  2795. updateTeamAndPlayerStuff(obj, NULL);
  2796. }
  2797. if (nextObj) {
  2798. nextObj->setTeam(teamDest);
  2799. updateTeamAndPlayerStuff(nextObj, NULL);
  2800. }
  2801. teamSrc->deleteTeam();
  2802. teamDest->setActive(); // in case we just created him.
  2803. }
  2804. //-------------------------------------------------------------------------------------------------
  2805. /** doDisableInput */
  2806. //-------------------------------------------------------------------------------------------------
  2807. void ScriptActions::doDisableInput()
  2808. {
  2809. #if defined(_DEBUG) || defined(_INTERNAL)
  2810. if (!TheGlobalData->m_disableScriptedInputDisabling)
  2811. #endif
  2812. {
  2813. TheInGameUI->setInputEnabled(false);
  2814. TheMouse->setVisibility(false);
  2815. TheInGameUI->deselectAllDrawables();
  2816. TheInGameUI->clearAttackMoveToMode();
  2817. TheInGameUI->setWaypointMode( FALSE );
  2818. TheControlBar->deleteBuildTooltipLayout();
  2819. TheLookAtTranslator->resetModes();
  2820. }
  2821. }
  2822. //-------------------------------------------------------------------------------------------------
  2823. /** doEnableInput */
  2824. //-------------------------------------------------------------------------------------------------
  2825. void ScriptActions::doEnableInput()
  2826. {
  2827. TheInGameUI->setInputEnabled(true);
  2828. TheMouse->setVisibility(true);
  2829. }
  2830. //-------------------------------------------------------------------------------------------------
  2831. /** doSetBorderShroud */
  2832. //-------------------------------------------------------------------------------------------------
  2833. void ScriptActions::doSetBorderShroud( Bool setting )
  2834. {
  2835. if( setting )
  2836. TheDisplay->setBorderShroudLevel(TheGlobalData->m_shroudAlpha);
  2837. else
  2838. TheDisplay->setBorderShroudLevel(TheGlobalData->m_clearAlpha);
  2839. }
  2840. //-------------------------------------------------------------------------------------------------
  2841. /** doIdleAllPlayerUnits */
  2842. //-------------------------------------------------------------------------------------------------
  2843. void ScriptActions::doIdleAllPlayerUnits(const AsciiString& playerName)
  2844. {
  2845. Player* player = TheScriptEngine->getPlayerFromAsciiString(playerName);
  2846. if (player && playerName.isNotEmpty())
  2847. {
  2848. player->setUnitsShouldIdleOrResume(true);
  2849. }
  2850. else
  2851. {
  2852. for (Int i=0; i<ThePlayerList->getPlayerCount(); ++i)
  2853. {
  2854. Player *player = ThePlayerList->getNthPlayer(i);
  2855. if (player->getPlayerType() == PLAYER_HUMAN)
  2856. {
  2857. DEBUG_LOG(("ScriptActions::doIdleAllPlayerUnits() for player %d\n", i));
  2858. player->setUnitsShouldIdleOrResume(true);
  2859. }
  2860. }
  2861. }
  2862. }
  2863. //-------------------------------------------------------------------------------------------------
  2864. /** doResumeSupplyTruckingForIdleUnits */
  2865. //-------------------------------------------------------------------------------------------------
  2866. void ScriptActions::doResumeSupplyTruckingForIdleUnits(const AsciiString& playerName)
  2867. {
  2868. Player* player = TheScriptEngine->getPlayerFromAsciiString(playerName);
  2869. if (player && playerName.isNotEmpty())
  2870. {
  2871. player->setUnitsShouldIdleOrResume(false);
  2872. }
  2873. else
  2874. {
  2875. for (Int i=0; i<ThePlayerList->getPlayerCount(); ++i)
  2876. {
  2877. Player *player = ThePlayerList->getNthPlayer(i);
  2878. if (player->getPlayerType() == PLAYER_HUMAN)
  2879. {
  2880. DEBUG_LOG(("ScriptActions::doResumeSupplyTruckingForIdleUnits() for player %d\n", i));
  2881. player->setUnitsShouldIdleOrResume(false);
  2882. }
  2883. }
  2884. }
  2885. }
  2886. //-------------------------------------------------------------------------------------------------
  2887. /** doAmbientSoundsPause */
  2888. //-------------------------------------------------------------------------------------------------
  2889. void ScriptActions::doAmbientSoundsPause(Bool pausing) // if true, then pause, if false then resume.
  2890. {
  2891. TheAudio->pauseAmbient(pausing);
  2892. }
  2893. //-------------------------------------------------------------------------------------------------
  2894. /** doMusicTrackChange */
  2895. //-------------------------------------------------------------------------------------------------
  2896. void ScriptActions::doMusicTrackChange(const AsciiString& newTrackName, Bool fadeout, Bool fadein)
  2897. {
  2898. // Stop playing the music
  2899. if (fadeout) {
  2900. TheAudio->removeAudioEvent(AHSV_StopTheMusicFade);
  2901. } else {
  2902. TheAudio->removeAudioEvent(AHSV_StopTheMusic);
  2903. }
  2904. AudioEventRTS event(newTrackName);
  2905. event.setShouldFade(fadein);
  2906. event.setPlayerIndex(ThePlayerList->getLocalPlayer()->getPlayerIndex());
  2907. TheAudio->addAudioEvent(&event);
  2908. TheScriptEngine->setCurrentTrackName(newTrackName);
  2909. }
  2910. //-------------------------------------------------------------------------------------------------
  2911. /** doTeamGarrisonSpecificBuilding */
  2912. //-------------------------------------------------------------------------------------------------
  2913. void ScriptActions::doTeamGarrisonSpecificBuilding(const AsciiString& teamName, const AsciiString& buildingName)
  2914. {
  2915. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  2916. if (!theTeam) {
  2917. return;
  2918. }
  2919. Object *theBuilding = TheScriptEngine->getUnitNamed(buildingName);
  2920. if (!theBuilding) {
  2921. return;
  2922. }
  2923. if( !theBuilding->getContain() )
  2924. {
  2925. DEBUG_CRASH( ("doTeamGarrisonSpecificBuilding script -- building doesn't have a container!" ) );
  2926. return;
  2927. }
  2928. PlayerMaskType player = theBuilding->getContain()->getPlayerWhoEntered();
  2929. if (!(theBuilding->isKindOf(KINDOF_STRUCTURE) &&
  2930. (player == 0) || (player == theTeam->getControllingPlayer()->getPlayerMask()))) {
  2931. return;
  2932. }
  2933. AIGroup* theGroup = TheAI->createGroup();
  2934. if (!theGroup) {
  2935. return;
  2936. }
  2937. theTeam->getTeamAsAIGroup(theGroup);
  2938. theGroup->groupEnter(theBuilding, CMD_FROM_SCRIPT);
  2939. }
  2940. //-------------------------------------------------------------------------------------------------
  2941. /** doExitSpecificBuilding */
  2942. //-------------------------------------------------------------------------------------------------
  2943. void ScriptActions::doExitSpecificBuilding(const AsciiString& buildingName)
  2944. {
  2945. Object *theBuilding = TheScriptEngine->getUnitNamed(buildingName);
  2946. if (!theBuilding)
  2947. {
  2948. return;
  2949. }
  2950. if (!theBuilding->isKindOf(KINDOF_STRUCTURE))
  2951. {
  2952. return;
  2953. }
  2954. AIUpdateInterface *ai = theBuilding->getAIUpdateInterface();
  2955. if (ai)
  2956. {
  2957. ai->chooseLocomotorSet(LOCOMOTORSET_NORMAL);
  2958. ai->aiEvacuate( FALSE, CMD_FROM_SCRIPT );
  2959. return;
  2960. }
  2961. ContainModuleInterface *contain = theBuilding->getContain();
  2962. if (contain)
  2963. {
  2964. contain->removeAllContained( FALSE );
  2965. }
  2966. }
  2967. //-------------------------------------------------------------------------------------------------
  2968. /** doTeamGarrisonNearestBuilding */
  2969. //-------------------------------------------------------------------------------------------------
  2970. void ScriptActions::doTeamGarrisonNearestBuilding(const AsciiString& teamName)
  2971. {
  2972. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  2973. if (!theTeam) {
  2974. return;
  2975. }
  2976. DLINK_ITERATOR<Object> diter = theTeam->iterate_TeamMemberList();
  2977. Object *leader = diter.cur();
  2978. if (!leader) {
  2979. return;
  2980. }
  2981. PartitionFilter *filters[16];
  2982. Int count = 0;
  2983. PartitionFilterAcceptByKindOf f1( MAKE_KINDOF_MASK( KINDOF_FS_INTERNET_CENTER ), KINDOFMASK_NONE );
  2984. PartitionFilterGarrisonableByPlayer f2(theTeam->getControllingPlayer(), true, CMD_FROM_SCRIPT);
  2985. if( leader->isKindOf( KINDOF_MONEY_HACKER ) )
  2986. {
  2987. //If the leader is a hacker, then look for an internet center instead of a normal building!
  2988. filters[ count++ ] = &f1;
  2989. }
  2990. else
  2991. {
  2992. //If the leader ISN'T a hacker, then look for standard fare garrisonable buildings (internet centers won't show up)!
  2993. filters[ count++ ] = &f2;
  2994. }
  2995. PartitionFilterSameMapStatus filterMapStatus(leader);
  2996. filters[ count++ ] = &filterMapStatus;
  2997. filters[count++] = NULL;
  2998. ObjectIterator *iter = ThePartitionManager->iterateObjectsInRange(leader, REALLY_FAR, FROM_CENTER_3D, filters, ITER_SORTED_NEAR_TO_FAR);
  2999. MemoryPoolObjectHolder hold(iter);
  3000. // here's what we do. Find out how many slots each building has open, and tell each unit individually to
  3001. // garrison a specific building. We won't use the partition solver because we've already done most of the work
  3002. for (Object *theBuilding = iter->first(); theBuilding; theBuilding = iter->next()) {
  3003. ContainModuleInterface *cmi = theBuilding->getContain();
  3004. if (!cmi) {
  3005. continue;
  3006. }
  3007. Int slotsAvailable = cmi->getContainMax() - cmi->getContainCount();
  3008. for (int i = 0; i < slotsAvailable; ) {
  3009. Object *obj = diter.cur();
  3010. if (diter.done() || !obj) {
  3011. return;
  3012. }
  3013. AIUpdateInterface *ai = obj->getAIUpdateInterface();
  3014. if (ai && obj->isKindOf(KINDOF_INFANTRY) && !obj->isKindOf(KINDOF_NO_GARRISON)) {
  3015. ai->aiEnter(theBuilding, CMD_FROM_SCRIPT);
  3016. ++i;
  3017. }
  3018. diter.advance();
  3019. }
  3020. }
  3021. }
  3022. //-------------------------------------------------------------------------------------------------
  3023. /** doTeamExitAllBuildings */
  3024. //-------------------------------------------------------------------------------------------------
  3025. void ScriptActions::doTeamExitAllBuildings(const AsciiString& teamName)
  3026. {
  3027. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  3028. if (!theTeam) {
  3029. return;
  3030. }
  3031. for (DLINK_ITERATOR<Object> iter = theTeam->iterate_TeamMemberList(); !iter.done(); iter.advance()) {
  3032. Object *obj = iter.cur();
  3033. if (!obj) {
  3034. continue;
  3035. }
  3036. AIUpdateInterface *ai = obj->getAIUpdateInterface();
  3037. if (!ai) {
  3038. continue;
  3039. }
  3040. ai->chooseLocomotorSet(LOCOMOTORSET_NORMAL);
  3041. ai->aiExit(NULL, CMD_FROM_SCRIPT);
  3042. }
  3043. }
  3044. //-------------------------------------------------------------------------------------------------
  3045. /** doUnitGarrisonSpecificBuilding */
  3046. //-------------------------------------------------------------------------------------------------
  3047. void ScriptActions::doUnitGarrisonSpecificBuilding(const AsciiString& unitName, const AsciiString& buildingName)
  3048. {
  3049. Object *theUnit = TheScriptEngine->getUnitNamed( unitName );
  3050. if (!theUnit) {
  3051. return;
  3052. }
  3053. Object *theBuilding = TheScriptEngine->getUnitNamed(buildingName);
  3054. if (!theBuilding) {
  3055. return;
  3056. }
  3057. ContainModuleInterface *contain = theBuilding->getContain();
  3058. if( !contain )
  3059. {
  3060. DEBUG_CRASH(("doUnitGarrisonSpecificBuilding script -- building doesn't have a container" ));
  3061. return;
  3062. }
  3063. PlayerMaskType player = theBuilding->getContain()->getPlayerWhoEntered();
  3064. if (!(theBuilding->isKindOf(KINDOF_STRUCTURE) &&
  3065. (player == 0) || (player == theUnit->getControllingPlayer()->getPlayerMask()))) {
  3066. return;
  3067. }
  3068. AIUpdateInterface *ai = theUnit->getAIUpdateInterface();
  3069. if (!ai) {
  3070. return;
  3071. }
  3072. ai->chooseLocomotorSet(LOCOMOTORSET_NORMAL);
  3073. ai->aiEnter(theBuilding, CMD_FROM_SCRIPT);
  3074. }
  3075. //-------------------------------------------------------------------------------------------------
  3076. /** doUnitGarrisonNearestBuilding */
  3077. //-------------------------------------------------------------------------------------------------
  3078. void ScriptActions::doUnitGarrisonNearestBuilding(const AsciiString& unitName)
  3079. {
  3080. Object *theUnit = TheScriptEngine->getUnitNamed( unitName );
  3081. if (!theUnit) {
  3082. return;
  3083. }
  3084. AIUpdateInterface *ai = theUnit->getAIUpdateInterface();
  3085. if (!ai) {
  3086. return;
  3087. }
  3088. PartitionFilter *filters[16];
  3089. Int count = 0;
  3090. PartitionFilterAcceptByKindOf f1(MAKE_KINDOF_MASK(KINDOF_STRUCTURE), KINDOFMASK_NONE);
  3091. filters[ count++ ] = &f1;
  3092. PartitionFilterSameMapStatus filterMapStatus(theUnit);
  3093. filters[ count++ ] = &filterMapStatus;
  3094. PartitionFilterAcceptByKindOf f2( MAKE_KINDOF_MASK( KINDOF_FS_INTERNET_CENTER ), KINDOFMASK_NONE );
  3095. PartitionFilterRejectByKindOf f3( MAKE_KINDOF_MASK( KINDOF_FS_INTERNET_CENTER ), KINDOFMASK_NONE );
  3096. if( theUnit->isKindOf( KINDOF_MONEY_HACKER ) )
  3097. {
  3098. //If the unit is a hacker, then look for an internet center instead of a normal building!
  3099. filters[ count++ ] = &f2;
  3100. }
  3101. else
  3102. {
  3103. //If the unit ISN'T a hacker, then ignore internet centers!
  3104. filters[ count++ ] = &f3;
  3105. }
  3106. filters[count++] = NULL;
  3107. ObjectIterator *iter = ThePartitionManager->iterateObjectsInRange(theUnit, REALLY_FAR, FROM_CENTER_3D, filters, ITER_SORTED_NEAR_TO_FAR);
  3108. MemoryPoolObjectHolder hold(iter);
  3109. for (Object *theBuilding = iter->first(); theBuilding; theBuilding = iter->next())
  3110. {
  3111. ContainModuleInterface *contain = theBuilding->getContain();
  3112. if( !contain )
  3113. {
  3114. DEBUG_CRASH( ("doUnitGarrisonNearestBuilding script -- building doesn't have a container.") );
  3115. continue;
  3116. }
  3117. PlayerMaskType player = theBuilding->getContain()->getPlayerWhoEntered();
  3118. if (!((player == 0) || (player == theUnit->getControllingPlayer()->getPlayerMask()))) {
  3119. continue;
  3120. }
  3121. ai->chooseLocomotorSet(LOCOMOTORSET_NORMAL);
  3122. ai->aiEnter(theBuilding, CMD_FROM_SCRIPT);
  3123. return;
  3124. }
  3125. }
  3126. //-------------------------------------------------------------------------------------------------
  3127. /** doNamedEnableStealth */
  3128. //-------------------------------------------------------------------------------------------------
  3129. void ScriptActions::doNamedEnableStealth( const AsciiString& unitName, Bool enabled )
  3130. {
  3131. Object *self = TheScriptEngine->getUnitNamed( unitName );
  3132. if( self )
  3133. {
  3134. self->setScriptStatus( OBJECT_STATUS_SCRIPT_UNSTEALTHED, !enabled );
  3135. }
  3136. }
  3137. //-------------------------------------------------------------------------------------------------
  3138. /** doTeamEnableStealth */
  3139. //-------------------------------------------------------------------------------------------------
  3140. void ScriptActions::doTeamEnableStealth( const AsciiString& teamName, Bool enabled )
  3141. {
  3142. Team *team = TheScriptEngine->getTeamNamed( teamName );
  3143. if( !team )
  3144. {
  3145. return;
  3146. }
  3147. for( DLINK_ITERATOR<Object> iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance() )
  3148. {
  3149. Object *obj = iter.cur();
  3150. if( obj )
  3151. {
  3152. obj->setScriptStatus( OBJECT_STATUS_SCRIPT_UNSTEALTHED, !enabled );
  3153. }
  3154. }
  3155. }
  3156. //-------------------------------------------------------------------------------------------------
  3157. /** doNamedSetUnmanned */
  3158. //-------------------------------------------------------------------------------------------------
  3159. void ScriptActions::doNamedSetUnmanned( const AsciiString& unitName )
  3160. {
  3161. Object *self = TheScriptEngine->getUnitNamed( unitName );
  3162. if( self )
  3163. {
  3164. self->setDisabled( DISABLED_UNMANNED );
  3165. TheGameLogic->deselectObject( self, PLAYERMASK_ALL, TRUE );
  3166. // Convert it to the neutral team so it renders gray giving visual representation that it is unmanned.
  3167. self->setTeam( ThePlayerList->getNeutralPlayer()->getDefaultTeam() );
  3168. }
  3169. }
  3170. //-------------------------------------------------------------------------------------------------
  3171. /** doTeamSetUnmanned */
  3172. //-------------------------------------------------------------------------------------------------
  3173. void ScriptActions::doTeamSetUnmanned( const AsciiString& teamName )
  3174. {
  3175. Team *team = TheScriptEngine->getTeamNamed( teamName );
  3176. if( !team )
  3177. {
  3178. return;
  3179. }
  3180. for( DLINK_ITERATOR<Object> iter = team->iterate_TeamMemberList(); !iter.done(); )
  3181. {
  3182. Object *obj = iter.cur();
  3183. //Advance the iterator NOW because when we unman the object, the team gets nuked, and
  3184. //the iterator stops after the first iteration!
  3185. iter.advance();
  3186. //*************
  3187. if( obj )
  3188. {
  3189. obj->setDisabled( DISABLED_UNMANNED );
  3190. TheGameLogic->deselectObject( obj, PLAYERMASK_ALL, TRUE );
  3191. // Convert it to the neutral team so it renders gray giving visual representation that it is unmanned.
  3192. obj->setTeam( ThePlayerList->getNeutralPlayer()->getDefaultTeam() );
  3193. }
  3194. }
  3195. }
  3196. //-------------------------------------------------------------------------------------------------
  3197. void ScriptActions::doNamedSetBoobytrapped( const AsciiString& thingTemplateName, const AsciiString& unitName )
  3198. {
  3199. Object *obj = TheScriptEngine->getUnitNamed( unitName );
  3200. if( obj )
  3201. {
  3202. const ThingTemplate *thing = TheThingFactory->findTemplate( thingTemplateName );
  3203. if( thing )
  3204. {
  3205. Object *boobytrap = TheThingFactory->newObject( thing, obj->getTeam() );
  3206. if( boobytrap )
  3207. {
  3208. static NameKeyType key_StickyBombUpdate = NAMEKEY( "StickyBombUpdate" );
  3209. StickyBombUpdate *update = (StickyBombUpdate*)boobytrap->findUpdateModule( key_StickyBombUpdate );
  3210. if( update )
  3211. {
  3212. //The charge gets positioned randomly on the outside of the perimeter of the victim.
  3213. Coord3D pos;
  3214. obj->getGeometryInfo().makeRandomOffsetOnPerimeter( pos );
  3215. //Get the angle and transform matrix from the obj... then transform the calculated
  3216. //position
  3217. const Matrix3D *transform = obj->getTransformMatrix();
  3218. transform->Transform_Vector( *transform, *(Vector3*)(&pos), (Vector3*)(&pos) );
  3219. update->initStickyBomb( obj, NULL, &pos );
  3220. }
  3221. }
  3222. }
  3223. }
  3224. }
  3225. //-------------------------------------------------------------------------------------------------
  3226. void ScriptActions::doTeamSetBoobytrapped( const AsciiString& thingTemplateName, const AsciiString& teamName )
  3227. {
  3228. Team *team = TheScriptEngine->getTeamNamed( teamName );
  3229. if( !team )
  3230. {
  3231. return;
  3232. }
  3233. for( DLINK_ITERATOR<Object> iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance() )
  3234. {
  3235. Object *obj = iter.cur();
  3236. const ThingTemplate *thing = TheThingFactory->findTemplate( thingTemplateName );
  3237. if( thing )
  3238. {
  3239. Object *boobytrap = TheThingFactory->newObject( thing, obj->getTeam() );
  3240. if( boobytrap )
  3241. {
  3242. static NameKeyType key_StickyBombUpdate = NAMEKEY( "StickyBombUpdate" );
  3243. StickyBombUpdate *update = (StickyBombUpdate*)boobytrap->findUpdateModule( key_StickyBombUpdate );
  3244. if( update )
  3245. {
  3246. //The charge gets positioned randomly on the outside of the perimeter of the victim.
  3247. Coord3D pos;
  3248. obj->getGeometryInfo().makeRandomOffsetOnPerimeter( pos );
  3249. //Get the angle and transform matrix from the obj... then transform the calculated
  3250. //position
  3251. const Matrix3D *transform = obj->getTransformMatrix();
  3252. transform->Transform_Vector( *transform, *(Vector3*)(&pos), (Vector3*)(&pos) );
  3253. update->initStickyBomb( obj, NULL, &pos );
  3254. }
  3255. }
  3256. }
  3257. }
  3258. }
  3259. //-------------------------------------------------------------------------------------------------
  3260. /** doUnitExitBuilding */
  3261. //-------------------------------------------------------------------------------------------------
  3262. void ScriptActions::doUnitExitBuilding(const AsciiString& unitName)
  3263. {
  3264. Object *theUnit = TheScriptEngine->getUnitNamed( unitName );
  3265. if (!theUnit) {
  3266. return;
  3267. }
  3268. AIUpdateInterface *ai = theUnit->getAIUpdateInterface();
  3269. if (!ai) {
  3270. return;
  3271. }
  3272. ai->chooseLocomotorSet(LOCOMOTORSET_NORMAL);
  3273. ai->aiExit(NULL, CMD_FROM_SCRIPT);
  3274. }
  3275. //-------------------------------------------------------------------------------------------------
  3276. /** doPlayerGarrisonAllBuildings */
  3277. //-------------------------------------------------------------------------------------------------
  3278. void ScriptActions::doPlayerGarrisonAllBuildings(const AsciiString& playerName)
  3279. {
  3280. Player* player = TheScriptEngine->getPlayerFromAsciiString(playerName);
  3281. if (!player) {
  3282. return;
  3283. }
  3284. player->garrisonAllUnits(CMD_FROM_SCRIPT);
  3285. }
  3286. //-------------------------------------------------------------------------------------------------
  3287. /** doPlayerExitAllBuildings */
  3288. //-------------------------------------------------------------------------------------------------
  3289. void ScriptActions::doPlayerExitAllBuildings(const AsciiString& playerName)
  3290. {
  3291. Player* player = TheScriptEngine->getPlayerFromAsciiString(playerName);
  3292. if (!player) {
  3293. return;
  3294. }
  3295. player->ungarrisonAllUnits(CMD_FROM_SCRIPT);
  3296. }
  3297. //-------------------------------------------------------------------------------------------------
  3298. /** doLetterBoxMode */
  3299. //-------------------------------------------------------------------------------------------------
  3300. void ScriptActions::doLetterBoxMode(Bool startLetterbox)
  3301. {
  3302. if (startLetterbox)
  3303. {
  3304. HideControlBar(TRUE);
  3305. TheDisplay->enableLetterBox(TRUE);
  3306. }
  3307. else
  3308. {
  3309. ShowControlBar(FALSE);
  3310. TheDisplay->enableLetterBox(FALSE);
  3311. }
  3312. }
  3313. //-------------------------------------------------------------------------------------------------
  3314. /** doBlackWhiteMode */
  3315. //-------------------------------------------------------------------------------------------------
  3316. void ScriptActions::doBlackWhiteMode(Bool startBWMode, Int frames)
  3317. {
  3318. if (startBWMode)
  3319. {
  3320. TheTacticalView->setViewFilterMode(FM_VIEW_BW_BLACK_AND_WHITE);
  3321. TheTacticalView->setViewFilter(FT_VIEW_BW_FILTER);
  3322. TheTacticalView->setFadeParameters(frames, 1);
  3323. }
  3324. else
  3325. {
  3326. if ((TheTacticalView->getViewFilterType()) == FT_VIEW_BW_FILTER)
  3327. { //mode already set, turn it off
  3328. TheTacticalView->setFadeParameters(frames, -1);
  3329. }
  3330. }
  3331. }
  3332. //-------------------------------------------------------------------------------------------------
  3333. /** doSkyBox */
  3334. //-------------------------------------------------------------------------------------------------
  3335. extern void doSkyBoxSet(Bool startDraw); //hack to avoid including globaldata here.
  3336. void ScriptActions::doSkyBox(Bool startDraw)
  3337. {
  3338. if (startDraw)
  3339. {
  3340. doSkyBoxSet(1);
  3341. }
  3342. else
  3343. {
  3344. doSkyBoxSet(0);
  3345. }
  3346. }
  3347. //-------------------------------------------------------------------------------------------------
  3348. /** doWeather */
  3349. //-------------------------------------------------------------------------------------------------
  3350. void ScriptActions::doWeather(Bool showWeather)
  3351. {
  3352. TheSnowManager->setVisible(showWeather);
  3353. }
  3354. //-------------------------------------------------------------------------------------------------
  3355. /** Freeze time */
  3356. //-------------------------------------------------------------------------------------------------
  3357. void ScriptActions::doFreezeTime(void)
  3358. {
  3359. TheScriptEngine->doFreezeTime();
  3360. }
  3361. //-------------------------------------------------------------------------------------------------
  3362. /** Unfreeze time */
  3363. //-------------------------------------------------------------------------------------------------
  3364. void ScriptActions::doUnfreezeTime(void)
  3365. {
  3366. TheScriptEngine->doUnfreezeTime();
  3367. }
  3368. //-------------------------------------------------------------------------------------------------
  3369. /** Show a military briefing */
  3370. //-------------------------------------------------------------------------------------------------
  3371. void ScriptActions::doMilitaryCaption(const AsciiString& briefing, Int duration)
  3372. {
  3373. #if defined(_DEBUG) || defined(_INTERNAL)
  3374. if (TheGlobalData->m_disableMilitaryCaption)
  3375. duration = 1;
  3376. #endif
  3377. TheInGameUI->militarySubtitle(briefing, duration);
  3378. }
  3379. //-------------------------------------------------------------------------------------------------
  3380. /** Set the audible distance for shots in which the camera is up, and is therefore the center */
  3381. //-------------------------------------------------------------------------------------------------
  3382. void ScriptActions::doCameraSetAudibleDistance(Real audibleDistance)
  3383. {
  3384. // No-op
  3385. }
  3386. //-------------------------------------------------------------------------------------------------
  3387. /** doSetStoppingDistance */
  3388. //-------------------------------------------------------------------------------------------------
  3389. void ScriptActions::doSetStoppingDistance(const AsciiString& team, Real stoppingDistance)
  3390. {
  3391. Team *theTeam = TheScriptEngine->getTeamNamed( team );
  3392. if (theTeam)
  3393. {
  3394. for (DLINK_ITERATOR<Object> iter = theTeam->iterate_TeamMemberList(); !iter.done(); iter.advance())
  3395. {
  3396. Object *obj = iter.cur();
  3397. AIUpdateInterface *aiUpdate = obj->getAIUpdateInterface();
  3398. if (!aiUpdate || !aiUpdate->getCurLocomotor()) {
  3399. return;
  3400. }
  3401. if (stoppingDistance >= 0.5f)
  3402. {
  3403. aiUpdate->getCurLocomotor()->setCloseEnoughDist(stoppingDistance);
  3404. }
  3405. }
  3406. }
  3407. }
  3408. //-------------------------------------------------------------------------------------------------
  3409. /** doNamedSetHeld */
  3410. //-------------------------------------------------------------------------------------------------
  3411. void ScriptActions::doNamedSetHeld(const AsciiString& unit, Bool held)
  3412. {
  3413. Object *theObj = TheScriptEngine->getUnitNamed( unit );
  3414. if (theObj)
  3415. {
  3416. theObj->setDisabledUntil( DISABLED_HELD, held ? FOREVER : NEVER );
  3417. }
  3418. }
  3419. //-------------------------------------------------------------------------------------------------
  3420. /** doNamedSetStoppingDistance */
  3421. //-------------------------------------------------------------------------------------------------
  3422. void ScriptActions::doNamedSetStoppingDistance(const AsciiString& unit, Real stoppingDistance)
  3423. {
  3424. Object *theObj = TheScriptEngine->getUnitNamed( unit );
  3425. if (theObj)
  3426. {
  3427. AIUpdateInterface *aiUpdate = theObj->getAIUpdateInterface();
  3428. if (!aiUpdate || !aiUpdate->getCurLocomotor()) {
  3429. return;
  3430. }
  3431. if (stoppingDistance >= 0.5f)
  3432. {
  3433. aiUpdate->getCurLocomotor()->setCloseEnoughDist(stoppingDistance);
  3434. }
  3435. }
  3436. }
  3437. //-------------------------------------------------------------------------------------------------
  3438. /** doDisableSpecialPowerDisplay */
  3439. //-------------------------------------------------------------------------------------------------
  3440. void ScriptActions::doDisableSpecialPowerDisplay(void)
  3441. {
  3442. TheInGameUI->setSuperweaponDisplayEnabledByScript(false);
  3443. }
  3444. //-------------------------------------------------------------------------------------------------
  3445. /** doEnableSpecialPowerDisplay */
  3446. //-------------------------------------------------------------------------------------------------
  3447. void ScriptActions::doEnableSpecialPowerDisplay(void)
  3448. {
  3449. TheInGameUI->setSuperweaponDisplayEnabledByScript(true);
  3450. }
  3451. //-------------------------------------------------------------------------------------------------
  3452. /** doNamedHideSpecialPowerDisplay */
  3453. //-------------------------------------------------------------------------------------------------
  3454. void ScriptActions::doNamedHideSpecialPowerDisplay(const AsciiString& unit)
  3455. {
  3456. Object *theObj = TheScriptEngine->getUnitNamed( unit );
  3457. if (theObj)
  3458. {
  3459. TheInGameUI->hideObjectSuperweaponDisplayByScript(theObj);
  3460. }
  3461. }
  3462. //-------------------------------------------------------------------------------------------------
  3463. /** doNamedShowSpecialPowerDisplay */
  3464. //-------------------------------------------------------------------------------------------------
  3465. void ScriptActions::doNamedShowSpecialPowerDisplay(const AsciiString& unit)
  3466. {
  3467. Object *theObj = TheScriptEngine->getUnitNamed( unit );
  3468. if (theObj)
  3469. {
  3470. TheInGameUI->showObjectSuperweaponDisplayByScript(theObj);
  3471. }
  3472. }
  3473. //-------------------------------------------------------------------------------------------------
  3474. /** doAudioSetVolume */
  3475. //-------------------------------------------------------------------------------------------------
  3476. void ScriptActions::doAudioSetVolume(AudioAffect whichToAffect, Real newVolumeLevel)
  3477. {
  3478. newVolumeLevel /= 100.0f;
  3479. if (newVolumeLevel < 0.0f) {
  3480. newVolumeLevel = 0.0f;
  3481. } else if (newVolumeLevel > 1.0f) {
  3482. newVolumeLevel = 1.0f;
  3483. }
  3484. TheAudio->setVolume(newVolumeLevel, whichToAffect);
  3485. }
  3486. //-------------------------------------------------------------------------------------------------
  3487. /** doTransferTeamToPlayer */
  3488. //-------------------------------------------------------------------------------------------------
  3489. void ScriptActions::doTransferTeamToPlayer(const AsciiString& teamName, const AsciiString& playerName)
  3490. {
  3491. Team *theTeam = TheScriptEngine->getTeamNamed(teamName);
  3492. Player* playerDest = TheScriptEngine->getPlayerFromAsciiString(playerName);
  3493. if (!(theTeam && playerDest)) {
  3494. return;
  3495. }
  3496. theTeam->setControllingPlayer(playerDest);
  3497. // srj sez: ensure that all these guys get the upgrades that belong to the new player
  3498. theTeam->iterateObjects(updateTeamAndPlayerStuff, NULL);
  3499. }
  3500. //-------------------------------------------------------------------------------------------------
  3501. /** doSetMoney */
  3502. //-------------------------------------------------------------------------------------------------
  3503. void ScriptActions::doSetMoney(const AsciiString& playerName, Int money)
  3504. {
  3505. Player* player = TheScriptEngine->getPlayerFromAsciiString(playerName);
  3506. if (!player) {
  3507. return;
  3508. }
  3509. Money *m = player->getMoney();
  3510. if (!m)
  3511. return;
  3512. m->withdraw(m->countMoney());
  3513. m->deposit(money);
  3514. }
  3515. //-------------------------------------------------------------------------------------------------
  3516. /** doGiveMoney */
  3517. //-------------------------------------------------------------------------------------------------
  3518. void ScriptActions::doGiveMoney(const AsciiString& playerName, Int money)
  3519. {
  3520. Player* player = TheScriptEngine->getPlayerFromAsciiString(playerName);
  3521. if (!player) {
  3522. return;
  3523. }
  3524. Money *m = player->getMoney();
  3525. if (!m)
  3526. return;
  3527. if (money < 0)
  3528. m->withdraw(-money);
  3529. else
  3530. m->deposit(money);
  3531. }
  3532. //-------------------------------------------------------------------------------------------------
  3533. /** doDisplayCounter */
  3534. //-------------------------------------------------------------------------------------------------
  3535. void ScriptActions::doDisplayCounter(const AsciiString& counterName, const AsciiString& counterText)
  3536. {
  3537. TheInGameUI->addNamedTimer(counterName, TheGameText->fetch(counterText), false);
  3538. }
  3539. //-------------------------------------------------------------------------------------------------
  3540. /** doHideCounter */
  3541. //-------------------------------------------------------------------------------------------------
  3542. void ScriptActions::doHideCounter(const AsciiString& counterName)
  3543. {
  3544. TheInGameUI->removeNamedTimer(counterName);
  3545. }
  3546. //-------------------------------------------------------------------------------------------------
  3547. /** doDisplayCountdownTimer */
  3548. //-------------------------------------------------------------------------------------------------
  3549. void ScriptActions::doDisplayCountdownTimer(const AsciiString& timerName, const AsciiString& timerText)
  3550. {
  3551. TheInGameUI->addNamedTimer(timerName, TheGameText->fetch(timerText), true);
  3552. }
  3553. //-------------------------------------------------------------------------------------------------
  3554. /** doHideCountdownTimer */
  3555. //-------------------------------------------------------------------------------------------------
  3556. void ScriptActions::doHideCountdownTimer(const AsciiString& timerName)
  3557. {
  3558. TheInGameUI->removeNamedTimer(timerName);
  3559. }
  3560. //-------------------------------------------------------------------------------------------------
  3561. /** doDisableCountdownTimerDisplay */
  3562. //-------------------------------------------------------------------------------------------------
  3563. void ScriptActions::doDisableCountdownTimerDisplay(void)
  3564. {
  3565. TheInGameUI->showNamedTimerDisplay(FALSE);
  3566. }
  3567. //-------------------------------------------------------------------------------------------------
  3568. /** doEnableCountdownTimerDisplay */
  3569. //-------------------------------------------------------------------------------------------------
  3570. void ScriptActions::doEnableCountdownTimerDisplay(void)
  3571. {
  3572. TheInGameUI->showNamedTimerDisplay(TRUE);
  3573. }
  3574. //-------------------------------------------------------------------------------------------------
  3575. /** doNamedStopSpecialPowerCountdown */
  3576. //-------------------------------------------------------------------------------------------------
  3577. void ScriptActions::doNamedStopSpecialPowerCountdown(const AsciiString& unit, const AsciiString& specialPower, Bool stop)
  3578. {
  3579. Object *theObj = TheScriptEngine->getUnitNamed( unit );
  3580. const SpecialPowerTemplate *power = TheSpecialPowerStore->findSpecialPowerTemplate(specialPower);
  3581. if (theObj && power)
  3582. {
  3583. SpecialPowerModuleInterface *mod = theObj->getSpecialPowerModule(power);
  3584. if (mod)
  3585. {
  3586. mod->pauseCountdown(stop);
  3587. }
  3588. }
  3589. }
  3590. //-------------------------------------------------------------------------------------------------
  3591. /** doNamedSetSpecialPowerCountdown */
  3592. //-------------------------------------------------------------------------------------------------
  3593. void ScriptActions::doNamedSetSpecialPowerCountdown( const AsciiString& unit, const AsciiString& specialPower, Int seconds )
  3594. {
  3595. Object *theObj = TheScriptEngine->getUnitNamed( unit );
  3596. const SpecialPowerTemplate *power = TheSpecialPowerStore->findSpecialPowerTemplate(specialPower);
  3597. if (theObj && power)
  3598. {
  3599. SpecialPowerModuleInterface *mod = theObj->getSpecialPowerModule(power);
  3600. if (mod)
  3601. {
  3602. Int frames = LOGICFRAMES_PER_SECOND * seconds;
  3603. mod->setReadyFrame(TheGameLogic->getFrame() + frames);
  3604. }
  3605. }
  3606. }
  3607. //-------------------------------------------------------------------------------------------------
  3608. /** doNamedAddSpecialPowerCountdown */
  3609. //-------------------------------------------------------------------------------------------------
  3610. void ScriptActions::doNamedAddSpecialPowerCountdown( const AsciiString& unit, const AsciiString& specialPower, Int seconds )
  3611. {
  3612. Object *theObj = TheScriptEngine->getUnitNamed( unit );
  3613. const SpecialPowerTemplate *power = TheSpecialPowerStore->findSpecialPowerTemplate(specialPower);
  3614. if (theObj && power)
  3615. {
  3616. SpecialPowerModuleInterface *mod = theObj->getSpecialPowerModule(power);
  3617. if (mod)
  3618. {
  3619. Int frames = LOGICFRAMES_PER_SECOND * seconds;
  3620. mod->setReadyFrame(mod->getReadyFrame() + frames);
  3621. }
  3622. }
  3623. }
  3624. //-------------------------------------------------------------------------------------------------
  3625. /** doNamedFireSpecialPowerAtArea */
  3626. //-------------------------------------------------------------------------------------------------
  3627. void ScriptActions::doNamedFireSpecialPowerAtWaypoint( const AsciiString& unit, const AsciiString& specialPower, const AsciiString& waypoint )
  3628. {
  3629. Object *theObj = TheScriptEngine->getUnitNamed( unit );
  3630. const SpecialPowerTemplate *power = TheSpecialPowerStore->findSpecialPowerTemplate(specialPower);
  3631. if (theObj && power)
  3632. {
  3633. SpecialPowerModuleInterface *mod = theObj->getSpecialPowerModule(power);
  3634. if (mod)
  3635. {
  3636. Waypoint *way = TheTerrainLogic->getWaypointByName(waypoint);
  3637. if (!way) {
  3638. return;
  3639. }
  3640. mod->doSpecialPowerAtLocation(way->getLocation(), INVALID_ANGLE, COMMAND_FIRED_BY_SCRIPT );
  3641. }
  3642. }
  3643. }
  3644. //-------------------------------------------------------------------------------------------------
  3645. /** doNamedFireSpecialPowerAtArea */
  3646. //-------------------------------------------------------------------------------------------------
  3647. void ScriptActions::doSkirmishFireSpecialPowerAtMostCost( const AsciiString &player, const AsciiString& specialPower )
  3648. {
  3649. Int enemyNdx;
  3650. Player *enemyPlayer = TheScriptEngine->getSkirmishEnemyPlayer();
  3651. if (enemyPlayer == NULL) return;
  3652. enemyNdx = enemyPlayer->getPlayerIndex();
  3653. const SpecialPowerTemplate *power = TheSpecialPowerStore->findSpecialPowerTemplate(specialPower);
  3654. if (power==NULL)
  3655. return;
  3656. Real radius = 50.0f;
  3657. if (power->getRadiusCursorRadius()>radius) {
  3658. radius = power->getRadiusCursorRadius();
  3659. }
  3660. Player::PlayerTeamList::const_iterator it;
  3661. Player *pPlayer = TheScriptEngine->getPlayerFromAsciiString(player);
  3662. if (pPlayer==NULL)
  3663. return;
  3664. for (it = pPlayer->getPlayerTeams()->begin(); it != pPlayer->getPlayerTeams()->end(); ++it)
  3665. {
  3666. for (DLINK_ITERATOR<Team> iter = (*it)->iterate_TeamInstanceList(); !iter.done(); iter.advance())
  3667. {
  3668. Team *team = iter.cur();
  3669. if (!team)
  3670. continue;
  3671. for (DLINK_ITERATOR<Object> iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance())
  3672. {
  3673. Object *pObj = iter.cur();
  3674. if (!pObj)
  3675. continue;
  3676. SpecialPowerModuleInterface *mod = pObj->getSpecialPowerModule(power);
  3677. if (mod)
  3678. {
  3679. if( !mod->isReady() )
  3680. continue;
  3681. Coord3D location;
  3682. Bool locationFound = FALSE;
  3683. locationFound = pPlayer->computeSuperweaponTarget(power, &location, enemyNdx, radius);
  3684. if( locationFound && power->getSpecialPowerType() == SPECIAL_SNEAK_ATTACK )
  3685. {
  3686. //We need to modify the location. We're already calculated the sweet spot, but we need to modify that
  3687. //position if we can't place it in the current location.
  3688. const ThingTemplate *sneakAttackTemplate = mod->getReferenceThingTemplate();
  3689. if( sneakAttackTemplate )
  3690. {
  3691. locationFound = pPlayer->calcClosestConstructionZoneLocation( sneakAttackTemplate, &location );
  3692. }
  3693. }
  3694. DEBUG_ASSERTCRASH( locationFound, ("ScriptActions::doSkirmishFireSpecialPowerAtMostCost() could not find a valid (costly) location.") );
  3695. if( locationFound && location.lengthSqr() > 0.0f )
  3696. {
  3697. mod->doSpecialPowerAtLocation( &location, INVALID_ANGLE, COMMAND_FIRED_BY_SCRIPT );
  3698. }
  3699. break;
  3700. }
  3701. }
  3702. }
  3703. }
  3704. }
  3705. //-------------------------------------------------------------------------------------------------
  3706. /** doNamedFireSpecialPowerAtNamed */
  3707. //-------------------------------------------------------------------------------------------------
  3708. void ScriptActions::doNamedFireSpecialPowerAtNamed( const AsciiString& unit, const AsciiString& specialPower, const AsciiString& target )
  3709. {
  3710. Object *theObj = TheScriptEngine->getUnitNamed( unit );
  3711. Object *theTarget = TheScriptEngine->getUnitNamed( target );
  3712. const SpecialPowerTemplate *power = TheSpecialPowerStore->findSpecialPowerTemplate(specialPower);
  3713. if (theObj && power && theTarget)
  3714. {
  3715. SpecialPowerModuleInterface *mod = theObj->getSpecialPowerModule(power);
  3716. if (mod)
  3717. {
  3718. mod->doSpecialPowerAtObject(theTarget, COMMAND_FIRED_BY_SCRIPT );
  3719. }
  3720. }
  3721. }
  3722. //-------------------------------------------------------------------------------------------------
  3723. void ScriptActions::doNamedUseCommandButtonAbility( const AsciiString& unit, const AsciiString& ability )
  3724. {
  3725. Object *theObj = TheScriptEngine->getUnitNamed( unit );
  3726. //Sanity check
  3727. if( !theObj )
  3728. {
  3729. return;
  3730. }
  3731. const CommandSet *commandSet = TheControlBar->findCommandSet( theObj->getCommandSetString() );
  3732. if( commandSet )
  3733. {
  3734. for( Int i = 0; i < MAX_COMMANDS_PER_SET; i++ )
  3735. {
  3736. //Get the command button.
  3737. const CommandButton *commandButton = commandSet->getCommandButton(i);
  3738. if( commandButton )
  3739. {
  3740. if( !commandButton->getName().isEmpty() )
  3741. {
  3742. if( commandButton->getName() == ability )
  3743. {
  3744. theObj->doCommandButton( commandButton, CMD_FROM_SCRIPT );
  3745. }
  3746. }
  3747. }
  3748. }
  3749. }
  3750. }
  3751. //-------------------------------------------------------------------------------------------------
  3752. void ScriptActions::doNamedUseCommandButtonAbilityOnNamed( const AsciiString& unit, const AsciiString& ability, const AsciiString& target )
  3753. {
  3754. Object *theObj = TheScriptEngine->getUnitNamed( unit );
  3755. Object *theTarget = TheScriptEngine->getUnitNamed( target );
  3756. //Sanity check
  3757. if( !theObj || !theTarget )
  3758. {
  3759. return;
  3760. }
  3761. const CommandSet *commandSet = TheControlBar->findCommandSet( theObj->getCommandSetString() );
  3762. if( commandSet )
  3763. {
  3764. for( Int i = 0; i < MAX_COMMANDS_PER_SET; i++ )
  3765. {
  3766. //Get the command button.
  3767. const CommandButton *commandButton = commandSet->getCommandButton(i);
  3768. if( commandButton )
  3769. {
  3770. if( !commandButton->getName().isEmpty() )
  3771. {
  3772. if( commandButton->getName() == ability )
  3773. {
  3774. theObj->doCommandButtonAtObject( commandButton, theTarget, CMD_FROM_SCRIPT );
  3775. }
  3776. }
  3777. }
  3778. }
  3779. }
  3780. }
  3781. //-------------------------------------------------------------------------------------------------
  3782. void ScriptActions::doNamedUseCommandButtonAbilityAtWaypoint( const AsciiString& unit, const AsciiString& ability, const AsciiString& waypoint )
  3783. {
  3784. Object *theObj = TheScriptEngine->getUnitNamed( unit );
  3785. Waypoint *pWaypoint = TheTerrainLogic->getWaypointByName( waypoint );
  3786. //Sanity check
  3787. if( !theObj || !pWaypoint )
  3788. {
  3789. return;
  3790. }
  3791. const CommandSet *commandSet = TheControlBar->findCommandSet( theObj->getCommandSetString() );
  3792. if( commandSet )
  3793. {
  3794. for( Int i = 0; i < MAX_COMMANDS_PER_SET; i++ )
  3795. {
  3796. //Get the command button.
  3797. const CommandButton *commandButton = commandSet->getCommandButton(i);
  3798. if( commandButton )
  3799. {
  3800. if( !commandButton->getName().isEmpty() )
  3801. {
  3802. if( commandButton->getName() == ability )
  3803. {
  3804. theObj->doCommandButtonAtPosition( commandButton, pWaypoint->getLocation(), CMD_FROM_SCRIPT );
  3805. }
  3806. }
  3807. }
  3808. }
  3809. }
  3810. }
  3811. //-------------------------------------------------------------------------------------------------
  3812. void ScriptActions::doNamedUseCommandButtonAbilityUsingWaypointPath( const AsciiString& unit, const AsciiString& ability, const AsciiString& waypointPath )
  3813. {
  3814. Object *theObj = TheScriptEngine->getUnitNamed( unit );
  3815. if( !theObj )
  3816. {
  3817. return;
  3818. }
  3819. Waypoint *pWaypoint = TheTerrainLogic->getClosestWaypointOnPath( theObj->getPosition(), waypointPath );
  3820. //Sanity check
  3821. if( !pWaypoint )
  3822. {
  3823. return;
  3824. }
  3825. const CommandSet *commandSet = TheControlBar->findCommandSet( theObj->getCommandSetString() );
  3826. if( commandSet )
  3827. {
  3828. for( Int i = 0; i < MAX_COMMANDS_PER_SET; i++ )
  3829. {
  3830. //Get the command button.
  3831. const CommandButton *commandButton = commandSet->getCommandButton(i);
  3832. if( commandButton )
  3833. {
  3834. if( !commandButton->getName().isEmpty() )
  3835. {
  3836. if( commandButton->getName() == ability )
  3837. {
  3838. theObj->doCommandButtonUsingWaypoints( commandButton, pWaypoint, CMD_FROM_SCRIPT );
  3839. }
  3840. }
  3841. }
  3842. }
  3843. }
  3844. }
  3845. //-------------------------------------------------------------------------------------------------
  3846. void ScriptActions::doTeamUseCommandButtonAbility( const AsciiString& team, const AsciiString& ability )
  3847. {
  3848. Team *theTeam = TheScriptEngine->getTeamNamed( team );
  3849. // The team is the team based on the name, and the calling team (if any) and the team that
  3850. // triggered the condition. jba. :)
  3851. if( !theTeam )
  3852. {
  3853. return;
  3854. }
  3855. const CommandButton *commandButton = TheControlBar->findCommandButton( ability );
  3856. if( !commandButton )
  3857. {
  3858. return;
  3859. }
  3860. AIGroup* theGroup = TheAI->createGroup();
  3861. if( !theGroup )
  3862. {
  3863. return;
  3864. }
  3865. theTeam->getTeamAsAIGroup( theGroup );
  3866. theGroup->groupDoCommandButton( commandButton, CMD_FROM_SCRIPT );
  3867. }
  3868. //-------------------------------------------------------------------------------------------------
  3869. void ScriptActions::doTeamUseCommandButtonAbilityOnNamed( const AsciiString& team, const AsciiString& ability, const AsciiString& target )
  3870. {
  3871. Team *theTeam = TheScriptEngine->getTeamNamed( team );
  3872. // The team is the team based on the name, and the calling team (if any) and the team that
  3873. // triggered the condition. jba. :)
  3874. if( !theTeam )
  3875. {
  3876. return;
  3877. }
  3878. Object *theObj = TheScriptEngine->getUnitNamed( target );
  3879. if( !theObj )
  3880. {
  3881. return;
  3882. }
  3883. const CommandButton *commandButton = TheControlBar->findCommandButton( ability );
  3884. if( !commandButton )
  3885. {
  3886. return;
  3887. }
  3888. AIGroup* theGroup = TheAI->createGroup();
  3889. if( !theGroup )
  3890. {
  3891. return;
  3892. }
  3893. theTeam->getTeamAsAIGroup( theGroup );
  3894. theGroup->groupDoCommandButtonAtObject( commandButton, theObj, CMD_FROM_SCRIPT );
  3895. }
  3896. //-------------------------------------------------------------------------------------------------
  3897. void ScriptActions::doTeamUseCommandButtonAbilityAtWaypoint( const AsciiString& team, const AsciiString& ability, const AsciiString& waypoint )
  3898. {
  3899. Team *theTeam = TheScriptEngine->getTeamNamed( team );
  3900. // The team is the team based on the name, and the calling team (if any) and the team that
  3901. // triggered the condition. jba. :)
  3902. if( !theTeam )
  3903. {
  3904. return;
  3905. }
  3906. Waypoint *pWaypoint = TheTerrainLogic->getWaypointByName( waypoint );
  3907. if( !pWaypoint )
  3908. {
  3909. return;
  3910. }
  3911. const CommandButton *commandButton = TheControlBar->findCommandButton( ability );
  3912. if( !commandButton )
  3913. {
  3914. return;
  3915. }
  3916. AIGroup* theGroup = TheAI->createGroup();
  3917. if( !theGroup )
  3918. {
  3919. return;
  3920. }
  3921. theTeam->getTeamAsAIGroup( theGroup );
  3922. theGroup->groupDoCommandButtonAtPosition( commandButton, pWaypoint->getLocation(), CMD_FROM_SCRIPT );
  3923. }
  3924. //-------------------------------------------------------------------------------------------------
  3925. /** doRadarRefresh */
  3926. //-------------------------------------------------------------------------------------------------
  3927. void ScriptActions::doRadarRefresh( void )
  3928. {
  3929. TheRadar->refreshTerrain( TheTerrainLogic );
  3930. }
  3931. //-------------------------------------------------------------------------------------------------
  3932. /** doCameraTetherNamed */
  3933. //-------------------------------------------------------------------------------------------------
  3934. void ScriptActions::doCameraTetherNamed(const AsciiString& unit, Bool snapToUnit, Real play)
  3935. {
  3936. Object *theObj = TheScriptEngine->getUnitNamed( unit );
  3937. if (theObj)
  3938. {
  3939. TheTacticalView->setCameraLock(theObj->getID());
  3940. if (snapToUnit)
  3941. TheTacticalView->snapToCameraLock();
  3942. TheTacticalView->setSnapMode( View::LOCK_TETHER, play );
  3943. }
  3944. }
  3945. //-------------------------------------------------------------------------------------------------
  3946. /** doCameraStopTetherNamed */
  3947. //-------------------------------------------------------------------------------------------------
  3948. void ScriptActions::doCameraStopTetherNamed(void)
  3949. {
  3950. TheTacticalView->setCameraLock(INVALID_ID);
  3951. }
  3952. //-------------------------------------------------------------------------------------------------
  3953. /** doCameraSetDefault */
  3954. //-------------------------------------------------------------------------------------------------
  3955. void ScriptActions::doCameraSetDefault(Real pitch, Real angle, Real maxHeight)
  3956. {
  3957. TheTacticalView->setDefaultView(pitch, angle, maxHeight);
  3958. }
  3959. //-------------------------------------------------------------------------------------------------
  3960. /** doNamedStop */
  3961. //-------------------------------------------------------------------------------------------------
  3962. void ScriptActions::doNamedStop(const AsciiString& unitName)
  3963. {
  3964. Object *theObj = TheScriptEngine->getUnitNamed( unitName );
  3965. if (!theObj) {
  3966. return;
  3967. }
  3968. AIUpdateInterface *ai = theObj->getAIUpdateInterface();
  3969. if (!ai) {
  3970. return;
  3971. }
  3972. ai->aiIdle(CMD_FROM_SCRIPT);
  3973. }
  3974. //-------------------------------------------------------------------------------------------------
  3975. /** doTeamStop */
  3976. //-------------------------------------------------------------------------------------------------
  3977. void ScriptActions::doTeamStop(const AsciiString& teamName, Bool shouldDisband)
  3978. {
  3979. Team *theTeam = TheScriptEngine->getTeamNamed(teamName);
  3980. if (!theTeam) {
  3981. return;
  3982. }
  3983. AIGroup* theGroup = TheAI->createGroup();
  3984. if (!theGroup) {
  3985. return;
  3986. }
  3987. theTeam->getTeamAsAIGroup(theGroup);
  3988. theGroup->groupIdle(CMD_FROM_SCRIPT);
  3989. if (shouldDisband) {
  3990. Team *playerDefaultTeam = theTeam->getControllingPlayer()->getDefaultTeam();
  3991. for (DLINK_ITERATOR<Object> iter = theTeam->iterate_TeamMemberList(); !iter.done(); iter.advance()) {
  3992. Object *obj = iter.cur();
  3993. AIUpdateInterface *ai = obj->getAIUpdateInterface();
  3994. if (!ai) {
  3995. continue;
  3996. }
  3997. ai->setIsRecruitable(TRUE);
  3998. }
  3999. doMergeTeamIntoTeam(teamName, playerDefaultTeam->getName());
  4000. }
  4001. }
  4002. //-------------------------------------------------------------------------------------------------
  4003. /** doTeamSetOverrideRelationToTeam */
  4004. //-------------------------------------------------------------------------------------------------
  4005. void ScriptActions::doTeamSetOverrideRelationToTeam(const AsciiString& teamName, const AsciiString& otherTeam, Int relation)
  4006. {
  4007. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  4008. Team *theOtherTeam = TheScriptEngine->getTeamNamed( otherTeam );
  4009. if (theTeam && theOtherTeam) {
  4010. theTeam->setOverrideTeamRelationship(theOtherTeam->getID(), (Relationship)relation);
  4011. }
  4012. }
  4013. //-------------------------------------------------------------------------------------------------
  4014. /** doTeamRemoveOverrideRelationToTeam */
  4015. //-------------------------------------------------------------------------------------------------
  4016. void ScriptActions::doTeamRemoveOverrideRelationToTeam(const AsciiString& teamName, const AsciiString& otherTeam)
  4017. {
  4018. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  4019. Team *theOtherTeam = TheScriptEngine->getTeamNamed( otherTeam );
  4020. if (theTeam && theOtherTeam) {
  4021. theTeam->removeOverrideTeamRelationship(theOtherTeam->getID());
  4022. }
  4023. }
  4024. //-------------------------------------------------------------------------------------------------
  4025. /** doPlayerSetOverrideRelationToTeam */
  4026. //-------------------------------------------------------------------------------------------------
  4027. void ScriptActions::doPlayerSetOverrideRelationToTeam(const AsciiString& playerName, const AsciiString& otherTeam, Int relation)
  4028. {
  4029. Player *thePlayer = ThePlayerList->findPlayerWithNameKey(NAMEKEY(playerName));
  4030. Team *theOtherTeam = TheScriptEngine->getTeamNamed( otherTeam );
  4031. if (thePlayer && theOtherTeam) {
  4032. thePlayer->setTeamRelationship(theOtherTeam, (Relationship)relation);
  4033. }
  4034. }
  4035. //-------------------------------------------------------------------------------------------------
  4036. /** doPlayerRemoveOverrideRelationToTeam */
  4037. //-------------------------------------------------------------------------------------------------
  4038. void ScriptActions::doPlayerRemoveOverrideRelationToTeam(const AsciiString& playerName, const AsciiString& otherTeam)
  4039. {
  4040. Player *thePlayer = ThePlayerList->findPlayerWithNameKey(NAMEKEY(playerName));
  4041. Team *theOtherTeam = TheScriptEngine->getTeamNamed( otherTeam );
  4042. if (thePlayer && theOtherTeam) {
  4043. thePlayer->removeTeamRelationship(theOtherTeam);
  4044. }
  4045. }
  4046. //-------------------------------------------------------------------------------------------------
  4047. /** doTeamSetOverrideRelationToPlayer */
  4048. //-------------------------------------------------------------------------------------------------
  4049. void ScriptActions::doTeamSetOverrideRelationToPlayer(const AsciiString& teamName, const AsciiString& otherPlayer, Int relation)
  4050. {
  4051. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  4052. Player *theOtherPlayer = ThePlayerList->findPlayerWithNameKey(NAMEKEY(otherPlayer));
  4053. if (theTeam && theOtherPlayer) {
  4054. theTeam->setOverridePlayerRelationship(theOtherPlayer->getPlayerIndex(), (Relationship)relation);
  4055. }
  4056. }
  4057. //-------------------------------------------------------------------------------------------------
  4058. /** doTeamRemoveOverrideRelationToTeam */
  4059. //-------------------------------------------------------------------------------------------------
  4060. void ScriptActions::doTeamRemoveOverrideRelationToPlayer(const AsciiString& teamName, const AsciiString& otherPlayer)
  4061. {
  4062. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  4063. Player *theOtherPlayer = ThePlayerList->findPlayerWithNameKey(NAMEKEY(otherPlayer));
  4064. if (theTeam && theOtherPlayer) {
  4065. theTeam->removeOverridePlayerRelationship(theOtherPlayer->getPlayerIndex());
  4066. }
  4067. }
  4068. //-------------------------------------------------------------------------------------------------
  4069. /** doTeamRemoveAllOverrideRelations */
  4070. //-------------------------------------------------------------------------------------------------
  4071. void ScriptActions::doTeamRemoveAllOverrideRelations(const AsciiString& teamName)
  4072. {
  4073. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  4074. if (theTeam) {
  4075. // invalid ID is OK -- it removes all relationships
  4076. theTeam->removeOverrideTeamRelationship( NULL );
  4077. theTeam->removeOverridePlayerRelationship( NULL );
  4078. }
  4079. }
  4080. //-------------------------------------------------------------------------------------------------
  4081. /** doUnitStartSequentialScript */
  4082. //-------------------------------------------------------------------------------------------------
  4083. void ScriptActions::doUnitStartSequentialScript(const AsciiString& unitName, const AsciiString& scriptName, Int loopVal)
  4084. {
  4085. Object *obj = TheScriptEngine->getUnitNamed(unitName);
  4086. if (!obj) {
  4087. return;
  4088. }
  4089. Script *script = const_cast<Script*>(TheScriptEngine->findScriptByName(scriptName));
  4090. if (!script) {
  4091. return;
  4092. }
  4093. SequentialScript* seqScript = newInstance(SequentialScript);
  4094. seqScript->m_objectID = obj->getID();
  4095. seqScript->m_scriptToExecuteSequentially = script;
  4096. seqScript->m_timesToLoop = loopVal;
  4097. TheScriptEngine->appendSequentialScript(seqScript);
  4098. seqScript->deleteInstance();
  4099. }
  4100. //-------------------------------------------------------------------------------------------------
  4101. /** doUnitStopSequentialScript */
  4102. //-------------------------------------------------------------------------------------------------
  4103. void ScriptActions::doUnitStopSequentialScript(const AsciiString& unitName)
  4104. {
  4105. Object *obj = TheScriptEngine->getUnitNamed(unitName);
  4106. if (!obj) {
  4107. return;
  4108. }
  4109. TheScriptEngine->removeAllSequentialScripts(obj);
  4110. }
  4111. //-------------------------------------------------------------------------------------------------
  4112. /** doTeamStartSequentialScript */
  4113. //-------------------------------------------------------------------------------------------------
  4114. /** doNamedFireWeaponFollowingWaypointPath -- Kris
  4115. Orders unit to fire a waypoint following capable weapon to follow a waypoint and attack the
  4116. final waypoint position. */
  4117. //-------------------------------------------------------------------------------------------------
  4118. void ScriptActions::doNamedFireWeaponFollowingWaypointPath( const AsciiString& unit, const AsciiString& waypointPath )
  4119. {
  4120. //Get the unit... if it fails, abort.
  4121. Object *theUnit = TheScriptEngine->getUnitNamed( unit );
  4122. if( !theUnit )
  4123. {
  4124. return;
  4125. }
  4126. Coord3D pos = *theUnit->getPosition();
  4127. //Find the closest waypoint on the path.
  4128. Waypoint *way = TheTerrainLogic->getClosestWaypointOnPath( &pos, waypointPath );
  4129. if( !way )
  4130. {
  4131. return;
  4132. }
  4133. //We have to do special checking to make sure our unit even has a waypoint following capable weapon.
  4134. Weapon *weapon = theUnit->findWaypointFollowingCapableWeapon();
  4135. if( !weapon )
  4136. {
  4137. return;
  4138. }
  4139. Object *projectile = weapon->forceFireWeapon( theUnit, &pos );
  4140. if( projectile )
  4141. {
  4142. //Get the AIUpdateInterface... if it fails, abort.
  4143. AIUpdateInterface* aiUpdate = projectile->getAIUpdateInterface();
  4144. if( !aiUpdate )
  4145. {
  4146. return;
  4147. }
  4148. DEBUG_ASSERTLOG(TheTerrainLogic->isPurposeOfPath(way, waypointPath), ("***Wrong waypoint purpose. Make jba fix this.\n"));
  4149. projectile->leaveGroup();
  4150. aiUpdate->chooseLocomotorSet(LOCOMOTORSET_NORMAL);
  4151. aiUpdate->aiFollowWaypointPath(way, CMD_FROM_SCRIPT);
  4152. }
  4153. }
  4154. //-------------------------------------------------------------------------------------------------
  4155. /** doTeamStartSequentialScript */
  4156. //-------------------------------------------------------------------------------------------------
  4157. void ScriptActions::doTeamStartSequentialScript(const AsciiString& teamName, const AsciiString& scriptName, Int loopVal)
  4158. {
  4159. Team *team = TheScriptEngine->getTeamNamed(teamName);
  4160. if (!team) {
  4161. return;
  4162. }
  4163. Script *script = const_cast<Script*>(TheScriptEngine->findScriptByName(scriptName));
  4164. if (!script) {
  4165. return;
  4166. }
  4167. // Idle the team so the seq script will start executing. jba.
  4168. AIGroup* theGroup = TheAI->createGroup();
  4169. if (!theGroup) {
  4170. return;
  4171. }
  4172. team->getTeamAsAIGroup(theGroup);
  4173. theGroup->groupIdle(CMD_FROM_SCRIPT);
  4174. SequentialScript* seqScript = newInstance(SequentialScript);
  4175. seqScript->m_teamToExecOn = team;
  4176. seqScript->m_scriptToExecuteSequentially = script;
  4177. seqScript->m_timesToLoop = loopVal;
  4178. TheScriptEngine->appendSequentialScript(seqScript);
  4179. seqScript->deleteInstance();
  4180. }
  4181. //-------------------------------------------------------------------------------------------------
  4182. /** doTeamStopSequentialScript */
  4183. //-------------------------------------------------------------------------------------------------
  4184. void ScriptActions::doTeamStopSequentialScript(const AsciiString& teamName)
  4185. {
  4186. Team *team = TheScriptEngine->getTeamNamed(teamName);
  4187. if (!team) {
  4188. return;
  4189. }
  4190. TheScriptEngine->removeAllSequentialScripts(team);
  4191. }
  4192. //-------------------------------------------------------------------------------------------------
  4193. /** doUnitGuardForFramecount */
  4194. //-------------------------------------------------------------------------------------------------
  4195. void ScriptActions::doUnitGuardForFramecount(const AsciiString& unitName, Int framecount)
  4196. {
  4197. Object *obj = TheScriptEngine->getUnitNamed(unitName);
  4198. if (!obj) {
  4199. return;
  4200. }
  4201. AIUpdateInterface *ai = obj->getAIUpdateInterface();
  4202. if (!ai) {
  4203. return;
  4204. }
  4205. Coord3D pos = *obj->getPosition();
  4206. ai->chooseLocomotorSet(LOCOMOTORSET_NORMAL);
  4207. ai->aiGuardPosition(&pos, GUARDMODE_NORMAL, CMD_FROM_SCRIPT);
  4208. TheScriptEngine->setSequentialTimer(obj, framecount);
  4209. }
  4210. //-------------------------------------------------------------------------------------------------
  4211. /** doUnitIdleForFramecount */
  4212. //-------------------------------------------------------------------------------------------------
  4213. void ScriptActions::doUnitIdleForFramecount(const AsciiString& unitName, Int framecount)
  4214. {
  4215. Object *obj = TheScriptEngine->getUnitNamed(unitName);
  4216. if (!obj) {
  4217. return;
  4218. }
  4219. AIUpdateInterface *ai = obj->getAIUpdateInterface();
  4220. if (!ai) {
  4221. return;
  4222. }
  4223. ai->aiIdle(CMD_FROM_SCRIPT);
  4224. TheScriptEngine->setSequentialTimer(obj, framecount);
  4225. }
  4226. //-------------------------------------------------------------------------------------------------
  4227. /** doTeamGuardForFramecount */
  4228. //-------------------------------------------------------------------------------------------------
  4229. void ScriptActions::doTeamGuardForFramecount(const AsciiString& teamName, Int framecount)
  4230. {
  4231. Team *theTeam = TheScriptEngine->getTeamNamed(teamName);
  4232. if (!theTeam) {
  4233. return;
  4234. }
  4235. // Have all the members of the team guard at their current pos.
  4236. for (DLINK_ITERATOR<Object> iter = theTeam->iterate_TeamMemberList(); !iter.done(); iter.advance())
  4237. {
  4238. Object *obj = iter.cur();
  4239. AIUpdateInterface *ai = obj->getAIUpdateInterface();
  4240. if (!ai) {
  4241. continue;
  4242. }
  4243. Coord3D pos = *obj->getPosition();
  4244. ai->aiGuardPosition(&pos, GUARDMODE_NORMAL, CMD_FROM_SCRIPT);
  4245. }
  4246. TheScriptEngine->setSequentialTimer(theTeam, framecount);
  4247. }
  4248. //-------------------------------------------------------------------------------------------------
  4249. /** doTeamIdleForFramecount */
  4250. //-------------------------------------------------------------------------------------------------
  4251. void ScriptActions::doTeamIdleForFramecount(const AsciiString& teamName, Int framecount)
  4252. {
  4253. Team *theTeam = TheScriptEngine->getTeamNamed(teamName);
  4254. if (!theTeam) {
  4255. return;
  4256. }
  4257. AIGroup* theGroup = TheAI->createGroup();
  4258. if (!theGroup) {
  4259. return;
  4260. }
  4261. theTeam->getTeamAsAIGroup(theGroup);
  4262. Coord3D center;
  4263. theGroup->getCenter(&center);
  4264. theGroup->groupIdle(CMD_FROM_SCRIPT);
  4265. TheScriptEngine->setSequentialTimer(theTeam, framecount);
  4266. }
  4267. //-------------------------------------------------------------------------------------------------
  4268. /** doWaterChangeHeight */
  4269. //-------------------------------------------------------------------------------------------------
  4270. void ScriptActions::doWaterChangeHeight(const AsciiString& waterName, Real newHeight)
  4271. {
  4272. const WaterHandle *water = TheTerrainLogic->getWaterHandleByName(waterName);
  4273. if (!water) {
  4274. return;
  4275. }
  4276. TheTerrainLogic->setWaterHeight(water, newHeight, 999999.9f, TRUE );
  4277. }
  4278. //-------------------------------------------------------------------------------------------------
  4279. /** doWaterChangeHeightOverTime */
  4280. //-------------------------------------------------------------------------------------------------
  4281. void ScriptActions::doWaterChangeHeightOverTime( const AsciiString& waterName, Real newHeight, Real time, Real damage )
  4282. {
  4283. const WaterHandle *water = TheTerrainLogic->getWaterHandleByName( waterName );
  4284. if( water )
  4285. {
  4286. TheTerrainLogic->changeWaterHeightOverTime( water, newHeight, time, damage );
  4287. }
  4288. }
  4289. //-------------------------------------------------------------------------------------------------
  4290. /** doBorderSwitch */
  4291. //-------------------------------------------------------------------------------------------------
  4292. void ScriptActions::doBorderSwitch(Int borderToUse)
  4293. {
  4294. /*
  4295. * The observer player always has to have the map completely revealed for him.
  4296. * Border switching doesn't play nice with the permanent map reveal so for the
  4297. * observer player we need to undo the old permanent reveal, switch map borders,
  4298. * and re-reveal the map. BGC
  4299. */
  4300. Int observerPlayerIndex = -1;
  4301. if (ThePlayerList != NULL)
  4302. {
  4303. Player *observer = ThePlayerList->findPlayerWithNameKey(TheNameKeyGenerator->nameToKey("ReplayObserver"));
  4304. if (observer != NULL) {
  4305. observerPlayerIndex = observer->getPlayerIndex();
  4306. }
  4307. }
  4308. if (observerPlayerIndex != -1)
  4309. {
  4310. ThePartitionManager->undoRevealMapForPlayerPermanently( observerPlayerIndex );
  4311. }
  4312. TheTerrainLogic->setActiveBoundary(borderToUse);
  4313. if (observerPlayerIndex != -1)
  4314. {
  4315. ThePartitionManager->revealMapForPlayerPermanently( observerPlayerIndex );
  4316. }
  4317. ThePartitionManager->refreshShroudForLocalPlayer();
  4318. }
  4319. //-------------------------------------------------------------------------------------------------
  4320. /** doForceObjectSelection */
  4321. //-------------------------------------------------------------------------------------------------
  4322. void ScriptActions::doForceObjectSelection(const AsciiString& teamName, const AsciiString& objectType, Bool centerInView, const AsciiString& audioToPlay)
  4323. {
  4324. Team *team = TheScriptEngine->getTeamNamed(teamName);
  4325. if (!team) {
  4326. return;
  4327. }
  4328. Object *bestGuess = NULL;
  4329. for (DLINK_ITERATOR<Object> iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance()) {
  4330. Object *obj = iter.cur();
  4331. if (!obj) {
  4332. continue;
  4333. }
  4334. if (obj->getTemplate() && obj->getTemplate()->getName() == objectType) {
  4335. if (bestGuess == NULL || obj->getID() < bestGuess->getID()) { // lower ID means its newer
  4336. bestGuess = obj;
  4337. }
  4338. }
  4339. }
  4340. if (!(bestGuess && bestGuess->getDrawable())) {
  4341. return;
  4342. }
  4343. TheInGameUI->deselectAllDrawables();
  4344. TheInGameUI->selectDrawable(bestGuess->getDrawable());
  4345. // play the sound
  4346. AudioEventRTS audioEvent(audioToPlay);
  4347. audioEvent.setPlayerIndex(ThePlayerList->getLocalPlayer()->getPlayerIndex());
  4348. TheAudio->addAudioEvent(&audioEvent);
  4349. if (centerInView) {
  4350. Coord3D pos = *bestGuess->getPosition();
  4351. TheTacticalView->moveCameraTo(&pos, 0, 0, FALSE, 0.0f, 0.0f);
  4352. }
  4353. }
  4354. void* __cdecl killTheObject( Object *obj, void* userObj )
  4355. {
  4356. userObj;
  4357. if (obj)
  4358. obj->kill();
  4359. return NULL;
  4360. }
  4361. //-------------------------------------------------------------------------------------------------
  4362. /** doForceObjectSelection */
  4363. //-------------------------------------------------------------------------------------------------
  4364. void ScriptActions::doDestroyAllContained(const AsciiString& unitName, Int damageType )
  4365. {
  4366. Object *obj = TheScriptEngine->getUnitNamed(unitName);
  4367. if (!obj) {
  4368. return;
  4369. }
  4370. ContainModuleInterface *cmi = obj->getContain();
  4371. if( !cmi || cmi->getContainCount() == 0 )
  4372. {
  4373. return;
  4374. }
  4375. cmi->iterateContained((ContainIterateFunc)killTheObject, NULL, false);
  4376. }
  4377. //-------------------------------------------------------------------------------------------------
  4378. /** doRadarForceEnable */
  4379. //-------------------------------------------------------------------------------------------------
  4380. void ScriptActions::doRadarForceEnable(void)
  4381. {
  4382. TheRadar->forceOn(true);
  4383. }
  4384. //-------------------------------------------------------------------------------------------------
  4385. /** doRadarRevertNormal */
  4386. //-------------------------------------------------------------------------------------------------
  4387. void ScriptActions::doRadarRevertNormal(void)
  4388. {
  4389. TheRadar->forceOn(false);
  4390. }
  4391. //-------------------------------------------------------------------------------------------------
  4392. /** doScreenShake */
  4393. //-------------------------------------------------------------------------------------------------
  4394. void ScriptActions::doScreenShake( UnsignedInt intensity )
  4395. {
  4396. Coord3D pos;
  4397. TheTacticalView->getPosition( &pos );
  4398. TheTacticalView->shake( &pos, (View::CameraShakeType)intensity );
  4399. }
  4400. //-------------------------------------------------------------------------------------------------
  4401. /** doModifyBuildableStatus */
  4402. //-------------------------------------------------------------------------------------------------
  4403. void ScriptActions::doModifyBuildableStatus( const AsciiString& objectType, Int buildableStatus )
  4404. {
  4405. const ThingTemplate *templ = TheThingFactory->findTemplate(objectType);
  4406. if (!templ)
  4407. {
  4408. return;
  4409. }
  4410. TheGameLogic->setBuildableStatusOverride(templ, (BuildableStatus) buildableStatus);
  4411. }
  4412. //-------------------------------------------------------------------------------------------------
  4413. static CaveInterface* findCave(Object* obj)
  4414. {
  4415. for (BehaviorModule** i = obj->getBehaviorModules(); *i; ++i)
  4416. {
  4417. CaveInterface* c = (*i)->getCaveInterface();
  4418. if (c != NULL)
  4419. return c;
  4420. }
  4421. return NULL;
  4422. }
  4423. //-------------------------------------------------------------------------------------------------
  4424. /** doSetCaveIndex */
  4425. //-------------------------------------------------------------------------------------------------
  4426. void ScriptActions::doSetCaveIndex( const AsciiString& caveName, Int caveIndex )
  4427. {
  4428. Object *obj = TheScriptEngine->getUnitNamed(caveName);
  4429. if (!obj)
  4430. {
  4431. return;
  4432. }
  4433. CaveInterface *caveModule = findCave(obj);
  4434. if( caveModule == NULL )
  4435. return;
  4436. caveModule->tryToSetCaveIndex( caveIndex );
  4437. }
  4438. //-------------------------------------------------------------------------------------------------
  4439. /** doSetWarehouseValue */
  4440. //-------------------------------------------------------------------------------------------------
  4441. void ScriptActions::doSetWarehouseValue( const AsciiString& warehouseName, Int cashValue )
  4442. {
  4443. Object *obj = TheScriptEngine->getUnitNamed(warehouseName);
  4444. if (!obj)
  4445. {
  4446. return;
  4447. }
  4448. static const NameKeyType warehouseModuleKey = TheNameKeyGenerator->nameToKey( "SupplyWarehouseDockUpdate" );
  4449. SupplyWarehouseDockUpdate *warehouseModule = (SupplyWarehouseDockUpdate *)obj->findUpdateModule( warehouseModuleKey );
  4450. if( warehouseModule == NULL )
  4451. return;
  4452. warehouseModule->setCashValue( cashValue );
  4453. }
  4454. //-------------------------------------------------------------------------------------------------
  4455. /** doSoundEnableType */
  4456. //-------------------------------------------------------------------------------------------------
  4457. void ScriptActions::doSoundEnableType( const AsciiString& soundEventName, Bool enable )
  4458. {
  4459. TheAudio->setAudioEventEnabled(soundEventName, enable);
  4460. }
  4461. //-------------------------------------------------------------------------------------------------
  4462. void ScriptActions::doSoundRemoveAllDisabled()
  4463. {
  4464. TheAudio->removeDisabledEvents();
  4465. }
  4466. //-------------------------------------------------------------------------------------------------
  4467. void ScriptActions::doSoundRemoveType( const AsciiString& soundEventName )
  4468. {
  4469. TheAudio->removeAudioEvent( soundEventName );
  4470. }
  4471. //-------------------------------------------------------------------------------------------------
  4472. /** doSoundOverrideVolume */
  4473. //-------------------------------------------------------------------------------------------------
  4474. void ScriptActions::doSoundOverrideVolume( const AsciiString& soundEventName, Real newVolume )
  4475. {
  4476. TheAudio->setAudioEventVolumeOverride(soundEventName, newVolume / 100.0f);
  4477. }
  4478. //-------------------------------------------------------------------------------------------------
  4479. /** doSetToppleDirection */
  4480. //-------------------------------------------------------------------------------------------------
  4481. void ScriptActions::doSetToppleDirection( const AsciiString& unitName, const Coord3D *dir )
  4482. {
  4483. TheScriptEngine->setToppleDirection(unitName, dir);
  4484. }
  4485. //-------------------------------------------------------------------------------------------------
  4486. /** doMoveTeamTowardsNearest */
  4487. //-------------------------------------------------------------------------------------------------
  4488. void ScriptActions::doMoveUnitTowardsNearest( const AsciiString& unitName, const AsciiString& objectType, AsciiString triggerName)
  4489. {
  4490. Object *obj = TheScriptEngine->getUnitNamed(unitName);
  4491. if (!obj)
  4492. {
  4493. return;
  4494. }
  4495. AIUpdateInterface *ai = obj->getAIUpdateInterface();
  4496. if (!ai)
  4497. {
  4498. return;
  4499. }
  4500. PolygonTrigger *trig = TheScriptEngine->getQualifiedTriggerAreaByName(triggerName);
  4501. if (!trig)
  4502. {
  4503. return;
  4504. }
  4505. Object *bestObj = NULL;
  4506. const ThingTemplate *templ = TheThingFactory->findTemplate( objectType, FALSE );
  4507. if( templ )
  4508. {
  4509. PartitionFilterThing thingsToAccept(templ, true);
  4510. PartitionFilterPolygonTrigger acceptWithin(trig);
  4511. PartitionFilterSameMapStatus filterMapStatus(obj);
  4512. PartitionFilter *filters[] = { &thingsToAccept, &acceptWithin, &filterMapStatus, NULL };
  4513. bestObj = ThePartitionManager->getClosestObject( obj->getPosition(), REALLY_FAR, FROM_CENTER_2D, filters );
  4514. if( !bestObj )
  4515. {
  4516. return;
  4517. }
  4518. }
  4519. else
  4520. {
  4521. ObjectTypes *objectTypes = TheScriptEngine->getObjectTypes( objectType );
  4522. if( objectTypes )
  4523. {
  4524. PartitionFilterPolygonTrigger acceptWithin( trig );
  4525. PartitionFilterSameMapStatus filterMapStatus( obj );
  4526. Coord3D pos = *obj->getPosition();
  4527. Real closestDist;
  4528. Real dist;
  4529. for( Int typeIndex = 0; typeIndex < objectTypes->getListSize(); typeIndex++ )
  4530. {
  4531. AsciiString thisTypeName = objectTypes->getNthInList( typeIndex );
  4532. const ThingTemplate *thisType = TheThingFactory->findTemplate( thisTypeName );
  4533. if( thisType )
  4534. {
  4535. PartitionFilterThing f2( thisType, true );
  4536. PartitionFilter *filters[] = { &f2, &acceptWithin, &filterMapStatus, 0 };
  4537. Object *obj = ThePartitionManager->getClosestObject( &pos, REALLY_FAR, FROM_CENTER_2D, filters, &dist );
  4538. if( obj )
  4539. {
  4540. if( !bestObj || dist < closestDist )
  4541. {
  4542. bestObj = obj;
  4543. closestDist = dist;
  4544. }
  4545. }
  4546. }
  4547. }
  4548. }
  4549. }
  4550. ai->chooseLocomotorSet( LOCOMOTORSET_NORMAL );
  4551. ai->aiMoveToObject( bestObj, CMD_FROM_SCRIPT );
  4552. }
  4553. //-------------------------------------------------------------------------------------------------
  4554. /** doMoveTeamTowardsNearest */
  4555. //-------------------------------------------------------------------------------------------------
  4556. void ScriptActions::doMoveTeamTowardsNearest( const AsciiString& teamName, const AsciiString& objectType, AsciiString triggerName)
  4557. {
  4558. Team *team = TheScriptEngine->getTeamNamed(teamName);
  4559. if (!team)
  4560. {
  4561. return;
  4562. }
  4563. PolygonTrigger *trig = TheScriptEngine->getQualifiedTriggerAreaByName(triggerName);
  4564. if (!trig)
  4565. {
  4566. return;
  4567. }
  4568. //Get the first object (to use in the partition filter checks).
  4569. Object *teamObj = NULL;
  4570. for (DLINK_ITERATOR<Object> iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance())
  4571. {
  4572. teamObj = iter.cur();
  4573. if( teamObj )
  4574. {
  4575. AIUpdateInterface *ai = teamObj->getAIUpdateInterface();
  4576. if( ai )
  4577. {
  4578. break;
  4579. }
  4580. }
  4581. }
  4582. if( !teamObj )
  4583. {
  4584. return;
  4585. }
  4586. Coord3D teamPos = *team->getEstimateTeamPosition();
  4587. PartitionFilterSameMapStatus filterMapStatus( teamObj );
  4588. PartitionFilterPolygonTrigger acceptWithin( trig );
  4589. Object *bestObj = NULL;
  4590. const ThingTemplate *templ = TheThingFactory->findTemplate( objectType, FALSE );
  4591. if( templ )
  4592. {
  4593. //Find the closest specified template.
  4594. PartitionFilterThing thingsToAccept( templ, true );
  4595. PartitionFilter *filters[] = { &thingsToAccept, &acceptWithin, &filterMapStatus, NULL };
  4596. bestObj = ThePartitionManager->getClosestObject( &teamPos, REALLY_FAR, FROM_CENTER_2D, filters );
  4597. if (!bestObj)
  4598. {
  4599. return;
  4600. }
  4601. }
  4602. else
  4603. {
  4604. //Find the closest object within the object template list.
  4605. ObjectTypes *objectTypes = TheScriptEngine->getObjectTypes( objectType );
  4606. if( objectTypes )
  4607. {
  4608. Real closestDist;
  4609. Real dist;
  4610. for( Int typeIndex = 0; typeIndex < objectTypes->getListSize(); typeIndex++ )
  4611. {
  4612. AsciiString thisTypeName = objectTypes->getNthInList( typeIndex );
  4613. const ThingTemplate *thisType = TheThingFactory->findTemplate( thisTypeName );
  4614. if( thisType )
  4615. {
  4616. PartitionFilterThing thingToAccept( thisType, true );
  4617. PartitionFilter *filters[] = { &thingToAccept, &acceptWithin, &filterMapStatus, NULL };
  4618. Object *obj = ThePartitionManager->getClosestObject( &teamPos, REALLY_FAR, FROM_CENTER_2D, filters, &dist );
  4619. if( obj )
  4620. {
  4621. if( !bestObj || dist < closestDist )
  4622. {
  4623. bestObj = obj;
  4624. closestDist = dist;
  4625. }
  4626. }
  4627. }
  4628. }
  4629. }
  4630. }
  4631. for( iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance() )
  4632. {
  4633. Object *obj = iter.cur();
  4634. if( !obj )
  4635. {
  4636. return;
  4637. }
  4638. AIUpdateInterface *ai = obj->getAI();
  4639. if( !ai )
  4640. {
  4641. return;
  4642. }
  4643. ai->chooseLocomotorSet( LOCOMOTORSET_NORMAL );
  4644. ai->aiMoveToObject( bestObj, CMD_FROM_SCRIPT );
  4645. }
  4646. }
  4647. //-------------------------------------------------------------------------------------------------
  4648. /** doUnitReceiveUpgrade */
  4649. //-------------------------------------------------------------------------------------------------
  4650. void ScriptActions::doUnitReceiveUpgrade( const AsciiString& unitName, const AsciiString& upgradeName )
  4651. {
  4652. Object *obj = TheScriptEngine->getUnitNamed(unitName);
  4653. if (!obj) {
  4654. return;
  4655. }
  4656. const UpgradeTemplate *templ = TheUpgradeCenter->findUpgrade(upgradeName);
  4657. if (!templ) {
  4658. return;
  4659. }
  4660. DEBUG_ASSERTCRASH(obj->affectedByUpgrade(templ), ("Design bug: Unit '%s' was given upgrade '%s', but he is unaffected.", unitName.str(), upgradeName.str()));
  4661. obj->giveUpgrade(templ);
  4662. }
  4663. //-------------------------------------------------------------------------------------------------
  4664. /** doSkirmishAttackNearestGroupWithValue */
  4665. //-------------------------------------------------------------------------------------------------
  4666. void ScriptActions::doSkirmishAttackNearestGroupWithValue( const AsciiString& teamName, Int comparison, Int value )
  4667. {
  4668. Team *team = TheScriptEngine->getTeamNamed(teamName);
  4669. if (!team) {
  4670. return;
  4671. }
  4672. AIGroup* theGroup = TheAI->createGroup();
  4673. team->getTeamAsAIGroup(theGroup);
  4674. Player *player = team->getControllingPlayer();
  4675. if (!player)
  4676. return;
  4677. Coord3D loc;
  4678. Coord3D groupLoc;
  4679. theGroup->getCenter(&groupLoc);
  4680. if (comparison == Parameter::GREATER_EQUAL || comparison == Parameter::GREATER) {
  4681. ThePartitionManager->getNearestGroupWithValue(player->getPlayerIndex(), ALLOW_ENEMIES, VOT_CashValue,
  4682. &groupLoc, value, true, &loc);
  4683. }
  4684. theGroup->groupAttackMoveToPosition( &loc, NO_MAX_SHOTS_LIMIT, CMD_FROM_SCRIPT );
  4685. }
  4686. //-------------------------------------------------------------------------------------------------
  4687. /** doSkirmishCommandButtonOnMostValuable */
  4688. //-------------------------------------------------------------------------------------------------
  4689. void ScriptActions::doSkirmishCommandButtonOnMostValuable( const AsciiString& teamName, const AsciiString& ability, Real range, Bool allTeamMembers)
  4690. {
  4691. Team *team = TheScriptEngine->getTeamNamed(teamName);
  4692. if (!team) {
  4693. return;
  4694. }
  4695. AIGroup *theGroup = TheAI->createGroup();
  4696. team->getTeamAsAIGroup(theGroup);
  4697. Player *player = team->getControllingPlayer();
  4698. if (!player)
  4699. return;
  4700. const CommandButton *commandButton = TheControlBar->findCommandButton( ability );
  4701. if( !commandButton ) {
  4702. return;
  4703. }
  4704. Object *srcObj = NULL;
  4705. if (commandButton->getSpecialPowerTemplate()) {
  4706. srcObj = theGroup->getSpecialPowerSourceObject(commandButton->getSpecialPowerTemplate()->getID());
  4707. } else {
  4708. srcObj = theGroup->getCommandButtonSourceObject(commandButton->getCommandType());
  4709. }
  4710. if ( !srcObj ) {
  4711. return;
  4712. }
  4713. Coord3D pos;
  4714. theGroup->getCenter(&pos);
  4715. PartitionFilterPlayerAffiliation f1(team->getControllingPlayer(), ALLOW_ENEMIES, true);
  4716. PartitionFilterValidCommandButtonTarget f2(srcObj, commandButton, true, CMD_FROM_SCRIPT);
  4717. PartitionFilterSameMapStatus filterMapStatus(srcObj);
  4718. PartitionFilter *filters[] = { &f1, &f2, &filterMapStatus, 0 };
  4719. // @todo: Should we add the group's radius to the range? Seems like a possibility.
  4720. SimpleObjectIterator *iter = ThePartitionManager->iterateObjectsInRange(&pos, range, FROM_CENTER_2D, filters, ITER_SORTED_EXPENSIVE_TO_CHEAP);
  4721. MemoryPoolObjectHolder hold(iter);
  4722. if (iter && iter->first()) {
  4723. theGroup->groupDoCommandButtonAtObject(commandButton, iter->first(), CMD_FROM_SCRIPT);
  4724. }
  4725. }
  4726. //-------------------------------------------------------------------------------------------------
  4727. /** doTeamSpinForFramecount */
  4728. //-------------------------------------------------------------------------------------------------
  4729. void ScriptActions::doTeamSpinForFramecount( const AsciiString& teamName, Int waitForFrames )
  4730. {
  4731. Team *team = TheScriptEngine->getTeamNamed(teamName);
  4732. if (!team) {
  4733. return;
  4734. }
  4735. TheScriptEngine->setSequentialTimer(team, waitForFrames);
  4736. }
  4737. //-------------------------------------------------------------------------------------------------
  4738. /** doTeamUseCommandButtonOnNamed */
  4739. //-------------------------------------------------------------------------------------------------
  4740. void ScriptActions::doTeamUseCommandButtonOnNamed( const AsciiString& teamName, const AsciiString& commandAbility, const AsciiString& unitName )
  4741. {
  4742. Team *team = TheScriptEngine->getTeamNamed(teamName);
  4743. if (!team) {
  4744. return;
  4745. }
  4746. AIGroup *theGroup = TheAI->createGroup();
  4747. team->getTeamAsAIGroup(theGroup);
  4748. const CommandButton *commandButton = TheControlBar->findCommandButton(commandAbility);
  4749. if(!commandButton) {
  4750. return;
  4751. }
  4752. Object *srcObj = NULL;
  4753. if (commandButton->getSpecialPowerTemplate()) {
  4754. srcObj = theGroup->getSpecialPowerSourceObject(commandButton->getSpecialPowerTemplate()->getID());
  4755. } else {
  4756. srcObj = theGroup->getCommandButtonSourceObject(commandButton->getCommandType());
  4757. }
  4758. if (!srcObj) {
  4759. return;
  4760. }
  4761. Object *obj = TheScriptEngine->getUnitNamed( unitName );
  4762. if (!obj) {
  4763. return;
  4764. }
  4765. if (commandButton->isValidToUseOn(srcObj, obj, NULL, CMD_FROM_SCRIPT)) {
  4766. theGroup->groupDoCommandButtonAtObject(commandButton, obj, CMD_FROM_SCRIPT);
  4767. }
  4768. }
  4769. //-------------------------------------------------------------------------------------------------
  4770. /** doTeamUseCommandButtonOnNearestEnemy */
  4771. //-------------------------------------------------------------------------------------------------
  4772. void ScriptActions::doTeamUseCommandButtonOnNearestEnemy( const AsciiString& teamName, const AsciiString& commandAbility )
  4773. {
  4774. Team *team = TheScriptEngine->getTeamNamed(teamName);
  4775. if (!team) {
  4776. return;
  4777. }
  4778. AIGroup *theGroup = TheAI->createGroup();
  4779. team->getTeamAsAIGroup(theGroup);
  4780. const CommandButton *commandButton = TheControlBar->findCommandButton(commandAbility);
  4781. if(!commandButton) {
  4782. return;
  4783. }
  4784. Object *srcObj = NULL;
  4785. if (commandButton->getSpecialPowerTemplate()) {
  4786. srcObj = theGroup->getSpecialPowerSourceObject(commandButton->getSpecialPowerTemplate()->getID());
  4787. } else {
  4788. srcObj = theGroup->getCommandButtonSourceObject(commandButton->getCommandType());
  4789. }
  4790. if (!srcObj) {
  4791. return;
  4792. }
  4793. PartitionFilterPlayerAffiliation f1(team->getControllingPlayer(), ALLOW_ENEMIES, true);
  4794. PartitionFilterValidCommandButtonTarget f2(srcObj, commandButton, true, CMD_FROM_SCRIPT);
  4795. PartitionFilterSameMapStatus filterMapStatus(srcObj);
  4796. Coord3D pos;
  4797. theGroup->getCenter(&pos);
  4798. PartitionFilter *filters[] = { &f1, &f2, &filterMapStatus, 0 };
  4799. Object *obj = ThePartitionManager->getClosestObject(&pos, REALLY_FAR, FROM_CENTER_2D, filters);
  4800. if (!obj) {
  4801. return;
  4802. }
  4803. // already been checked for validity
  4804. theGroup->groupDoCommandButtonAtObject(commandButton, obj, CMD_FROM_SCRIPT);
  4805. }
  4806. //-------------------------------------------------------------------------------------------------
  4807. /** doTeamUseCommandButtonOnNearestGarrisonedBuilding */
  4808. //-------------------------------------------------------------------------------------------------
  4809. void ScriptActions::doTeamUseCommandButtonOnNearestGarrisonedBuilding( const AsciiString& teamName, const AsciiString& commandAbility )
  4810. {
  4811. Team *team = TheScriptEngine->getTeamNamed(teamName);
  4812. if (!team) {
  4813. return;
  4814. }
  4815. AIGroup *theGroup = TheAI->createGroup();
  4816. team->getTeamAsAIGroup(theGroup);
  4817. const CommandButton *commandButton = TheControlBar->findCommandButton(commandAbility);
  4818. if(!commandButton) {
  4819. return;
  4820. }
  4821. Object *srcObj = NULL;
  4822. if (commandButton->getSpecialPowerTemplate()) {
  4823. srcObj = theGroup->getSpecialPowerSourceObject(commandButton->getSpecialPowerTemplate()->getID());
  4824. } else {
  4825. srcObj = theGroup->getCommandButtonSourceObject(commandButton->getCommandType());
  4826. }
  4827. if (!srcObj) {
  4828. return;
  4829. }
  4830. PartitionFilterPlayerAffiliation f1(team->getControllingPlayer(), ALLOW_ENEMIES, true);
  4831. PartitionFilterAcceptByKindOf f2(MAKE_KINDOF_MASK(KINDOF_STRUCTURE), KINDOFMASK_NONE);
  4832. PartitionFilterGarrisonable f3(true);
  4833. PartitionFilterValidCommandButtonTarget f4(srcObj, commandButton, true, CMD_FROM_SCRIPT);
  4834. PartitionFilterSameMapStatus filterMapStatus(srcObj);
  4835. Coord3D pos;
  4836. theGroup->getCenter(&pos);
  4837. PartitionFilter *filters[] = { &f1, &f2, &f3, &f4, &filterMapStatus, 0 };
  4838. Object *obj = ThePartitionManager->getClosestObject(&pos, REALLY_FAR, FROM_CENTER_2D, filters);
  4839. if (!obj) {
  4840. return;
  4841. }
  4842. // already been checked for validity
  4843. theGroup->groupDoCommandButtonAtObject(commandButton, obj, CMD_FROM_SCRIPT);
  4844. }
  4845. //-------------------------------------------------------------------------------------------------
  4846. /** doTeamUseCommandButtonOnNearestKindof */
  4847. //-------------------------------------------------------------------------------------------------
  4848. void ScriptActions::doTeamUseCommandButtonOnNearestKindof( const AsciiString& teamName, const AsciiString& commandAbility, Int kindofBit )
  4849. {
  4850. Team *team = TheScriptEngine->getTeamNamed(teamName);
  4851. if (!team) {
  4852. return;
  4853. }
  4854. AIGroup *theGroup = TheAI->createGroup();
  4855. team->getTeamAsAIGroup(theGroup);
  4856. const CommandButton *commandButton = TheControlBar->findCommandButton(commandAbility);
  4857. if (!commandButton) {
  4858. return;
  4859. }
  4860. Object *srcObj = NULL;
  4861. if (commandButton->getSpecialPowerTemplate()) {
  4862. srcObj = theGroup->getSpecialPowerSourceObject(commandButton->getSpecialPowerTemplate()->getID());
  4863. } else {
  4864. srcObj = theGroup->getCommandButtonSourceObject(commandButton->getCommandType());
  4865. }
  4866. if (!srcObj) {
  4867. return;
  4868. }
  4869. PartitionFilterPlayerAffiliation f1(team->getControllingPlayer(), ALLOW_ENEMIES, true);
  4870. PartitionFilterAcceptByKindOf f2(MAKE_KINDOF_MASK(kindofBit), KINDOFMASK_NONE);
  4871. PartitionFilterValidCommandButtonTarget f3(srcObj, commandButton, true, CMD_FROM_SCRIPT);
  4872. PartitionFilterSameMapStatus filterMapStatus(srcObj);
  4873. Coord3D pos;
  4874. theGroup->getCenter(&pos);
  4875. PartitionFilter *filters[] = { &f1, &f2, &f3, &filterMapStatus, 0 };
  4876. Object *obj = ThePartitionManager->getClosestObject(&pos, REALLY_FAR, FROM_CENTER_2D, filters);
  4877. if (!obj) {
  4878. return;
  4879. }
  4880. // already been checked for validity
  4881. theGroup->groupDoCommandButtonAtObject(commandButton, obj, CMD_FROM_SCRIPT);
  4882. }
  4883. //-------------------------------------------------------------------------------------------------
  4884. /** doTeamUseCommandButtonOnNearestBuilding */
  4885. //-------------------------------------------------------------------------------------------------
  4886. void ScriptActions::doTeamUseCommandButtonOnNearestBuilding( const AsciiString& teamName, const AsciiString& commandAbility )
  4887. {
  4888. Team *team = TheScriptEngine->getTeamNamed(teamName);
  4889. if (!team) {
  4890. return;
  4891. }
  4892. AIGroup *theGroup = TheAI->createGroup();
  4893. team->getTeamAsAIGroup(theGroup);
  4894. const CommandButton *commandButton = TheControlBar->findCommandButton(commandAbility);
  4895. if (!commandButton) {
  4896. return;
  4897. }
  4898. Object *srcObj = NULL;
  4899. if (commandButton->getSpecialPowerTemplate()) {
  4900. srcObj = theGroup->getSpecialPowerSourceObject(commandButton->getSpecialPowerTemplate()->getID());
  4901. } else {
  4902. srcObj = theGroup->getCommandButtonSourceObject(commandButton->getCommandType());
  4903. }
  4904. if (!srcObj) {
  4905. return;
  4906. }
  4907. PartitionFilterPlayerAffiliation f1(team->getControllingPlayer(), ALLOW_ENEMIES, true);
  4908. PartitionFilterAcceptByKindOf f2(MAKE_KINDOF_MASK(KINDOF_STRUCTURE), KINDOFMASK_NONE);
  4909. PartitionFilterValidCommandButtonTarget f3(srcObj, commandButton, true, CMD_FROM_SCRIPT);
  4910. PartitionFilterSameMapStatus filterMapStatus(srcObj);
  4911. Coord3D pos;
  4912. theGroup->getCenter(&pos);
  4913. PartitionFilter *filters[] = { &f1, &f2, &f3, &filterMapStatus, 0 };
  4914. Object *obj = ThePartitionManager->getClosestObject(&pos, REALLY_FAR, FROM_CENTER_2D, filters);
  4915. if (!obj) {
  4916. return;
  4917. }
  4918. // already been checked for validity
  4919. theGroup->groupDoCommandButtonAtObject(commandButton, obj, CMD_FROM_SCRIPT);
  4920. }
  4921. //-------------------------------------------------------------------------------------------------
  4922. /** doTeamUseCommandButtonOnNearestBuildingClass */
  4923. //-------------------------------------------------------------------------------------------------
  4924. void ScriptActions::doTeamUseCommandButtonOnNearestBuildingClass( const AsciiString& teamName, const AsciiString& commandAbility, Int kindofBit )
  4925. {
  4926. Team *team = TheScriptEngine->getTeamNamed(teamName);
  4927. if (!team) {
  4928. return;
  4929. }
  4930. AIGroup *theGroup = TheAI->createGroup();
  4931. team->getTeamAsAIGroup(theGroup);
  4932. const CommandButton *commandButton = TheControlBar->findCommandButton(commandAbility);
  4933. if (!commandButton) {
  4934. return;
  4935. }
  4936. Object *srcObj = NULL;
  4937. if (commandButton->getSpecialPowerTemplate()) {
  4938. srcObj = theGroup->getSpecialPowerSourceObject(commandButton->getSpecialPowerTemplate()->getID());
  4939. } else {
  4940. srcObj = theGroup->getCommandButtonSourceObject(commandButton->getCommandType());
  4941. }
  4942. if (!srcObj) {
  4943. return;
  4944. }
  4945. PartitionFilterPlayerAffiliation f1(team->getControllingPlayer(), ALLOW_ENEMIES, true);
  4946. PartitionFilterAcceptByKindOf f2(MAKE_KINDOF_MASK(KINDOF_STRUCTURE), KINDOFMASK_NONE);
  4947. PartitionFilterAcceptByKindOf f3(MAKE_KINDOF_MASK(kindofBit), KINDOFMASK_NONE);
  4948. PartitionFilterValidCommandButtonTarget f4(srcObj, commandButton, true, CMD_FROM_SCRIPT);
  4949. PartitionFilterSameMapStatus filterMapStatus(srcObj);
  4950. Coord3D pos;
  4951. theGroup->getCenter(&pos);
  4952. PartitionFilter *filters[] = { &f1, &f2, &f3, &f4, &filterMapStatus, 0 };
  4953. Object *obj = ThePartitionManager->getClosestObject(&pos, REALLY_FAR, FROM_CENTER_2D, filters);
  4954. if (!obj) {
  4955. return;
  4956. }
  4957. // already been checked for validity
  4958. theGroup->groupDoCommandButtonAtObject(commandButton, obj, CMD_FROM_SCRIPT);
  4959. }
  4960. //-------------------------------------------------------------------------------------------------
  4961. /** doTeamUseCommandButtonOnNearestObjectType */
  4962. //-------------------------------------------------------------------------------------------------
  4963. void ScriptActions::doTeamUseCommandButtonOnNearestObjectType( const AsciiString& teamName, const AsciiString& commandAbility, const AsciiString& objectType )
  4964. {
  4965. Team *team = TheScriptEngine->getTeamNamed(teamName);
  4966. if (!team) {
  4967. return;
  4968. }
  4969. AIGroup *theGroup = TheAI->createGroup();
  4970. team->getTeamAsAIGroup(theGroup);
  4971. const CommandButton *commandButton = TheControlBar->findCommandButton(commandAbility);
  4972. if (!commandButton) {
  4973. return;
  4974. }
  4975. Object *srcObj = NULL;
  4976. if (commandButton->getSpecialPowerTemplate()) {
  4977. srcObj = theGroup->getSpecialPowerSourceObject(commandButton->getSpecialPowerTemplate()->getID());
  4978. } else {
  4979. srcObj = theGroup->getCommandButtonSourceObject(commandButton->getCommandType());
  4980. }
  4981. if (!srcObj) {
  4982. return;
  4983. }
  4984. Object *bestObj = NULL;
  4985. //First look for a specific object type (object lists will fail)
  4986. const ThingTemplate *thingTemplate = TheThingFactory->findTemplate( objectType, FALSE );
  4987. if( thingTemplate )
  4988. {
  4989. PartitionFilterPlayerAffiliation f1(team->getControllingPlayer(), ALLOW_ENEMIES | ALLOW_NEUTRAL, true);
  4990. PartitionFilterThing f2(thingTemplate, true);
  4991. PartitionFilterValidCommandButtonTarget f3(srcObj, commandButton, true, CMD_FROM_SCRIPT);
  4992. PartitionFilterSameMapStatus filterMapStatus(srcObj);
  4993. PartitionFilter *filters[] = { &f1, &f2, &f3, &filterMapStatus, 0 };
  4994. Coord3D pos;
  4995. theGroup->getCenter(&pos);
  4996. bestObj = ThePartitionManager->getClosestObject(&pos, REALLY_FAR, FROM_CENTER_2D, filters);
  4997. if( !bestObj )
  4998. {
  4999. return;
  5000. }
  5001. }
  5002. else
  5003. {
  5004. ObjectTypes *objectTypes = TheScriptEngine->getObjectTypes( objectType );
  5005. if( objectTypes )
  5006. {
  5007. PartitionFilterPlayerAffiliation f1(team->getControllingPlayer(), ALLOW_ENEMIES | ALLOW_NEUTRAL, true);
  5008. PartitionFilterValidCommandButtonTarget f3(srcObj, commandButton, true, CMD_FROM_SCRIPT);
  5009. PartitionFilterSameMapStatus f4(srcObj);
  5010. Coord3D pos;
  5011. theGroup->getCenter(&pos);
  5012. Real closestDist;
  5013. Real dist;
  5014. for( Int typeIndex = 0; typeIndex < objectTypes->getListSize(); typeIndex++ )
  5015. {
  5016. AsciiString thisTypeName = objectTypes->getNthInList( typeIndex );
  5017. const ThingTemplate *thisType = TheThingFactory->findTemplate( thisTypeName );
  5018. if( thisType )
  5019. {
  5020. PartitionFilterThing f2( thisType, true );
  5021. PartitionFilter *filters[] = { &f1, &f2, &f3, &f4, 0 };
  5022. Object *obj = ThePartitionManager->getClosestObject(&pos, REALLY_FAR, FROM_CENTER_2D, filters, &dist );
  5023. if( obj )
  5024. {
  5025. if( !bestObj || dist < closestDist )
  5026. {
  5027. bestObj = obj;
  5028. closestDist = dist;
  5029. }
  5030. }
  5031. }
  5032. }
  5033. }
  5034. }
  5035. // already been checked for validity
  5036. theGroup->groupDoCommandButtonAtObject(commandButton, bestObj, CMD_FROM_SCRIPT);
  5037. }
  5038. //-------------------------------------------------------------------------------------------------
  5039. /** doTeamPartialUseCommandButton */
  5040. //-------------------------------------------------------------------------------------------------
  5041. void ScriptActions::doTeamPartialUseCommandButton( Real percentage, const AsciiString& teamName, const AsciiString& commandAbility )
  5042. {
  5043. Team *team = TheScriptEngine->getTeamNamed(teamName);
  5044. if (!team) {
  5045. return;
  5046. }
  5047. const CommandButton *commandButton = TheControlBar->findCommandButton(commandAbility);
  5048. if (!commandButton) {
  5049. return;
  5050. }
  5051. std::vector<Object *> objList;
  5052. DLINK_ITERATOR<Object> iter = team->iterate_TeamMemberList();
  5053. for (iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance()) {
  5054. Object *obj = iter.cur();
  5055. if (commandButton->isValidToUseOn(obj, NULL, NULL, CMD_FROM_SCRIPT)) {
  5056. objList.push_back(obj);
  5057. }
  5058. }
  5059. Int numObjs = /*REAL_TO_INT_CEIL*/(percentage / 100.0f * objList.size());
  5060. Int count = 0;
  5061. for (std::vector<Object*>::const_iterator it = objList.begin(); it != objList.end(); ++it)
  5062. {
  5063. Object *obj = (*it);
  5064. if (count >= numObjs)
  5065. return;
  5066. obj->doCommandButton(commandButton, CMD_FROM_SCRIPT);
  5067. ++count;
  5068. }
  5069. }
  5070. //-------------------------------------------------------------------------------------------------
  5071. /** doTeamCaptureNearestUnownedFactionUnit */
  5072. //-------------------------------------------------------------------------------------------------
  5073. void ScriptActions::doTeamCaptureNearestUnownedFactionUnit( const AsciiString& teamName )
  5074. {
  5075. Team *team = TheScriptEngine->getTeamNamed(teamName);
  5076. if (!team) {
  5077. return;
  5078. }
  5079. AIGroup *theGroup = TheAI->createGroup();
  5080. team->getTeamAsAIGroup(theGroup);
  5081. PartitionFilterPlayerAffiliation f1(team->getControllingPlayer(), ALLOW_ENEMIES | ALLOW_NEUTRAL, true);
  5082. PartitionFilterUnmannedObject f2(true);
  5083. PartitionFilterOnMap filterMapStatus;
  5084. Coord3D pos;
  5085. theGroup->getCenter(&pos);
  5086. PartitionFilter *filters[] = { &f1, &f2, &filterMapStatus, 0 };
  5087. Object *obj = ThePartitionManager->getClosestObject(&pos, REALLY_FAR, FROM_CENTER_2D, filters);
  5088. if (!obj) {
  5089. return;
  5090. }
  5091. theGroup->groupEnter(obj, CMD_FROM_SCRIPT);
  5092. }
  5093. //-------------------------------------------------------------------------------------------------
  5094. /** doCreateTeamFromCapturedUnits */
  5095. //-------------------------------------------------------------------------------------------------
  5096. void ScriptActions::doCreateTeamFromCapturedUnits( const AsciiString& playerName, const AsciiString& teamName )
  5097. {
  5098. Team *team = TheScriptEngine->getTeamNamed(teamName);
  5099. if (!team) {
  5100. return;
  5101. }
  5102. }
  5103. //-------------------------------------------------------------------------------------------------
  5104. void ScriptActions::doPlayerAddSkillPoints(const AsciiString& playerName, Int delta)
  5105. {
  5106. Player* pPlayer = TheScriptEngine->getPlayerFromAsciiString(playerName);
  5107. if (!pPlayer)
  5108. return;
  5109. pPlayer->addSkillPoints(delta);
  5110. }
  5111. //-------------------------------------------------------------------------------------------------
  5112. void ScriptActions::doPlayerAddRankLevels(const AsciiString& playerName, Int delta)
  5113. {
  5114. Player* pPlayer = TheScriptEngine->getPlayerFromAsciiString(playerName);
  5115. if (!pPlayer)
  5116. return;
  5117. pPlayer->setRankLevel(pPlayer->getRankLevel() + delta);
  5118. }
  5119. //-------------------------------------------------------------------------------------------------
  5120. void ScriptActions::doPlayerSetRankLevel(const AsciiString& playerName, Int level)
  5121. {
  5122. Player* pPlayer = TheScriptEngine->getPlayerFromAsciiString(playerName);
  5123. if (!pPlayer)
  5124. return;
  5125. pPlayer->setRankLevel(level);
  5126. }
  5127. //-------------------------------------------------------------------------------------------------
  5128. void ScriptActions::doMapSetRankLevelLimit(Int level)
  5129. {
  5130. if (TheGameLogic)
  5131. TheGameLogic->setRankLevelLimit(level);
  5132. }
  5133. //-------------------------------------------------------------------------------------------------
  5134. void ScriptActions::doPlayerGrantScience(const AsciiString& playerName, const AsciiString& scienceName)
  5135. {
  5136. Player* pPlayer = TheScriptEngine->getPlayerFromAsciiString(playerName);
  5137. if (!pPlayer)
  5138. return;
  5139. ScienceType science = TheScienceStore->getScienceFromInternalName(scienceName);
  5140. if (science == SCIENCE_INVALID)
  5141. return;
  5142. pPlayer->grantScience(science);
  5143. }
  5144. //-------------------------------------------------------------------------------------------------
  5145. void ScriptActions::doPlayerPurchaseScience(const AsciiString& playerName, const AsciiString& scienceName)
  5146. {
  5147. Player* pPlayer = TheScriptEngine->getPlayerFromAsciiString(playerName);
  5148. if (!pPlayer)
  5149. return;
  5150. ScienceType science = TheScienceStore->getScienceFromInternalName(scienceName);
  5151. if (science == SCIENCE_INVALID)
  5152. return;
  5153. pPlayer->attemptToPurchaseScience(science);
  5154. }
  5155. //-------------------------------------------------------------------------------------------------
  5156. void ScriptActions::doPlayerSetScienceAvailability( const AsciiString& playerName, const AsciiString& scienceName, const AsciiString& scienceAvailability )
  5157. {
  5158. Player* player = TheScriptEngine->getPlayerFromAsciiString(playerName);
  5159. if( player )
  5160. {
  5161. ScienceAvailabilityType saType = player->getScienceAvailabilityTypeFromString( scienceAvailability );
  5162. if( saType != SCIENCE_AVAILABILITY_INVALID )
  5163. {
  5164. ScienceType science = TheScienceStore->getScienceFromInternalName( scienceName );
  5165. if( science != SCIENCE_INVALID )
  5166. {
  5167. player->setScienceAvailability( science, saType );
  5168. }
  5169. }
  5170. }
  5171. }
  5172. //-------------------------------------------------------------------------------------------------
  5173. void ScriptActions::doTeamEmoticon(const AsciiString& teamName, const AsciiString& emoticonName, Real duration)
  5174. {
  5175. Team *theTeam = TheScriptEngine->getTeamNamed( teamName );
  5176. if( !theTeam )
  5177. {
  5178. return;
  5179. }
  5180. AIGroup* theGroup = TheAI->createGroup();
  5181. if( !theGroup )
  5182. {
  5183. return;
  5184. }
  5185. theTeam->getTeamAsAIGroup( theGroup );
  5186. Int frames = (Int)( duration * LOGICFRAMES_PER_SECOND );
  5187. theGroup->groupSetEmoticon( emoticonName, frames );
  5188. }
  5189. //-------------------------------------------------------------------------------------------------
  5190. void ScriptActions::doNamedEmoticon(const AsciiString& unitName, const AsciiString& emoticonName, Real duration)
  5191. {
  5192. Object *obj = TheScriptEngine->getUnitNamed( unitName );
  5193. if( obj )
  5194. {
  5195. Drawable *draw = obj->getDrawable();
  5196. if( draw )
  5197. {
  5198. Int frames = (Int)( duration * LOGICFRAMES_PER_SECOND );
  5199. draw->setEmoticon( emoticonName, frames );
  5200. }
  5201. }
  5202. }
  5203. //-------------------------------------------------------------------------------------------------
  5204. // if addObject, we're adding an object to a list. If not addObject, we're removing the associated
  5205. // object.
  5206. //-------------------------------------------------------------------------------------------------
  5207. void ScriptActions::doObjectTypeListMaintenance(const AsciiString& objectList, const AsciiString& objectType, Bool addObject)
  5208. {
  5209. TheScriptEngine->doObjectTypeListMaintenance( objectList, objectType, addObject );
  5210. }
  5211. //-------------------------------------------------------------------------------------------------
  5212. void ScriptActions::doRevealMapAtWaypointPermanent(const AsciiString& waypointName, Real radiusToReveal, const AsciiString& playerName, const AsciiString& lookName)
  5213. {
  5214. TheScriptEngine->createNamedMapReveal(lookName, waypointName, radiusToReveal, playerName);
  5215. TheScriptEngine->doNamedMapReveal(lookName);
  5216. }
  5217. //-------------------------------------------------------------------------------------------------
  5218. void ScriptActions::doUndoRevealMapAtWaypointPermanent(const AsciiString& lookName)
  5219. {
  5220. TheScriptEngine->undoNamedMapReveal(lookName);
  5221. TheScriptEngine->removeNamedMapReveal(lookName);
  5222. }
  5223. //-------------------------------------------------------------------------------------------------
  5224. void ScriptActions::doEvaEnabledDisabled(Bool setEnabled)
  5225. {
  5226. TheEva->setEvaEnabled(setEnabled);
  5227. }
  5228. //-------------------------------------------------------------------------------------------------
  5229. void ScriptActions::doSetOcclusionMode(Bool setEnabled)
  5230. {
  5231. TheGameLogic->setShowBehindBuildingMarkers(setEnabled);
  5232. }
  5233. //-------------------------------------------------------------------------------------------------
  5234. void ScriptActions::doSetDrawIconUIMode(Bool setEnabled)
  5235. {
  5236. TheGameLogic->setDrawIconUI(setEnabled);
  5237. }
  5238. //-------------------------------------------------------------------------------------------------
  5239. void ScriptActions::doSetDynamicLODMode(Bool setEnabled)
  5240. {
  5241. TheGameLogic->setShowDynamicLOD(setEnabled);
  5242. }
  5243. //-------------------------------------------------------------------------------------------------
  5244. void ScriptActions::doOverrideHulkLifetime( Real seconds )
  5245. {
  5246. if( seconds < 0.0f )
  5247. {
  5248. // Turn it off.
  5249. TheGameLogic->setHulkMaxLifetimeOverride(-1);
  5250. }
  5251. else
  5252. {
  5253. // Convert real seconds into frames.
  5254. Int frames = (Int)(seconds * LOGICFRAMES_PER_SECOND);
  5255. TheGameLogic->setHulkMaxLifetimeOverride(frames);
  5256. }
  5257. }
  5258. //-------------------------------------------------------------------------------------------------
  5259. // MBL CNC3 INCURSION - This is to Have Max camera animation playback
  5260. //
  5261. void ScriptActions::doC3CameraEnableSlaveMode
  5262. (
  5263. const AsciiString& thingTemplateName,
  5264. const AsciiString& boneName
  5265. )
  5266. {
  5267. TheTacticalView->cameraEnableSlaveMode( thingTemplateName, boneName );
  5268. }
  5269. //-------------------------------------------------------------------------------------------------
  5270. void ScriptActions::doC3CameraDisableSlaveMode( void )
  5271. {
  5272. TheTacticalView->cameraDisableSlaveMode();
  5273. }
  5274. //-------------------------------------------------------------------------------------------------
  5275. // WST 11.12.2002 CNC3 INCURSION - This is for New Camera Shake
  5276. //
  5277. void ScriptActions::doC3CameraShake
  5278. (
  5279. const AsciiString &waypointName,
  5280. const Real amplitude,
  5281. const Real duration_seconds,
  5282. const Real radius
  5283. )
  5284. {
  5285. Waypoint *way = TheTerrainLogic->getWaypointByName(waypointName);
  5286. DEBUG_ASSERTLOG( (way != NULL), ("Camera shake with No Valid Waypoint\n") );
  5287. Coord3D pos = *way->getLocation();
  5288. TheTacticalView->Add_Camera_Shake(pos, radius, duration_seconds, amplitude);
  5289. }
  5290. //-------------------------------------------------------------------------------------------------
  5291. void ScriptActions::doNamedFaceNamed( const AsciiString &unitName, const AsciiString &faceUnitName )
  5292. {
  5293. Object *obj = TheScriptEngine->getUnitNamed( unitName );
  5294. if( obj )
  5295. {
  5296. Object *faceObj = TheScriptEngine->getUnitNamed( faceUnitName );
  5297. if( faceObj )
  5298. {
  5299. AIUpdateInterface *ai = obj->getAI();
  5300. if( ai )
  5301. {
  5302. ai->clearWaypointQueue();
  5303. obj->leaveGroup();
  5304. ai->chooseLocomotorSet( LOCOMOTORSET_NORMAL );
  5305. ai->aiFaceObject( faceObj, CMD_FROM_SCRIPT );
  5306. }
  5307. }
  5308. }
  5309. }
  5310. //-------------------------------------------------------------------------------------------------
  5311. void ScriptActions::doNamedFaceWaypoint( const AsciiString &unitName, const AsciiString &faceWaypointName )
  5312. {
  5313. Object *obj = TheScriptEngine->getUnitNamed( unitName );
  5314. if( obj )
  5315. {
  5316. Waypoint *way = TheTerrainLogic->getWaypointByName( faceWaypointName );
  5317. if( way )
  5318. {
  5319. AIUpdateInterface *ai = obj->getAI();
  5320. if( ai )
  5321. {
  5322. ai->clearWaypointQueue();
  5323. obj->leaveGroup();
  5324. ai->chooseLocomotorSet( LOCOMOTORSET_NORMAL );
  5325. ai->aiFacePosition( way->getLocation(), CMD_FROM_SCRIPT );
  5326. }
  5327. }
  5328. }
  5329. }
  5330. //-------------------------------------------------------------------------------------------------
  5331. void ScriptActions::doTeamFaceNamed( const AsciiString &teamName, const AsciiString &faceUnitName )
  5332. {
  5333. Team *team = TheScriptEngine->getTeamNamed(teamName);
  5334. if( team )
  5335. {
  5336. Object *faceObj = TheScriptEngine->getUnitNamed( faceUnitName );
  5337. if( faceObj )
  5338. {
  5339. DLINK_ITERATOR<Object> iter = team->iterate_TeamMemberList();
  5340. for( iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance() )
  5341. {
  5342. Object *obj = iter.cur();
  5343. if( obj )
  5344. {
  5345. AIUpdateInterface *ai = obj->getAI();
  5346. if( ai )
  5347. {
  5348. ai->clearWaypointQueue();
  5349. obj->leaveGroup();
  5350. ai->chooseLocomotorSet( LOCOMOTORSET_NORMAL );
  5351. ai->aiFaceObject( faceObj, CMD_FROM_SCRIPT );
  5352. }
  5353. }
  5354. }
  5355. }
  5356. }
  5357. }
  5358. //-------------------------------------------------------------------------------------------------
  5359. void ScriptActions::doTeamFaceWaypoint( const AsciiString &teamName, const AsciiString &faceWaypointName )
  5360. {
  5361. Team *team = TheScriptEngine->getTeamNamed(teamName);
  5362. if( team )
  5363. {
  5364. Waypoint *way = TheTerrainLogic->getWaypointByName( faceWaypointName );
  5365. if( way )
  5366. {
  5367. DLINK_ITERATOR<Object> iter = team->iterate_TeamMemberList();
  5368. for( iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance() )
  5369. {
  5370. Object *obj = iter.cur();
  5371. if( obj )
  5372. {
  5373. AIUpdateInterface *ai = obj->getAI();
  5374. if( ai )
  5375. {
  5376. ai->clearWaypointQueue();
  5377. obj->leaveGroup();
  5378. ai->chooseLocomotorSet( LOCOMOTORSET_NORMAL );
  5379. ai->aiFacePosition( way->getLocation(), CMD_FROM_SCRIPT );
  5380. }
  5381. }
  5382. }
  5383. }
  5384. }
  5385. }
  5386. //-------------------------------------------------------------------------------------------------
  5387. void ScriptActions::doAffectObjectPanelFlagsUnit(const AsciiString& unitName, const AsciiString& flagName, Bool enable)
  5388. {
  5389. Object *obj = TheScriptEngine->getUnitNamed( unitName );
  5390. if (!obj) {
  5391. return;
  5392. }
  5393. changeObjectPanelFlagForSingleObject(obj, flagName, enable);
  5394. }
  5395. //-------------------------------------------------------------------------------------------------
  5396. void ScriptActions::doAffectObjectPanelFlagsTeam(const AsciiString& teamName, const AsciiString& flagName, Bool enable)
  5397. {
  5398. Team *team = TheScriptEngine->getTeamNamed(teamName);
  5399. if (!team) {
  5400. return;
  5401. }
  5402. DLINK_ITERATOR<Object> iter = team->iterate_TeamMemberList();
  5403. for (iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance()) {
  5404. Object *obj = iter.cur();
  5405. changeObjectPanelFlagForSingleObject(obj, flagName, enable);
  5406. }
  5407. }
  5408. //-------------------------------------------------------------------------------------------------
  5409. void ScriptActions::doAffectPlayerSkillset(const AsciiString& playerName, Int skillset)
  5410. {
  5411. Player *player = TheScriptEngine->getPlayerFromAsciiString(playerName);
  5412. if (!player) {
  5413. return;
  5414. }
  5415. --skillset;
  5416. player->friend_setSkillset(skillset);
  5417. }
  5418. //-------------------------------------------------------------------------------------------------
  5419. void ScriptActions::doGuardSupplyCenter(const AsciiString& teamName, Int supplies)
  5420. {
  5421. Team *team = TheScriptEngine->getTeamNamed(teamName);
  5422. if (!team) {
  5423. return;
  5424. }
  5425. Player *player = team->getControllingPlayer();
  5426. if (!player) {
  5427. return;
  5428. }
  5429. player->guardSupplyCenter(team, supplies);
  5430. }
  5431. //-------------------------------------------------------------------------------------------------
  5432. void ScriptActions::doTeamGuardInTunnelNetwork(const AsciiString& teamName)
  5433. {
  5434. Team *team = TheScriptEngine->getTeamNamed(teamName);
  5435. if (!team) {
  5436. return;
  5437. }
  5438. // Have all the members of the team guard at a tunnel network.
  5439. for (DLINK_ITERATOR<Object> iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance())
  5440. {
  5441. Object *obj = iter.cur();
  5442. AIUpdateInterface *ai = obj->getAIUpdateInterface();
  5443. if (!ai) {
  5444. continue;
  5445. }
  5446. ai->aiGuardTunnelNetwork(GUARDMODE_NORMAL, CMD_FROM_SCRIPT);
  5447. }
  5448. }
  5449. //-------------------------------------------------------------------------------------------------
  5450. void ScriptActions::doRemoveCommandBarButton(const AsciiString& buttonName, const AsciiString& objectType)
  5451. {
  5452. const ThingTemplate *templ = TheThingFactory->findTemplate(objectType);
  5453. if (!templ) {
  5454. return;
  5455. }
  5456. const CommandSet *cs = TheControlBar->findCommandSet(templ->friend_getCommandSetString());
  5457. if (!cs) {
  5458. return;
  5459. }
  5460. Int slotNum = -1;
  5461. for (Int i = 0; i < MAX_COMMANDS_PER_SET; ++i)
  5462. {
  5463. if (cs->getCommandButton(i) && (cs->getCommandButton(i)->getName() == buttonName))
  5464. {
  5465. slotNum = i;
  5466. break;
  5467. }
  5468. }
  5469. if (slotNum >= 0)
  5470. {
  5471. TheGameLogic->setControlBarOverride(templ->friend_getCommandSetString(), slotNum, NULL);
  5472. }
  5473. }
  5474. //-------------------------------------------------------------------------------------------------
  5475. void ScriptActions::doAddCommandBarButton(const AsciiString& buttonName, const AsciiString& objectType, Int slotNum)
  5476. {
  5477. const ThingTemplate *templ = TheThingFactory->findTemplate(objectType);
  5478. if (!templ) {
  5479. return;
  5480. }
  5481. const CommandButton *commandButton = TheControlBar->findCommandButton( buttonName );
  5482. if (commandButton == NULL)
  5483. {
  5484. // not here. use doRemoveCommandBarButton to remove one.
  5485. return;
  5486. }
  5487. // decrement it, so we can present it as 1-12 for the designers.
  5488. --slotNum;
  5489. if (slotNum < 0 || slotNum >= MAX_COMMANDS_PER_SET)
  5490. return;
  5491. TheGameLogic->setControlBarOverride(templ->friend_getCommandSetString(), slotNum, commandButton);
  5492. }
  5493. //-------------------------------------------------------------------------------------------------
  5494. void ScriptActions::doAffectSkillPointsModifier(const AsciiString& playerName, Real newModifier)
  5495. {
  5496. Player *playerDst = TheScriptEngine->getPlayerFromAsciiString(playerName);
  5497. if (!playerDst) {
  5498. return;
  5499. }
  5500. playerDst->setSkillPointsModifier(newModifier);
  5501. }
  5502. //-------------------------------------------------------------------------------------------------
  5503. void ScriptActions::doResizeViewGuardband(const Real gbx, const Real gby)
  5504. {
  5505. Coord2D newGuardBand = { gbx, gby };
  5506. TheTacticalView->setGuardBandBias( &newGuardBand );
  5507. }
  5508. //-------------------------------------------------------------------------------------------------
  5509. void ScriptActions::deleteAllUnmanned()
  5510. {
  5511. Object *obj = TheGameLogic->getFirstObject();
  5512. while (obj) {
  5513. if (obj->isDisabledByType(DISABLED_UNMANNED))
  5514. TheGameLogic->destroyObject(obj);
  5515. obj = obj->getNextObject();
  5516. }
  5517. }
  5518. //-------------------------------------------------------------------------------------------------
  5519. void ScriptActions::doEnableOrDisableObjectDifficultyBonuses(Bool enableBonuses)
  5520. {
  5521. // Loops over every object in the game, applying bonuses or not.
  5522. Object *obj = TheGameLogic->getFirstObject();
  5523. while (obj) {
  5524. obj->setReceivingDifficultyBonus(enableBonuses);
  5525. obj = obj->getNextObject();
  5526. }
  5527. // notify the script engine of our decision
  5528. TheScriptEngine->setObjectsShouldReceiveDifficultyBonus(enableBonuses);
  5529. }
  5530. //-------------------------------------------------------------------------------------------------
  5531. void ScriptActions::doChooseVictimAlwaysUsesNormal(Bool enable)
  5532. {
  5533. TheScriptEngine->setChooseVictimAlwaysUsesNormal(enable);
  5534. }
  5535. //-------------------------------------------------------------------------------------------------
  5536. void ScriptActions::doNamedSetTrainHeld( const AsciiString &locoName, const Bool set )
  5537. {
  5538. Object *obj = TheScriptEngine->getUnitNamed( locoName );
  5539. if( obj )
  5540. {
  5541. static const NameKeyType rrkey = NAMEKEY( "RailroadBehavior" );
  5542. RailroadBehavior *rBehavior = (RailroadBehavior*)obj->findUpdateModule( rrkey );
  5543. if ( rBehavior )
  5544. {
  5545. rBehavior->RailroadBehavior::setHeld( set );
  5546. }
  5547. }
  5548. }
  5549. //-------------------------------------------------------------------------------------------------
  5550. /** Execute an action */
  5551. //-------------------------------------------------------------------------------------------------
  5552. void ScriptActions::executeAction( ScriptAction *pAction )
  5553. {
  5554. switch (pAction->getActionType()) {
  5555. default:
  5556. DEBUG_CRASH(("Unknown ScriptAction type %d", pAction->getActionType())); return;
  5557. case ScriptAction::DEBUG_MESSAGE_BOX:
  5558. doDebugMessage(pAction->getParameter(0)->getString(), true);
  5559. return;
  5560. case ScriptAction::DEBUG_STRING:
  5561. doDebugMessage(pAction->getParameter(0)->getString(), false);
  5562. return;
  5563. case ScriptAction::DAMAGE_MEMBERS_OF_TEAM:
  5564. doDamageTeamMembers(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getReal());
  5565. return;
  5566. case ScriptAction::MOVE_TEAM_TO:
  5567. doMoveToWaypoint(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5568. return;
  5569. case ScriptAction::MOVE_NAMED_UNIT_TO:
  5570. doNamedMoveToWaypoint(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5571. return;
  5572. case ScriptAction::TEAM_SET_STATE:
  5573. doSetTeamState(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5574. return;
  5575. case ScriptAction::TEAM_FOLLOW_WAYPOINTS:
  5576. doTeamFollowWaypoints(pAction->getParameter(0)->getString(),
  5577. pAction->getParameter(1)->getString(),
  5578. pAction->getParameter(2)->getInt());
  5579. return;
  5580. case ScriptAction::TEAM_FOLLOW_WAYPOINTS_EXACT:
  5581. doTeamFollowWaypointsExact(pAction->getParameter(0)->getString(),
  5582. pAction->getParameter(1)->getString(),
  5583. pAction->getParameter(2)->getInt());
  5584. return;
  5585. case ScriptAction::NAMED_FOLLOW_WAYPOINTS_EXACT:
  5586. doNamedFollowWaypointsExact(pAction->getParameter(0)->getString(),
  5587. pAction->getParameter(1)->getString());
  5588. return;
  5589. case ScriptAction::SKIRMISH_FOLLOW_APPROACH_PATH:
  5590. doTeamFollowSkirmishApproachPath(pAction->getParameter(0)->getString(),
  5591. pAction->getParameter(1)->getString(),
  5592. pAction->getParameter(2)->getInt());
  5593. return;
  5594. case ScriptAction::SKIRMISH_MOVE_TO_APPROACH_PATH:
  5595. doTeamMoveToSkirmishApproachPath(pAction->getParameter(0)->getString(),
  5596. pAction->getParameter(1)->getString());
  5597. return;
  5598. case ScriptAction::CREATE_REINFORCEMENT_TEAM:
  5599. doCreateReinforcements(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5600. return;
  5601. case ScriptAction::SKIRMISH_BUILD_BUILDING:
  5602. doBuildBuilding(pAction->getParameter(0)->getString());
  5603. return;
  5604. case ScriptAction::AI_PLAYER_BUILD_SUPPLY_CENTER:
  5605. doBuildSupplyCenter(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getInt());
  5606. return;
  5607. case ScriptAction::AI_PLAYER_BUILD_TYPE_NEAREST_TEAM:
  5608. doBuildObjectNearestTeam( pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getString() );
  5609. return;
  5610. case ScriptAction::AI_PLAYER_BUILD_UPGRADE:
  5611. doBuildUpgrade(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5612. return;
  5613. case ScriptAction::SKIRMISH_BUILD_BASE_DEFENSE_FRONT:
  5614. doBuildBaseDefense(false);
  5615. return;
  5616. case ScriptAction::SKIRMISH_BUILD_BASE_DEFENSE_FLANK:
  5617. doBuildBaseDefense(true);
  5618. return;
  5619. case ScriptAction::SKIRMISH_BUILD_STRUCTURE_FRONT:
  5620. doBuildBaseStructure(pAction->getParameter(0)->getString(), false);
  5621. return;
  5622. case ScriptAction::SKIRMISH_BUILD_STRUCTURE_FLANK:
  5623. doBuildBaseStructure(pAction->getParameter(0)->getString(), true);
  5624. return;
  5625. case ScriptAction::RECRUIT_TEAM:
  5626. doRecruitTeam(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getReal());
  5627. return;
  5628. case ScriptAction::PLAY_SOUND_EFFECT:
  5629. doPlaySoundEffect(pAction->getParameter(0)->getString());
  5630. return;
  5631. case ScriptAction::MOVE_CAMERA_TO:
  5632. doMoveCameraTo(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getReal(), pAction->getParameter(2)->getReal(), pAction->getParameter(3)->getReal(), pAction->getParameter(4)->getReal());
  5633. return;
  5634. case ScriptAction::SETUP_CAMERA:
  5635. doSetupCamera(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getReal(), pAction->getParameter(2)->getReal(), pAction->getParameter(3)->getString());
  5636. return;
  5637. case ScriptAction::ZOOM_CAMERA:
  5638. doZoomCamera(pAction->getParameter(0)->getReal(), pAction->getParameter(1)->getReal(), pAction->getParameter(2)->getReal(), pAction->getParameter(3)->getReal());
  5639. return;
  5640. case ScriptAction::PITCH_CAMERA:
  5641. doPitchCamera(pAction->getParameter(0)->getReal(), pAction->getParameter(1)->getReal(), pAction->getParameter(2)->getReal(), pAction->getParameter(3)->getReal());
  5642. return;
  5643. case ScriptAction::CAMERA_FOLLOW_NAMED:
  5644. doCameraFollowNamed(pAction->getParameter(0)->getString(), (pAction->getParameter(1) && pAction->getParameter(1)->getInt() != 0));
  5645. return;
  5646. case ScriptAction::CAMERA_STOP_FOLLOW:
  5647. doStopCameraFollowUnit();
  5648. return;
  5649. case ScriptAction::OVERSIZE_TERRAIN:
  5650. doOversizeTheTerrain(pAction->getParameter(0)->getInt());
  5651. return;
  5652. case ScriptAction::CAMERA_MOD_LOOK_TOWARD:
  5653. doModCameraLookToward(pAction->getParameter(0)->getString());
  5654. return;
  5655. case ScriptAction::CAMERA_MOD_FINAL_LOOK_TOWARD:
  5656. doModCameraFinalLookToward(pAction->getParameter(0)->getString());
  5657. return;
  5658. case ScriptAction::MOVE_CAMERA_ALONG_WAYPOINT_PATH:
  5659. doMoveCameraAlongWaypointPath(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getReal(), pAction->getParameter(2)->getReal(), pAction->getParameter(3)->getReal(), pAction->getParameter(4)->getReal());
  5660. return;
  5661. case ScriptAction::ROTATE_CAMERA:
  5662. doRotateCamera(pAction->getParameter(0)->getReal(), pAction->getParameter(1)->getReal(), pAction->getParameter(2)->getReal(), pAction->getParameter(3)->getReal());
  5663. return;
  5664. case ScriptAction::CAMERA_LOOK_TOWARD_OBJECT:
  5665. doRotateCameraTowardObject(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getReal(), pAction->getParameter(2)->getReal(), pAction->getParameter(3)->getReal(), pAction->getParameter(4)->getReal());
  5666. return;
  5667. case ScriptAction::CAMERA_LOOK_TOWARD_WAYPOINT:
  5668. doRotateCameraTowardWaypoint(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getReal(), pAction->getParameter(2)->getReal(), pAction->getParameter(3)->getReal(), pAction->getParameter(4)->getInt());
  5669. return;
  5670. case ScriptAction::RESET_CAMERA:
  5671. doResetCamera(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getReal(), pAction->getParameter(2)->getReal(), pAction->getParameter(3)->getReal());
  5672. return;
  5673. case ScriptAction::MOVE_CAMERA_TO_SELECTION:
  5674. doModCameraMoveToSelection();
  5675. return;
  5676. case ScriptAction::CAMERA_MOD_FREEZE_TIME:
  5677. TheTacticalView->cameraModFreezeTime();
  5678. return;
  5679. case ScriptAction::CAMERA_MOD_FREEZE_ANGLE:
  5680. TheTacticalView->cameraModFreezeAngle();
  5681. return;
  5682. case ScriptAction::CAMERA_MOD_SET_FINAL_ZOOM:
  5683. TheTacticalView->cameraModFinalZoom(pAction->getParameter(0)->getReal(), pAction->getParameter(1)->getReal(), pAction->getParameter(2)->getReal());
  5684. return;
  5685. case ScriptAction::CAMERA_MOD_SET_FINAL_PITCH:
  5686. TheTacticalView->cameraModFinalPitch(pAction->getParameter(0)->getReal(), pAction->getParameter(1)->getReal(), pAction->getParameter(2)->getReal());
  5687. return;
  5688. case ScriptAction::CAMERA_MOD_SET_FINAL_SPEED_MULTIPLIER:
  5689. TheTacticalView->cameraModFinalTimeMultiplier(pAction->getParameter(0)->getInt());
  5690. return;
  5691. case ScriptAction::CAMERA_MOD_SET_ROLLING_AVERAGE:
  5692. TheTacticalView->cameraModRollingAverage(pAction->getParameter(0)->getInt());
  5693. return;
  5694. case ScriptAction::SET_VISUAL_SPEED_MULTIPLIER:
  5695. TheTacticalView->setTimeMultiplier(pAction->getParameter(0)->getInt());
  5696. return;
  5697. case ScriptAction::SUSPEND_BACKGROUND_SOUNDS:
  5698. TheAudio->pauseAudio(AudioAffect_Sound);
  5699. return;
  5700. case ScriptAction::RESUME_BACKGROUND_SOUNDS:
  5701. TheAudio->resumeAudio(AudioAffect_Sound);
  5702. return;
  5703. case ScriptAction::PLAY_SOUND_EFFECT_AT:
  5704. doPlaySoundEffectAt(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5705. return;
  5706. case ScriptAction::SET_INFANTRY_LIGHTING_OVERRIDE:
  5707. doSetInfantryLightingOverride(pAction->getParameter(0)->getReal());
  5708. return;
  5709. case ScriptAction::RESET_INFANTRY_LIGHTING_OVERRIDE:
  5710. doSetInfantryLightingOverride(-1.0f);
  5711. return;
  5712. case ScriptAction::QUICKVICTORY:
  5713. doQuickVictory();
  5714. return;
  5715. case ScriptAction::VICTORY:
  5716. doVictory();
  5717. return;
  5718. case ScriptAction::DEFEAT:
  5719. doDefeat();
  5720. return;
  5721. case ScriptAction::LOCALDEFEAT:
  5722. doLocalDefeat();
  5723. return;
  5724. case ScriptAction::CREATE_OBJECT:
  5725. {
  5726. Coord3D pos;
  5727. pAction->getParameter(2)->getCoord3D(&pos);
  5728. doCreateObject( m_unnamedUnit, pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), &pos, pAction->getParameter(3)->getReal() );
  5729. return;
  5730. }
  5731. case ScriptAction::TEAM_ATTACK_TEAM:
  5732. doAttack( pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString() );
  5733. return;
  5734. case ScriptAction::NAMED_ATTACK_NAMED:
  5735. doNamedAttack( pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString() );
  5736. return;
  5737. case ScriptAction::CREATE_NAMED_ON_TEAM_AT_WAYPOINT:
  5738. createUnitOnTeamAt( pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getString(), pAction->getParameter(3)->getString());
  5739. return;
  5740. case ScriptAction::CREATE_UNNAMED_ON_TEAM_AT_WAYPOINT:
  5741. createUnitOnTeamAt( AsciiString::TheEmptyString, pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getString());
  5742. return;
  5743. //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5744. case ScriptAction::NAMED_APPLY_ATTACK_PRIORITY_SET:
  5745. updateNamedAttackPrioritySet(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5746. return;
  5747. case ScriptAction::TEAM_APPLY_ATTACK_PRIORITY_SET:
  5748. updateTeamAttackPrioritySet(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5749. return;
  5750. case ScriptAction::SET_BASE_CONSTRUCTION_SPEED:
  5751. updateBaseConstructionSpeed(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  5752. return;
  5753. case ScriptAction::NAMED_SET_ATTITUDE:
  5754. updateNamedSetAttitude(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  5755. return;
  5756. case ScriptAction::TEAM_SET_ATTITUDE:
  5757. updateTeamSetAttitude(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  5758. return;
  5759. case ScriptAction::NAMED_SET_REPULSOR:
  5760. doNamedSetRepulsor(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  5761. return;
  5762. case ScriptAction::TEAM_SET_REPULSOR:
  5763. doTeamSetRepulsor(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  5764. return;
  5765. case ScriptAction::NAMED_ATTACK_AREA:
  5766. doNamedAttackArea(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5767. return;
  5768. case ScriptAction::NAMED_ATTACK_TEAM:
  5769. doNamedAttackTeam(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5770. return;
  5771. case ScriptAction::TEAM_ATTACK_AREA:
  5772. doTeamAttackArea(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5773. return;
  5774. case ScriptAction::TEAM_ATTACK_NAMED:
  5775. doTeamAttackNamed(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5776. return;
  5777. case ScriptAction::TEAM_LOAD_TRANSPORTS:
  5778. doLoadAllTransports(pAction->getParameter(0)->getString());
  5779. return;
  5780. case ScriptAction::NAMED_ENTER_NAMED:
  5781. doNamedEnterNamed(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5782. return;
  5783. case ScriptAction::TEAM_ENTER_NAMED:
  5784. doTeamEnterNamed(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5785. return;
  5786. case ScriptAction::NAMED_EXIT_ALL:
  5787. doNamedExitAll(pAction->getParameter(0)->getString());
  5788. return;
  5789. case ScriptAction::TEAM_EXIT_ALL:
  5790. doTeamExitAll(pAction->getParameter(0)->getString());
  5791. return;
  5792. case ScriptAction::NAMED_SET_EVAC_LEFT_OR_RIGHT:
  5793. doNamedSetGarrisonEvacDisposition(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  5794. return;
  5795. case ScriptAction::NAMED_FOLLOW_WAYPOINTS:
  5796. doNamedFollowWaypoints(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5797. return;
  5798. case ScriptAction::NAMED_GUARD:
  5799. doNamedGuard(pAction->getParameter(0)->getString());
  5800. return;
  5801. case ScriptAction::TEAM_GUARD:
  5802. doTeamGuard(pAction->getParameter(0)->getString());
  5803. return;
  5804. case ScriptAction::TEAM_GUARD_POSITION:
  5805. doTeamGuardPosition(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5806. return;
  5807. case ScriptAction::TEAM_GUARD_OBJECT:
  5808. doTeamGuardObject(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5809. return;
  5810. case ScriptAction::TEAM_GUARD_AREA:
  5811. doTeamGuardArea(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5812. return;
  5813. case ScriptAction::NAMED_HUNT:
  5814. doNamedHunt(pAction->getParameter(0)->getString());
  5815. return;
  5816. case ScriptAction::TEAM_HUNT:
  5817. doTeamHunt(pAction->getParameter(0)->getString());
  5818. return;
  5819. case ScriptAction::TEAM_HUNT_WITH_COMMAND_BUTTON:
  5820. doTeamHuntWithCommandButton(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5821. return;
  5822. case ScriptAction::PLAYER_HUNT:
  5823. doPlayerHunt(pAction->getParameter(0)->getString());
  5824. return;
  5825. case ScriptAction::PLAYER_SELL_EVERYTHING:
  5826. doPlayerSellEverything(pAction->getParameter(0)->getString());
  5827. return;
  5828. case ScriptAction::PLAYER_DISABLE_BASE_CONSTRUCTION:
  5829. doPlayerDisableBaseConstruction(pAction->getParameter(0)->getString());
  5830. return;
  5831. case ScriptAction::PLAYER_DISABLE_FACTORIES:
  5832. doPlayerDisableFactories(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5833. return;
  5834. case ScriptAction::PLAYER_DISABLE_UNIT_CONSTRUCTION:
  5835. doPlayerDisableUnitConstruction(pAction->getParameter(0)->getString());
  5836. return;
  5837. case ScriptAction::PLAYER_ENABLE_BASE_CONSTRUCTION:
  5838. doPlayerEnableBaseConstruction(pAction->getParameter(0)->getString());
  5839. return;
  5840. case ScriptAction::PLAYER_ENABLE_FACTORIES:
  5841. doPlayerEnableFactories(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString() );
  5842. return;
  5843. case ScriptAction::PLAYER_REPAIR_NAMED_STRUCTURE:
  5844. doPlayerRepairStructure(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString() );
  5845. return;
  5846. case ScriptAction::PLAYER_ENABLE_UNIT_CONSTRUCTION:
  5847. doPlayerEnableUnitConstruction(pAction->getParameter(0)->getString());
  5848. return;
  5849. case ScriptAction::CAMERA_MOVE_HOME:
  5850. doCameraMoveHome();
  5851. return;
  5852. case ScriptAction::BUILD_TEAM:
  5853. doBuildTeam(pAction->getParameter(0)->getString());
  5854. return;
  5855. case ScriptAction::NAMED_DAMAGE:
  5856. doNamedDamage(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  5857. return;
  5858. case ScriptAction::NAMED_DELETE:
  5859. doNamedDelete(pAction->getParameter(0)->getString());
  5860. return;
  5861. case ScriptAction::TEAM_DELETE:
  5862. doTeamDelete(pAction->getParameter(0)->getString(), FALSE);
  5863. return;
  5864. case ScriptAction::TEAM_DELETE_LIVING:
  5865. doTeamDelete(pAction->getParameter(0)->getString(), TRUE);
  5866. return;
  5867. case ScriptAction::TEAM_WANDER:
  5868. doTeamWander(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5869. return;
  5870. case ScriptAction::TEAM_WANDER_IN_PLACE:
  5871. doTeamWanderInPlace(pAction->getParameter(0)->getString());
  5872. return;
  5873. case ScriptAction::TEAM_INCREASE_PRIORITY:
  5874. doTeamIncreasePriority(pAction->getParameter(0)->getString());
  5875. return;
  5876. case ScriptAction::TEAM_DECREASE_PRIORITY:
  5877. doTeamDecreasePriority(pAction->getParameter(0)->getString());
  5878. return;
  5879. case ScriptAction::TEAM_PANIC:
  5880. doTeamPanic(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5881. return;
  5882. case ScriptAction::NAMED_KILL:
  5883. doNamedKill(pAction->getParameter(0)->getString());
  5884. return;
  5885. case ScriptAction::TEAM_KILL:
  5886. doTeamKill(pAction->getParameter(0)->getString());
  5887. return;
  5888. case ScriptAction::PLAYER_KILL:
  5889. doPlayerKill(pAction->getParameter(0)->getString());
  5890. return;
  5891. case ScriptAction::DISPLAY_TEXT:
  5892. doDisplayText(pAction->getParameter(0)->getString());
  5893. return;
  5894. case ScriptAction::DISPLAY_CINEMATIC_TEXT:
  5895. doDisplayCinematicText(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(),
  5896. pAction->getParameter(2)->getInt());
  5897. return;
  5898. case ScriptAction::DEBUG_CRASH_BOX:
  5899. #if defined(_DEBUG) || defined(_INTERNAL)
  5900. {
  5901. const char* MSG = "Your Script requested the following message be displayed:\n\n";
  5902. const char* MSG2 = "\n\nTHIS IS NOT A BUG. DO NOT REPORT IT.";
  5903. DEBUG_CRASH(("%s%s%s\n",MSG,pAction->getParameter(0)->getString().str(),MSG2));
  5904. }
  5905. #endif
  5906. return;
  5907. case ScriptAction::INGAME_POPUP_MESSAGE:
  5908. doInGamePopupMessage(pAction->getParameter(0)->getString(),pAction->getParameter(1)->getInt(),
  5909. pAction->getParameter(2)->getInt(), pAction->getParameter(3)->getInt(),
  5910. pAction->getParameter(4)->getInt() );
  5911. return;
  5912. case ScriptAction::CAMEO_FLASH:
  5913. doCameoFlash(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  5914. return;
  5915. case ScriptAction::NAMED_FLASH:
  5916. doNamedFlash(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt(), NULL);
  5917. return;
  5918. case ScriptAction::TEAM_FLASH:
  5919. doTeamFlash(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt(), NULL);
  5920. return;
  5921. case ScriptAction::NAMED_FLASH_WHITE:
  5922. {
  5923. RGBColor c;
  5924. c.red = c.green = c.blue = 1.0f;
  5925. doNamedFlash(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt(), &c);
  5926. }
  5927. return;
  5928. case ScriptAction::NAMED_CUSTOM_COLOR:
  5929. {
  5930. doNamedCustomColor(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  5931. }
  5932. return;
  5933. case ScriptAction::TEAM_FLASH_WHITE:
  5934. {
  5935. RGBColor c;
  5936. c.red = c.green = c.blue = 1.0f;
  5937. doTeamFlash(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt(), &c);
  5938. }
  5939. return;
  5940. case ScriptAction::MOVIE_PLAY_FULLSCREEN:
  5941. doMoviePlayFullScreen(pAction->getParameter(0)->getString());
  5942. return;
  5943. case ScriptAction::MOVIE_PLAY_RADAR:
  5944. doMoviePlayRadar(pAction->getParameter(0)->getString());
  5945. return;
  5946. case ScriptAction::SOUND_PLAY_NAMED:
  5947. doSoundPlayFromNamed(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5948. return;
  5949. case ScriptAction::SPEECH_PLAY:
  5950. doSpeechPlay(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  5951. return;
  5952. case ScriptAction::PLAYER_TRANSFER_OWNERSHIP_PLAYER:
  5953. doPlayerTransferAssetsToPlayer(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5954. return;
  5955. case ScriptAction::NAMED_TRANSFER_OWNERSHIP_PLAYER:
  5956. doNamedTransferAssetsToPlayer(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  5957. return;
  5958. case ScriptAction::PLAYER_EXCLUDE_FROM_SCORE_SCREEN:
  5959. excludePlayerFromScoreScreen(pAction->getParameter(0)->getString());
  5960. return;
  5961. case ScriptAction::ENABLE_SCORING:
  5962. enableScoring(TRUE);
  5963. return;
  5964. case ScriptAction::DISABLE_SCORING:
  5965. enableScoring(FALSE);
  5966. return;
  5967. case ScriptAction::PLAYER_RELATES_PLAYER:
  5968. updatePlayerRelationTowardPlayer(pAction->getParameter(0)->getString(), pAction->getParameter(2)->getInt(), pAction->getParameter(1)->getString());
  5969. return;
  5970. case ScriptAction::RADAR_CREATE_EVENT:
  5971. {
  5972. Coord3D pos;
  5973. pAction->getParameter(0)->getCoord3D(&pos);
  5974. doRadarCreateEvent(&pos, pAction->getParameter(1)->getInt());
  5975. return;
  5976. }
  5977. case ScriptAction::OBJECT_CREATE_RADAR_EVENT:
  5978. doObjectRadarCreateEvent(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  5979. return;
  5980. case ScriptAction::TEAM_CREATE_RADAR_EVENT:
  5981. doTeamRadarCreateEvent(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  5982. return;
  5983. case ScriptAction::RADAR_DISABLE:
  5984. doRadarDisable();
  5985. return;
  5986. case ScriptAction::RADAR_ENABLE:
  5987. doRadarEnable();
  5988. return;
  5989. case ScriptAction::NAMED_SET_STEALTH_ENABLED:
  5990. doNamedEnableStealth(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  5991. return;
  5992. case ScriptAction::TEAM_SET_STEALTH_ENABLED:
  5993. doTeamEnableStealth(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  5994. return;
  5995. case ScriptAction::NAMED_SET_UNMANNED_STATUS:
  5996. doNamedSetUnmanned(pAction->getParameter(0)->getString() );
  5997. return;
  5998. case ScriptAction::TEAM_SET_UNMANNED_STATUS:
  5999. doTeamSetUnmanned(pAction->getParameter(0)->getString() );
  6000. return;
  6001. case ScriptAction::NAMED_SET_BOOBYTRAPPED:
  6002. doNamedSetBoobytrapped( pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString() );
  6003. return;
  6004. case ScriptAction::TEAM_SET_BOOBYTRAPPED:
  6005. doTeamSetBoobytrapped( pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString() );
  6006. return;
  6007. case ScriptAction::MAP_REVEAL_AT_WAYPOINT:
  6008. doRevealMapAtWaypoint(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getReal(), pAction->getParameter(2)->getString());
  6009. return;
  6010. case ScriptAction::MAP_SHROUD_AT_WAYPOINT:
  6011. doShroudMapAtWaypoint(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getReal(), pAction->getParameter(2)->getString());
  6012. return;
  6013. case ScriptAction::MAP_REVEAL_ALL:
  6014. doRevealMapEntire(pAction->getParameter(0)->getString());
  6015. return;
  6016. case ScriptAction::MAP_REVEAL_ALL_PERM:
  6017. doRevealMapEntirePermanently(TRUE, pAction->getParameter(0)->getString());
  6018. return;
  6019. case ScriptAction::MAP_REVEAL_ALL_UNDO_PERM:
  6020. doRevealMapEntirePermanently(FALSE, pAction->getParameter(0)->getString());
  6021. return;
  6022. case ScriptAction::MAP_SHROUD_ALL:
  6023. doShroudMapEntire(pAction->getParameter(0)->getString());
  6024. return;
  6025. case ScriptAction::TEAM_AVAILABLE_FOR_RECRUITMENT:
  6026. doTeamAvailableForRecruitment(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  6027. return;
  6028. case ScriptAction::TEAM_COLLECT_NEARBY_FOR_TEAM:
  6029. doCollectNearbyForTeam(pAction->getParameter(0)->getString());
  6030. return;
  6031. case ScriptAction::TEAM_MERGE_INTO_TEAM:
  6032. doMergeTeamIntoTeam(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  6033. return;
  6034. case ScriptAction::IDLE_ALL_UNITS:
  6035. doIdleAllPlayerUnits(AsciiString::TheEmptyString);
  6036. return;
  6037. case ScriptAction::RESUME_SUPPLY_TRUCKING:
  6038. doResumeSupplyTruckingForIdleUnits(AsciiString::TheEmptyString);
  6039. return;
  6040. case ScriptAction::DISABLE_INPUT:
  6041. doDisableInput();
  6042. return;
  6043. case ScriptAction::ENABLE_INPUT:
  6044. doEnableInput();
  6045. return;
  6046. case ScriptAction::DISABLE_BORDER_SHROUD:
  6047. doSetBorderShroud(FALSE);
  6048. return;
  6049. case ScriptAction::ENABLE_BORDER_SHROUD:
  6050. doSetBorderShroud(TRUE);
  6051. return;
  6052. case ScriptAction::SOUND_AMBIENT_PAUSE:
  6053. doAmbientSoundsPause(true);
  6054. return;
  6055. case ScriptAction::SOUND_AMBIENT_RESUME:
  6056. doAmbientSoundsPause(false);
  6057. return;
  6058. case ScriptAction::MUSIC_SET_TRACK:
  6059. doMusicTrackChange(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt(), pAction->getParameter(2)->getInt());
  6060. return;
  6061. case ScriptAction::TEAM_GARRISON_SPECIFIC_BUILDING:
  6062. doTeamGarrisonSpecificBuilding(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  6063. return;
  6064. case ScriptAction::EXIT_SPECIFIC_BUILDING:
  6065. doExitSpecificBuilding(pAction->getParameter(0)->getString());
  6066. return;
  6067. case ScriptAction::TEAM_GARRISON_NEAREST_BUILDING:
  6068. doTeamGarrisonNearestBuilding(pAction->getParameter(0)->getString());
  6069. return;
  6070. case ScriptAction::TEAM_EXIT_ALL_BUILDINGS:
  6071. doTeamExitAllBuildings(pAction->getParameter(0)->getString());
  6072. return;
  6073. case ScriptAction::NAMED_GARRISON_SPECIFIC_BUILDING:
  6074. doUnitGarrisonSpecificBuilding(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  6075. return;
  6076. case ScriptAction::NAMED_GARRISON_NEAREST_BUILDING:
  6077. doUnitGarrisonNearestBuilding(pAction->getParameter(0)->getString());
  6078. return;
  6079. case ScriptAction::NAMED_EXIT_BUILDING:
  6080. doUnitExitBuilding(pAction->getParameter(0)->getString());
  6081. return;
  6082. case ScriptAction::PLAYER_GARRISON_ALL_BUILDINGS:
  6083. doPlayerGarrisonAllBuildings(pAction->getParameter(0)->getString());
  6084. return;
  6085. case ScriptAction::PLAYER_EXIT_ALL_BUILDINGS:
  6086. doPlayerExitAllBuildings(pAction->getParameter(0)->getString());
  6087. return;
  6088. case ScriptAction::CAMERA_LETTERBOX_BEGIN:
  6089. doLetterBoxMode(true);
  6090. return;
  6091. case ScriptAction::CAMERA_LETTERBOX_END:
  6092. doLetterBoxMode(false);
  6093. return;
  6094. case ScriptAction::CAMERA_BW_MODE_BEGIN:
  6095. doBlackWhiteMode(true, pAction->getParameter(0) ? pAction->getParameter(0)->getInt() : 0);
  6096. return;
  6097. case ScriptAction::CAMERA_BW_MODE_END:
  6098. doBlackWhiteMode(false, pAction->getParameter(0) ? pAction->getParameter(0)->getInt() : 0);
  6099. return;
  6100. case ScriptAction::DRAW_SKYBOX_BEGIN:
  6101. doSkyBox(true);
  6102. return;
  6103. case ScriptAction::DRAW_SKYBOX_END:
  6104. doSkyBox(false);
  6105. return;
  6106. case ScriptAction::SHOW_WEATHER:
  6107. doWeather(pAction->getParameter(0)->getInt());
  6108. return;
  6109. case ScriptAction::CAMERA_MOTION_BLUR:
  6110. doCameraMotionBlur(pAction->getParameter(0)->getInt(), pAction->getParameter(1)->getInt());
  6111. return;
  6112. case ScriptAction::CAMERA_MOTION_BLUR_JUMP:
  6113. doCameraMotionBlurJump(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  6114. return;
  6115. case ScriptAction::CAMERA_MOTION_BLUR_FOLLOW:
  6116. TheTacticalView->setViewFilterMode((enum FilterModes)(FM_VIEW_MB_PAN_ALPHA+pAction->getParameter(0)->getInt()));
  6117. TheTacticalView->setViewFilter(FT_VIEW_MOTION_BLUR_FILTER);
  6118. return;
  6119. case ScriptAction::CAMERA_MOTION_BLUR_END_FOLLOW:
  6120. TheTacticalView->setViewFilterMode(FM_VIEW_MB_END_PAN_ALPHA);
  6121. TheTacticalView->setViewFilter(FT_VIEW_MOTION_BLUR_FILTER);
  6122. return;
  6123. case ScriptAction::FREEZE_TIME:
  6124. doFreezeTime();
  6125. return;
  6126. case ScriptAction::UNFREEZE_TIME:
  6127. doUnfreezeTime();
  6128. return;
  6129. case ScriptAction::SHOW_MILITARY_CAPTION:
  6130. doMilitaryCaption(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  6131. return;
  6132. case ScriptAction::CAMERA_SET_AUDIBLE_DISTANCE:
  6133. doCameraSetAudibleDistance(pAction->getParameter(0)->getReal());
  6134. return;
  6135. case ScriptAction::SET_STOPPING_DISTANCE:
  6136. doSetStoppingDistance(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getReal());
  6137. return;
  6138. case ScriptAction::SET_FPS_LIMIT:
  6139. if (!pAction->getParameter(0)->getInt())
  6140. {
  6141. TheGameEngine->setFramesPerSecondLimit(TheGlobalData->m_framesPerSecondLimit);
  6142. }
  6143. else
  6144. {
  6145. TheGameEngine->setFramesPerSecondLimit(pAction->getParameter(0)->getInt());
  6146. }
  6147. // Setting the fps limit doesn't do much good if we don't use it. jba.
  6148. TheWritableGlobalData->m_useFpsLimit = true;
  6149. return;
  6150. case ScriptAction::DISABLE_SPECIAL_POWER_DISPLAY:
  6151. doDisableSpecialPowerDisplay();
  6152. return;
  6153. case ScriptAction::ENABLE_SPECIAL_POWER_DISPLAY:
  6154. doEnableSpecialPowerDisplay();
  6155. return;
  6156. case ScriptAction::NAMED_HIDE_SPECIAL_POWER_DISPLAY:
  6157. doNamedHideSpecialPowerDisplay(pAction->getParameter(0)->getString());
  6158. return;
  6159. case ScriptAction::NAMED_SHOW_SPECIAL_POWER_DISPLAY:
  6160. doNamedShowSpecialPowerDisplay(pAction->getParameter(0)->getString());
  6161. return;
  6162. case ScriptAction::NAMED_SET_STOPPING_DISTANCE:
  6163. doNamedSetStoppingDistance(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getReal());
  6164. return;
  6165. case ScriptAction::NAMED_SET_HELD:
  6166. doNamedSetHeld(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  6167. return;
  6168. case ScriptAction::MUSIC_SET_VOLUME:
  6169. doAudioSetVolume(AudioAffect_Music, pAction->getParameter(0)->getReal());
  6170. return;
  6171. case ScriptAction::SOUND_SET_VOLUME:
  6172. doAudioSetVolume((AudioAffect)(AudioAffect_Sound | AudioAffect_Sound3D), pAction->getParameter(0)->getReal());
  6173. return;
  6174. case ScriptAction::SPEECH_SET_VOLUME:
  6175. doAudioSetVolume(AudioAffect_Speech, pAction->getParameter(0)->getReal());
  6176. return;
  6177. case ScriptAction::TEAM_TRANSFER_TO_PLAYER:
  6178. doTransferTeamToPlayer(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  6179. return;
  6180. case ScriptAction::PLAYER_SET_MONEY:
  6181. doSetMoney(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  6182. return;
  6183. case ScriptAction::PLAYER_GIVE_MONEY:
  6184. doGiveMoney(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  6185. return;
  6186. case ScriptAction::DISPLAY_COUNTDOWN_TIMER:
  6187. doDisplayCountdownTimer(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  6188. return;
  6189. case ScriptAction::HIDE_COUNTDOWN_TIMER:
  6190. doHideCountdownTimer(pAction->getParameter(0)->getString());
  6191. return;
  6192. case ScriptAction::DISPLAY_COUNTER:
  6193. doDisplayCounter(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  6194. return;
  6195. case ScriptAction::HIDE_COUNTER:
  6196. doHideCounter(pAction->getParameter(0)->getString());
  6197. return;
  6198. case ScriptAction::DISABLE_COUNTDOWN_TIMER_DISPLAY:
  6199. doDisableCountdownTimerDisplay();
  6200. return;
  6201. case ScriptAction::ENABLE_COUNTDOWN_TIMER_DISPLAY:
  6202. doEnableCountdownTimerDisplay();
  6203. return;
  6204. case ScriptAction::NAMED_STOP_SPECIAL_POWER_COUNTDOWN:
  6205. doNamedStopSpecialPowerCountdown(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), TRUE);
  6206. return;
  6207. case ScriptAction::NAMED_START_SPECIAL_POWER_COUNTDOWN:
  6208. doNamedStopSpecialPowerCountdown(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), FALSE);
  6209. return;
  6210. case ScriptAction::NAMED_SET_SPECIAL_POWER_COUNTDOWN:
  6211. doNamedSetSpecialPowerCountdown(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getInt());
  6212. return;
  6213. case ScriptAction::NAMED_ADD_SPECIAL_POWER_COUNTDOWN:
  6214. doNamedAddSpecialPowerCountdown(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getInt());
  6215. return;
  6216. case ScriptAction::NAMED_FIRE_SPECIAL_POWER_AT_WAYPOINT:
  6217. doNamedFireSpecialPowerAtWaypoint(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getString());
  6218. return;
  6219. case ScriptAction::SKIRMISH_FIRE_SPECIAL_POWER_AT_MOST_COST:
  6220. doSkirmishFireSpecialPowerAtMostCost(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  6221. return;
  6222. case ScriptAction::NAMED_FIRE_SPECIAL_POWER_AT_NAMED:
  6223. doNamedFireSpecialPowerAtNamed(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getString());
  6224. return;
  6225. case ScriptAction::REFRESH_RADAR:
  6226. doRadarRefresh();
  6227. return;
  6228. case ScriptAction::NAMED_STOP:
  6229. doNamedStop(pAction->getParameter(0)->getString());
  6230. return;
  6231. case ScriptAction::TEAM_STOP:
  6232. doTeamStop(pAction->getParameter(0)->getString(), FALSE);
  6233. return;
  6234. case ScriptAction::TEAM_STOP_AND_DISBAND:
  6235. doTeamStop(pAction->getParameter(0)->getString(), TRUE);
  6236. return;
  6237. case ScriptAction::CAMERA_TETHER_NAMED:
  6238. doCameraTetherNamed(pAction->getParameter(0)->getString(), (Bool)(pAction->getParameter(1)->getInt()), pAction->getParameter(2)->getReal());
  6239. return;
  6240. case ScriptAction::CAMERA_STOP_TETHER_NAMED:
  6241. doCameraStopTetherNamed();
  6242. return;
  6243. case ScriptAction::CAMERA_SET_DEFAULT:
  6244. doCameraSetDefault(pAction->getParameter(0)->getReal(), pAction->getParameter(1)->getReal(), pAction->getParameter(2)->getReal());
  6245. return;
  6246. case ScriptAction::TEAM_SET_OVERRIDE_RELATION_TO_TEAM:
  6247. doTeamSetOverrideRelationToTeam(pAction->getParameter(0)->getString(), // first team
  6248. pAction->getParameter(1)->getString(), // second team
  6249. pAction->getParameter(2)->getInt()); // relation (ENEMIES, etc)
  6250. return;
  6251. case ScriptAction::TEAM_REMOVE_OVERRIDE_RELATION_TO_TEAM:
  6252. doTeamRemoveOverrideRelationToTeam(pAction->getParameter(0)->getString(), // first team
  6253. pAction->getParameter(1)->getString()); // second team
  6254. return;
  6255. case ScriptAction::TEAM_REMOVE_ALL_OVERRIDE_RELATIONS:
  6256. doTeamRemoveAllOverrideRelations(pAction->getParameter(0)->getString()); // first team
  6257. return;
  6258. case ScriptAction::TEAM_SET_OVERRIDE_RELATION_TO_PLAYER:
  6259. doTeamSetOverrideRelationToPlayer(pAction->getParameter(0)->getString(), // first team
  6260. pAction->getParameter(1)->getString(), // second player
  6261. pAction->getParameter(2)->getInt()); // relation (ENEMIES, etc)
  6262. return;
  6263. case ScriptAction::TEAM_REMOVE_OVERRIDE_RELATION_TO_PLAYER:
  6264. doTeamRemoveOverrideRelationToPlayer(pAction->getParameter(0)->getString(), // first team
  6265. pAction->getParameter(1)->getString()); // second player
  6266. return;
  6267. case ScriptAction::PLAYER_SET_OVERRIDE_RELATION_TO_TEAM:
  6268. doPlayerSetOverrideRelationToTeam(pAction->getParameter(0)->getString(), // first player
  6269. pAction->getParameter(1)->getString(), // second team
  6270. pAction->getParameter(2)->getInt()); // relation (ENEMIES, etc)
  6271. return;
  6272. case ScriptAction::PLAYER_REMOVE_OVERRIDE_RELATION_TO_TEAM:
  6273. doPlayerRemoveOverrideRelationToTeam(pAction->getParameter(0)->getString(), // first player
  6274. pAction->getParameter(1)->getString()); // second team
  6275. return;
  6276. case ScriptAction::NAMED_FIRE_WEAPON_FOLLOWING_WAYPOINT_PATH:
  6277. doNamedFireWeaponFollowingWaypointPath(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString() );
  6278. return;
  6279. case ScriptAction::NAMED_USE_COMMANDBUTTON_ABILITY:
  6280. doNamedUseCommandButtonAbility( pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString() );
  6281. return;
  6282. case ScriptAction::NAMED_USE_COMMANDBUTTON_ABILITY_ON_NAMED:
  6283. doNamedUseCommandButtonAbilityOnNamed( pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getString() );
  6284. return;
  6285. case ScriptAction::NAMED_USE_COMMANDBUTTON_ABILITY_AT_WAYPOINT:
  6286. doNamedUseCommandButtonAbilityAtWaypoint( pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getString() );
  6287. return;
  6288. case ScriptAction::NAMED_USE_COMMANDBUTTON_ABILITY_USING_WAYPOINT_PATH:
  6289. doNamedUseCommandButtonAbilityUsingWaypointPath( pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getString() );
  6290. return;
  6291. case ScriptAction::TEAM_USE_COMMANDBUTTON_ABILITY:
  6292. doTeamUseCommandButtonAbility( pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString() );
  6293. return;
  6294. case ScriptAction::TEAM_USE_COMMANDBUTTON_ABILITY_ON_NAMED:
  6295. doTeamUseCommandButtonAbilityOnNamed( pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getString() );
  6296. return;
  6297. case ScriptAction::TEAM_USE_COMMANDBUTTON_ABILITY_AT_WAYPOINT:
  6298. doTeamUseCommandButtonAbilityAtWaypoint( pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getString() );
  6299. return;
  6300. case ScriptAction::UNIT_EXECUTE_SEQUENTIAL_SCRIPT:
  6301. doUnitStartSequentialScript(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), 0);
  6302. return;
  6303. case ScriptAction::UNIT_EXECUTE_SEQUENTIAL_SCRIPT_LOOPING:
  6304. doUnitStartSequentialScript(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getInt() - 1);
  6305. return;
  6306. case ScriptAction::UNIT_STOP_SEQUENTIAL_SCRIPT:
  6307. doUnitStopSequentialScript(pAction->getParameter(0)->getString());
  6308. return;
  6309. case ScriptAction::TEAM_EXECUTE_SEQUENTIAL_SCRIPT:
  6310. doTeamStartSequentialScript(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), 0);
  6311. return;
  6312. case ScriptAction::TEAM_EXECUTE_SEQUENTIAL_SCRIPT_LOOPING:
  6313. doTeamStartSequentialScript(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getInt() - 1);
  6314. return;
  6315. case ScriptAction::TEAM_STOP_SEQUENTIAL_SCRIPT:
  6316. doTeamStopSequentialScript(pAction->getParameter(0)->getString());
  6317. return;
  6318. case ScriptAction::UNIT_GUARD_FOR_FRAMECOUNT:
  6319. doUnitGuardForFramecount(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  6320. return;
  6321. case ScriptAction::UNIT_IDLE_FOR_FRAMECOUNT:
  6322. doUnitIdleForFramecount(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  6323. return;
  6324. case ScriptAction::TEAM_GUARD_FOR_FRAMECOUNT:
  6325. doTeamIdleForFramecount(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  6326. return;
  6327. case ScriptAction::TEAM_IDLE_FOR_FRAMECOUNT:
  6328. doTeamIdleForFramecount(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  6329. return;
  6330. case ScriptAction::WATER_CHANGE_HEIGHT:
  6331. doWaterChangeHeight(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getReal());
  6332. return;
  6333. case ScriptAction::WATER_CHANGE_HEIGHT_OVER_TIME:
  6334. doWaterChangeHeightOverTime( pAction->getParameter(0)->getString(), pAction->getParameter(1)->getReal(),
  6335. pAction->getParameter(2)->getReal(), pAction->getParameter(3)->getReal() );
  6336. return;
  6337. case ScriptAction::MAP_SWITCH_BORDER:
  6338. doBorderSwitch(pAction->getParameter(0)->getInt());
  6339. return;
  6340. case ScriptAction::OBJECT_FORCE_SELECT:
  6341. doForceObjectSelection(pAction->getParameter(0)->getString(),
  6342. pAction->getParameter(1)->getString(),
  6343. pAction->getParameter(2)->getInt(),
  6344. pAction->getParameter(3)->getString());
  6345. return;
  6346. case ScriptAction::UNIT_DESTROY_ALL_CONTAINED:
  6347. doDestroyAllContained(pAction->getParameter(0)->getString(), 0);
  6348. return;
  6349. case ScriptAction::RADAR_FORCE_ENABLE:
  6350. doRadarForceEnable();
  6351. return;
  6352. case ScriptAction::RADAR_REVERT_TO_NORMAL:
  6353. doRadarRevertNormal();
  6354. return;
  6355. case ScriptAction::SCREEN_SHAKE:
  6356. doScreenShake( (View::CameraShakeType)pAction->getParameter( 0 )->getInt() );
  6357. return;
  6358. case ScriptAction::TECHTREE_MODIFY_BUILDABILITY_OBJECT:
  6359. doModifyBuildableStatus(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  6360. return;
  6361. case ScriptAction::SET_CAVE_INDEX:
  6362. doSetCaveIndex(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  6363. return;
  6364. case ScriptAction::WAREHOUSE_SET_VALUE:
  6365. doSetWarehouseValue(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  6366. return;
  6367. case ScriptAction::SOUND_DISABLE_TYPE:
  6368. doSoundEnableType(pAction->getParameter(0)->getString(), false);
  6369. return;
  6370. case ScriptAction::SOUND_ENABLE_TYPE:
  6371. doSoundEnableType(pAction->getParameter(0)->getString(), true);
  6372. return;
  6373. case ScriptAction::SOUND_ENABLE_ALL:
  6374. doSoundEnableType(AsciiString::TheEmptyString, true);
  6375. return;
  6376. case ScriptAction::SOUND_REMOVE_ALL_DISABLED:
  6377. doSoundRemoveAllDisabled();
  6378. return;
  6379. case ScriptAction::SOUND_REMOVE_TYPE:
  6380. doSoundRemoveType(pAction->getParameter(0)->getString());
  6381. return;
  6382. case ScriptAction::AUDIO_OVERRIDE_VOLUME_TYPE:
  6383. doSoundOverrideVolume(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getReal());
  6384. return;
  6385. case ScriptAction::AUDIO_RESTORE_VOLUME_TYPE:
  6386. doSoundOverrideVolume(pAction->getParameter(0)->getString(), -100.0);
  6387. return;
  6388. case ScriptAction::AUDIO_RESTORE_VOLUME_ALL_TYPE:
  6389. doSoundOverrideVolume(AsciiString::TheEmptyString, -100.0);
  6390. return;
  6391. case ScriptAction::NAMED_SET_TOPPLE_DIRECTION:
  6392. {
  6393. Coord3D dir;
  6394. pAction->getParameter(1)->getCoord3D(&dir);
  6395. doSetToppleDirection(pAction->getParameter(0)->getString(), &dir);
  6396. return;
  6397. }
  6398. case ScriptAction::UNIT_MOVE_TOWARDS_NEAREST_OBJECT_TYPE:
  6399. doMoveUnitTowardsNearest(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getString());
  6400. return;
  6401. case ScriptAction::TEAM_MOVE_TOWARDS_NEAREST_OBJECT_TYPE:
  6402. doMoveTeamTowardsNearest(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getString());
  6403. return;
  6404. case ScriptAction::NAMED_RECEIVE_UPGRADE:
  6405. doUnitReceiveUpgrade(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  6406. return;
  6407. case ScriptAction::SKIRMISH_ATTACK_NEAREST_GROUP_WITH_VALUE:
  6408. doSkirmishAttackNearestGroupWithValue(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt(), pAction->getParameter(2)->getInt());
  6409. return;
  6410. case ScriptAction::SKIRMISH_PERFORM_COMMANDBUTTON_ON_MOST_VALUABLE_OBJECT:
  6411. doSkirmishCommandButtonOnMostValuable(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getReal(), pAction->getParameter(3)->getInt());
  6412. return;
  6413. case ScriptAction::SKIRMISH_WAIT_FOR_COMMANDBUTTON_AVAILABLE_ALL:
  6414. // We should never get here.
  6415. DEBUG_CRASH(("\"[Skirmish] Wait for command button available - all\" should never be used outside of Sequential scripts. - jkmcd"));
  6416. return;
  6417. case ScriptAction::SKIRMISH_WAIT_FOR_COMMANDBUTTON_AVAILABLE_PARTIAL:
  6418. // We should never get here.
  6419. DEBUG_CRASH(("\"[Skirmish] Wait for command button available - partial\" should never be used outside of Sequential scripts. - jkmcd"));
  6420. return;
  6421. case ScriptAction::TEAM_WAIT_FOR_NOT_CONTAINED_ALL:
  6422. // We should never get here.
  6423. DEBUG_CRASH(("\"[Team] Wait for team no longer contained - all\" should never be used outside of Sequential scripts. - jkmcd"));
  6424. return;
  6425. case ScriptAction::TEAM_WAIT_FOR_NOT_CONTAINED_PARTIAL:
  6426. // We should never get here.
  6427. DEBUG_CRASH(("\"[Team] Wait for team no longer contained - partial\" should never be used outside of Sequential scripts. - jkmcd"));
  6428. return;
  6429. case ScriptAction::TEAM_SPIN_FOR_FRAMECOUNT:
  6430. doTeamSpinForFramecount( pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt() );
  6431. return;
  6432. case ScriptAction::TEAM_ALL_USE_COMMANDBUTTON_ON_NAMED:
  6433. doTeamUseCommandButtonOnNamed(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getString());
  6434. return;
  6435. case ScriptAction::TEAM_ALL_USE_COMMANDBUTTON_ON_NEAREST_ENEMY_UNIT:
  6436. doTeamUseCommandButtonOnNearestEnemy(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  6437. return;
  6438. case ScriptAction::TEAM_ALL_USE_COMMANDBUTTON_ON_NEAREST_GARRISONED_BUILDING:
  6439. doTeamUseCommandButtonOnNearestGarrisonedBuilding(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  6440. return;
  6441. case ScriptAction::TEAM_ALL_USE_COMMANDBUTTON_ON_NEAREST_KINDOF:
  6442. doTeamUseCommandButtonOnNearestKindof(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getInt());
  6443. return;
  6444. case ScriptAction::TEAM_ALL_USE_COMMANDBUTTON_ON_NEAREST_ENEMY_BUILDING:
  6445. doTeamUseCommandButtonOnNearestBuilding(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  6446. return;
  6447. case ScriptAction::TEAM_ALL_USE_COMMANDBUTTON_ON_NEAREST_ENEMY_BUILDING_CLASS:
  6448. doTeamUseCommandButtonOnNearestBuildingClass(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getInt());
  6449. return;
  6450. case ScriptAction::TEAM_ALL_USE_COMMANDBUTTON_ON_NEAREST_OBJECTTYPE:
  6451. doTeamUseCommandButtonOnNearestObjectType(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getString());
  6452. return;
  6453. case ScriptAction::TEAM_PARTIAL_USE_COMMANDBUTTON:
  6454. doTeamPartialUseCommandButton(pAction->getParameter(0)->getReal(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getString());
  6455. return;
  6456. case ScriptAction::TEAM_CAPTURE_NEAREST_UNOWNED_FACTION_UNIT:
  6457. doTeamCaptureNearestUnownedFactionUnit(pAction->getParameter(0)->getString());
  6458. return;
  6459. case ScriptAction::PLAYER_CREATE_TEAM_FROM_CAPTURED_UNITS:
  6460. doCreateTeamFromCapturedUnits(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  6461. return;
  6462. case ScriptAction::PLAYER_ADD_SKILLPOINTS:
  6463. doPlayerAddSkillPoints(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  6464. return;
  6465. case ScriptAction::PLAYER_ADD_RANKLEVEL:
  6466. doPlayerAddRankLevels(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  6467. return;
  6468. case ScriptAction::PLAYER_SET_RANKLEVEL:
  6469. doPlayerSetRankLevel(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  6470. return;
  6471. case ScriptAction::PLAYER_SET_RANKLEVELLIMIT:
  6472. doMapSetRankLevelLimit(pAction->getParameter(0)->getInt());
  6473. return;
  6474. case ScriptAction::PLAYER_GRANT_SCIENCE:
  6475. doPlayerGrantScience(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  6476. return;
  6477. case ScriptAction::PLAYER_PURCHASE_SCIENCE:
  6478. doPlayerPurchaseScience(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  6479. return;
  6480. case ScriptAction::PLAYER_SCIENCE_AVAILABILITY:
  6481. doPlayerSetScienceAvailability(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getString());
  6482. return;
  6483. case ScriptAction::TEAM_SET_EMOTICON:
  6484. doTeamEmoticon( pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getReal() );
  6485. return;
  6486. case ScriptAction::NAMED_SET_EMOTICON:
  6487. doNamedEmoticon( pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getReal() );
  6488. return;
  6489. case ScriptAction::OBJECTLIST_ADDOBJECTTYPE:
  6490. doObjectTypeListMaintenance(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), TRUE);
  6491. return;
  6492. case ScriptAction::OBJECTLIST_REMOVEOBJECTTYPE:
  6493. doObjectTypeListMaintenance(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), FALSE);
  6494. return;
  6495. case ScriptAction::MAP_REVEAL_PERMANENTLY_AT_WAYPOINT:
  6496. doRevealMapAtWaypointPermanent(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getReal(), pAction->getParameter(2)->getString(), pAction->getParameter(3)->getString());
  6497. return;
  6498. case ScriptAction::MAP_UNDO_REVEAL_PERMANENTLY_AT_WAYPOINT:
  6499. doUndoRevealMapAtWaypointPermanent(pAction->getParameter(0)->getString());
  6500. return;
  6501. case ScriptAction::EVA_SET_ENABLED_DISABLED:
  6502. doEvaEnabledDisabled(pAction->getParameter(0)->getInt());
  6503. return;
  6504. case ScriptAction::OPTIONS_SET_OCCLUSION_MODE:
  6505. doSetOcclusionMode(pAction->getParameter(0)->getInt());
  6506. return;
  6507. case ScriptAction::OPTIONS_SET_DRAWICON_UI_MODE:
  6508. doSetDrawIconUIMode(pAction->getParameter(0)->getInt());
  6509. return;
  6510. case ScriptAction::CAMERA_ENABLE_SLAVE_MODE:
  6511. {
  6512. doC3CameraEnableSlaveMode
  6513. (
  6514. pAction->getParameter(0)->getString(),
  6515. pAction->getParameter(1)->getString()
  6516. );
  6517. }
  6518. return;
  6519. case ScriptAction::CAMERA_DISABLE_SLAVE_MODE:
  6520. {
  6521. doC3CameraDisableSlaveMode();
  6522. }
  6523. return;
  6524. case ScriptAction::CAMERA_ADD_SHAKER_AT: // WST 11.12.2002 (MBL)
  6525. {
  6526. doC3CameraShake
  6527. (
  6528. pAction->getParameter(0)->getString(), // Waypoint name
  6529. pAction->getParameter(1)->getReal(), // Amplitude
  6530. pAction->getParameter(2)->getReal(), // Duration in seconds
  6531. pAction->getParameter(3)->getReal() // Radius
  6532. );
  6533. }
  6534. return;
  6535. case ScriptAction::OPTIONS_SET_PARTICLE_CAP_MODE:
  6536. doSetDynamicLODMode(pAction->getParameter(0)->getInt());
  6537. return;
  6538. case ScriptAction::SCRIPTING_OVERRIDE_HULK_LIFETIME:
  6539. doOverrideHulkLifetime( pAction->getParameter( 0 )->getReal() );
  6540. return;
  6541. case ScriptAction::NAMED_FACE_NAMED:
  6542. doNamedFaceNamed( pAction->getParameter( 0 )->getString(), pAction->getParameter( 1 )->getString() );
  6543. return;
  6544. case ScriptAction::NAMED_FACE_WAYPOINT:
  6545. doNamedFaceWaypoint( pAction->getParameter( 0 )->getString(), pAction->getParameter( 1 )->getString() );
  6546. return;
  6547. case ScriptAction::TEAM_FACE_NAMED:
  6548. doTeamFaceNamed( pAction->getParameter( 0 )->getString(), pAction->getParameter( 1 )->getString() );
  6549. return;
  6550. case ScriptAction::TEAM_FACE_WAYPOINT:
  6551. doTeamFaceWaypoint( pAction->getParameter( 0 )->getString(), pAction->getParameter( 1 )->getString() );
  6552. return;
  6553. case ScriptAction::UNIT_AFFECT_OBJECT_PANEL_FLAGS:
  6554. doAffectObjectPanelFlagsUnit(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getInt());
  6555. return;
  6556. case ScriptAction::TEAM_AFFECT_OBJECT_PANEL_FLAGS:
  6557. doAffectObjectPanelFlagsTeam(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getInt());
  6558. return;
  6559. case ScriptAction::PLAYER_SELECT_SKILLSET:
  6560. doAffectPlayerSkillset(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  6561. return;
  6562. case ScriptAction::COMMANDBAR_REMOVE_BUTTON_OBJECTTYPE:
  6563. doRemoveCommandBarButton(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString());
  6564. return;
  6565. case ScriptAction::COMMANDBAR_ADD_BUTTON_OBJECTTYPE_SLOT:
  6566. doAddCommandBarButton(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getInt());
  6567. return;
  6568. case ScriptAction::UNIT_SPAWN_NAMED_LOCATION_ORIENTATION:
  6569. {
  6570. Coord3D pos;
  6571. pAction->getParameter(3)->getCoord3D(&pos);
  6572. doCreateObject( pAction->getParameter(0)->getString(), pAction->getParameter(1)->getString(), pAction->getParameter(2)->getString(), &pos, pAction->getParameter(4)->getReal() );
  6573. return;
  6574. }
  6575. case ScriptAction::PLAYER_AFFECT_RECEIVING_EXPERIENCE:
  6576. doAffectSkillPointsModifier(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getReal());
  6577. return;
  6578. case ScriptAction::TEAM_GUARD_SUPPLY_CENTER:
  6579. doGuardSupplyCenter(pAction->getParameter(0)->getString(), pAction->getParameter(1)->getInt());
  6580. return;
  6581. case ScriptAction::OBJECT_ALLOW_BONUSES:
  6582. doEnableOrDisableObjectDifficultyBonuses(pAction->getParameter(0)->getInt());
  6583. return;
  6584. case ScriptAction::TEAM_GUARD_IN_TUNNEL_NETWORK:
  6585. doTeamGuardInTunnelNetwork(pAction->getParameter(0)->getString());
  6586. return;
  6587. case ScriptAction::RESIZE_VIEW_GUARDBAND:
  6588. doResizeViewGuardband( pAction->getParameter(0)->getReal(), pAction->getParameter(1)->getReal() );
  6589. return;
  6590. case ScriptAction::DELETE_ALL_UNMANNED:
  6591. deleteAllUnmanned();
  6592. return;
  6593. case ScriptAction::CHOOSE_VICTIM_ALWAYS_USES_NORMAL:
  6594. doChooseVictimAlwaysUsesNormal(pAction->getParameter(0)->getInt());
  6595. return;
  6596. case ScriptAction::SET_TRAIN_HELD:
  6597. doNamedSetTrainHeld( pAction->getParameter( 0 )->getString(), (Bool)pAction->getParameter( 1 )->getInt() );
  6598. return;
  6599. case ScriptAction::ENABLE_OBJECT_SOUND:
  6600. doEnableObjectSound(pAction->getParameter(0)->getString(), true);
  6601. return;
  6602. case ScriptAction::DISABLE_OBJECT_SOUND:
  6603. doEnableObjectSound(pAction->getParameter(0)->getString(), false);
  6604. return;
  6605. }
  6606. }