Advertisement
Guest User

Sea.c

a guest
Apr 12th, 2014
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 62.88 KB | None | 0 0
  1. #include "sea_ai\Script_defines.h"
  2. #include "sea_ai\SeaPeople.h"
  3.  
  4. #include "sea_ai\AIGroup.c"
  5. #include "sea_ai\AIShip.c"
  6. #include "sea_ai\AIFort.c"
  7. #include "sea_ai\AISea.c"
  8. #include "sea_ai\AICameras.c"
  9. #include "sea_ai\AIAbordage.c"
  10. #include "sea_ai\AIFantom.c"
  11. #include "sea_ai\AICannon.c"
  12. #include "sea_ai\AIBalls.c"
  13. #include "sea_ai\AIIsland.c"
  14. #include "sea_ai\AISeaGoods.c"
  15. #include "sea_ai\AITasks\AITasks.c"
  16.  
  17. #include "sea_ai\ShipBortFire.c"
  18. #include "sea_ai\ShipDead.c"
  19. #include "sea_ai\ShipWalk.c"
  20.  
  21. #include "sea_ai\Telescope.c"
  22.  
  23. #include "battle_interface\BattleInterface.c"
  24.  
  25. #event_handler("Sea_FirstInit", "Sea_FirstInit");
  26.  
  27. #define DEBUGCR 0 // LDH set to 1 to get coastal traffic debugging info 15Feb09
  28.  
  29. string sCurrentSeaExecute = "execute";
  30. string sCurrentSeaRealize = "realize";
  31.  
  32. int iAITemplatesNum;
  33. bool bSeaActive;
  34. bool bSkipSeaLogin = false;
  35. bool bIslandLoaded = false;
  36. bool bSeaReloadStarted = false;
  37. bool bNotEnoughBalls;
  38. bool bStorm, bTornado;
  39. bool bSeaQuestGroupHere = false;
  40.  
  41. int iStormLockSeconds = 0;
  42.  
  43. object Island, IslandReflModel;
  44. object Touch, AISea;
  45. object SeaFader;
  46. object Seafoam, BallSplash, SinkEffect, PeopleOnShip, Telescope, SeaOperator, Artifact;
  47. object Sharks;
  48. object SeaLighter;
  49.  
  50. object SeaLocatorShow;
  51. object LoginGroupsNow;
  52. bool bSeaShowLocators = true;
  53. bool bQuestDisableMapEnter = false;
  54. bool bQuestDisableSeaEnter = false; // KK
  55. bool bFromCoast = false;
  56.  
  57. float SeaMapLoadX = -1570.99;
  58. float SeaMapLoadZ = 950.812;
  59. float SeaMapLoadAY = 10.54;
  60.  
  61. float fSeaExp = 0.0;
  62. float fSeaExpTimer = 0.0;
  63.  
  64. int iSeaSectionLang = -1;
  65.  
  66. bool bRecognized = false; // KK
  67.  
  68. void DeleteSeaEnvironment()
  69. {
  70. ref rPlayer = GetMainCharacter();
  71.  
  72. StopMusic();
  73. bSeaActive = false;
  74. sCurrentSeaExecute = "execute";
  75. sCurrentSeaRealize = "realize";
  76.  
  77. rPlayer.Ship.Stopped = true;
  78. // PB: Steam Ships -->
  79. rPlayer.Ship.Power = 0;
  80. DeleteAttribute(rPlayer, "Ship.PlayedEngineSound");
  81. // PB: Steam Ships <--
  82. DeleteAttribute(rPlayer, "KrakenAttack"); // PB: Kraken Attack
  83. DeleteAttribute(rPlayer, "ship.speedburst"); // PB: Black Pearl & Queen Anne's Revenge
  84. DeleteAttribute(rPlayer, "Flags.waitdelay"); // PB: Just to make sure this is gone
  85. TreasureFleet = false; // PB: Treasure Fleet
  86. DeleteBattleInterface();
  87.  
  88. DelEventHandler(SHIP_BORT_FIRE, "Ship_BortFire");
  89. DelEventHandler(BALL_FLY_UPDATE, "Ball_OnFlyUpdate");
  90.  
  91. SendMessage(&AISea, "l", AI_MESSAGE_UNLOAD);
  92.  
  93. DeleteSea();
  94.  
  95. DeleteClass(&Island);
  96. DeleteClass(&IslandReflModel);
  97. DeleteClass(&Touch);
  98. DeleteClass(&Seafoam);
  99. DeleteClass(&BallSplash);
  100. DeleteClass(&SinkEffect);
  101. DeleteClass(&PeopleOnShip);
  102. DeleteClass(&SeaLocatorShow);
  103. DeleteClass(&SeaOperator);
  104. DeleteClass(&Telescope);
  105. DeleteClass(&Sharks);
  106.  
  107. DeleteClass(&SeaLighter);
  108.  
  109. if (IsEntity(&Artifact)) DeleteClass(&Artifact);
  110.  
  111. DeleteBallsEnvironment();
  112. DeleteCannonsEnvironment();
  113. DeleteSeaCamerasEnvironment();
  114. DeleteShipEnvironment();
  115. DeleteFortEnvironment();
  116. DeleteAbordageEnvironment();
  117. DeleteSeaGoodsEnvironment();
  118.  
  119. DeleteWeatherEnvironment();
  120.  
  121. DeleteAttribute(&AISea,"");
  122.  
  123. LayerFreeze(SEA_EXECUTE, true);
  124. LayerFreeze(SEA_REALIZE, true);
  125.  
  126. LayerFreeze("realize", false);
  127. LayerFreeze("execute", false);
  128.  
  129. DeleteClass(&AISea);
  130.  
  131. DeleteAnimals();
  132.  
  133. // delete masts fall modules
  134. DeleteEntitiesByType("mast");
  135.  
  136. // delete particle system
  137. DeleteParticles();
  138.  
  139. // delete our group
  140. Group_DeleteGroup(PLAYER_GROUP);
  141.  
  142. // delete fantom and dead groups
  143. Group_DeleteUnusedGroup();
  144.  
  145. //
  146. LanguageCloseFile(iSeaSectionLang); iSeaSectionLang = -1;
  147.  
  148. //
  149. Encounter_DeleteDeadQuestMapEncounters();
  150.  
  151. if(FCOHS && CheckAttribute(rPlayer, "FCoHS")) // PB: Don't stop the mod if it's not started yet (for example on New Game)
  152. FCoHS_Main_Stop(); // FCoHS
  153. }
  154.  
  155. void CreateSeaEnvironment()
  156. {
  157. sCurrentSeaExecute = SEA_EXECUTE;
  158. sCurrentSeaRealize = SEA_REALIZE;
  159.  
  160. iSeaSectionLang = LanguageOpenFile("SeaSection.txt");
  161.  
  162. CreateParticleEntity();
  163.  
  164. Ship_Walk_Init();
  165.  
  166. LayerFreeze("realize", true);
  167. LayerFreeze("execute", true);
  168. LayerCreate("sea_reflection", 1);
  169. LayerFreeze("sea_reflection", false);
  170.  
  171. InterfaceStates.Buttons.Resume.enable = true;
  172.  
  173. bSeaActive = true;
  174. LayerCreate(SEA_REALIZE, 1);
  175. LayerSetRealize(SEA_REALIZE, 1);
  176. LayerCreate(SEA_EXECUTE, 1);
  177. LayerSetExecute(SEA_EXECUTE, 1);
  178.  
  179. LayerFreeze(SEA_EXECUTE, false);
  180. LayerFreeze(SEA_REALIZE, false);
  181.  
  182. CreateSea(SEA_EXECUTE, SEA_REALIZE); ReloadProgressUpdate();
  183. CreateWeather(SEA_EXECUTE, SEA_REALIZE); ReloadProgressUpdate();
  184.  
  185. CreateEntity(&AISea, "sea_ai"); ReloadProgressUpdate();
  186. LayerAddObject(SEA_EXECUTE, &AISea, 1);
  187. LayerAddObject(SEA_REALIZE, &AISea, -1);
  188.  
  189. CreateEntity(&Touch, "touch"); ReloadProgressUpdate();
  190. LayerAddObject(SEA_EXECUTE, &Touch, 1);
  191. Touch.CollisionDepth = -10.0;
  192. //LayerAddObject(SEA_REALIZE, &Touch, -1); // for collision debug
  193.  
  194. CreateEntity(&BallSplash, "BallSplash"); ReloadProgressUpdate();
  195. LayerAddObject(SEA_EXECUTE, &BallSplash, -1);
  196. LayerAddObject(SEA_REALIZE, &BallSplash, 65535);
  197.  
  198. CreateEntity(&SinkEffect, "SINKEFFECT"); ReloadProgressUpdate();
  199. LayerAddObject(SEA_EXECUTE, &SinkEffect, 65531);
  200. LayerAddObject(SEA_REALIZE, &SinkEffect, 65531);
  201.  
  202. CreateEntity(&PeopleOnShip, "PEOPLE_ON_SHIP"); ReloadProgressUpdate();
  203. LayerAddObject(SEA_EXECUTE, &PeopleOnShip, 100);
  204. LayerAddObject(SEA_REALIZE, &PeopleOnShip, 100);
  205.  
  206. // 1.03 - CreateEntity(&SeaLocatorShow, "SeaLocatorShow"); ReloadProgressUpdate();
  207. // KK LayerAddObject(SEA_REALIZE, &SeaLocatorShow, -1); // since we hadn't created entity...
  208.  
  209. CreateEntity(&Telescope, "TELESCOPE"); ReloadProgressUpdate();
  210. LayerAddObject(SEA_EXECUTE, &Telescope, -1);
  211. LayerAddObject(SEA_REALIZE, &Telescope, -3);
  212. TelescopeInitParameters(&Telescope);
  213.  
  214. CreateSeaAnimals(); ReloadProgressUpdate();
  215.  
  216. // create all other environment
  217. CreateBallsEnvironment(); ReloadProgressUpdate();
  218. CreateCannonsEnvironment(); ReloadProgressUpdate();
  219. CreateShipEnvironment(); ReloadProgressUpdate();
  220. CreateFortEnvironment(); ReloadProgressUpdate();
  221. CreateAbordageEnvironment(); ReloadProgressUpdate();
  222. CreateSeaGoodsEnvironment(); ReloadProgressUpdate();
  223.  
  224. SetEventHandler(SHIP_CREATE, "Ship_Walk_Create", 0);
  225. SetEventHandler("MSG_TELESCOPE_REQUEST", "Telescope_Request", 0);
  226. SetEventHandler(SHIP_BORT_FIRE, "Ship_BortFire", 0);
  227.  
  228. CreateSeaCamerasEnvironment(); ReloadProgressUpdate(); // KK
  229.  
  230. bNotEnoughBalls = false;
  231.  
  232. if (CANNONPOWDER_MOD) {// TIH --> mod toggle 7-7-06
  233. ref mCh = GetMainCharacter();
  234. int fPwdr = 0;
  235. int pwdrQty = GetCargoGoodsSimple(mCh, GOOD_GUNPOWDER);
  236. ref rCannon; makeref(rCannon,Cannon[GetCaracterShipCannonsType(mCh)]);
  237. if(CheckAttribute(rCannon,"gunpowder")) fPwdr = sti(rCannon.gunpowder);
  238. if( pwdrQty < sti( GetCannonArcCurQty(mCh, 0)) * fPwdr || pwdrQty < sti(GetCannonArcCurQty(mCh, 2)) * fPwdr )
  239. {
  240. if(mCh.Ship.Cannons.Type != CANNON_TYPE_NONECANNON)
  241. {
  242. Log_SetStringToLog(TranslateString("","Captain, we're out of gunpowder!"));
  243. }
  244. }
  245. }// TIH <-- mod toggle
  246.  
  247. Sharks.execute = SEA_EXECUTE;
  248. Sharks.realize = SEA_REALIZE;
  249. Sharks.executeModels = 75;
  250. Sharks.realizeModels = 75;
  251. Sharks.executeParticles = 78;
  252. Sharks.realizeParticles = 100001;
  253.  
  254. CreateEntity(&Sharks, "Sharks"); ReloadProgressUpdate();
  255.  
  256. PeopleOnShip.isNight = Whr_IsNight();
  257. chrWaitReloadLocator = "";//MAXIMUS
  258. if(FCOHS) FCoHS_Main_Start(); // FCoHS
  259. }
  260.  
  261. void Sea_LandLoad()
  262. {
  263. bSeaReloadStarted = true;
  264. PauseAllSounds();
  265. ResetSoundScheme();
  266.  
  267. if (!bSeaActive) return;
  268. if (bCanEnterToLand) {
  269. LayerFreeze("realize", false);
  270. LayerFreeze("execute", false);
  271.  
  272. // KK -->
  273. if (bDeckEnter)
  274. {
  275. AnchorDrop();
  276. return;
  277. }
  278. // <-- KK
  279. ClearDeck();//MAXIMUS
  280.  
  281. // added after build 11 by KAM -->
  282. ref tempMainChar = GetMainCharacter();
  283. tempMainChar.ShipBerthing.DoInvoice = true;
  284. // <-- added after build 11 by KAM
  285.  
  286. ResetSquadronWoundedCrew(); // KK
  287. CancelAllGunReadySounds(); // KK
  288.  
  289. // Maximus & PB: Lower sails and play sound when anchoring -->
  290. if (sti(tempMainChar.LastSailState) != 0) SendMessage(&AISea, "laf", AI_MESSAGE_SHIP_SET_SAIL_STATE, tempMainChar, 0.0);
  291. // KK -->
  292. DeleteAttribute(tempMainChar, "LastSailState");
  293. tempMainChar.Anchoring = true;
  294. Log_SetActiveAction("Nothing");
  295.  
  296. if (stf(tempMainChar.Ship.Speed.z) != 0.0) PlaySound("anchor"); // NK
  297. // <-- KK
  298. }
  299. }
  300.  
  301. // KK -->
  302. void Sea_ImmediateLandLoad(bool toFort)
  303. {
  304. bSeaReloadStarted = true;
  305. PauseAllSounds();
  306. ResetSoundScheme();
  307.  
  308. if (bSeaActive == false) return;
  309. if (bCanEnterToLand == true)
  310. {
  311. SeaCameras_Switch();
  312. SeaCameras_Switch();
  313.  
  314. LayerFreeze("realize", false);
  315. LayerFreeze("execute", false);
  316.  
  317. // added after build 11 by KAM -->
  318. ref tempMainChar = GetMainCharacter();
  319. tempMainChar.ShipBerthing.DoInvoice = true;
  320. // <-- added after build 11 by KAM
  321.  
  322. ResetSquadronWoundedCrew(); // KK
  323. CancelAllGunReadySounds(); // KK
  324.  
  325. // Maximus & PB: Lower sails and play sound when anchoring -->
  326. if (sti(tempMainChar.LastSailState) != 0) SendMessage(&AISea, "laf", AI_MESSAGE_SHIP_SET_SAIL_STATE, tempMainChar, 0.0);
  327. // KK -->
  328. DeleteAttribute(tempMainChar, "LastSailState");
  329. tempMainChar.Anchoring = true;
  330. tempMainChar.Anchoring.Immediate = true;
  331. Log_SetActiveAction("Nothing");
  332. if (toFort) tempMainChar.location.Fort = true;
  333.  
  334. if (stf(tempMainChar.Ship.Speed.z) != 0.0) PlaySound("anchor"); // NK
  335. // <-- KK
  336. }
  337. }
  338.  
  339. //#event_handler("LAi_deck", "GoToDeck");
  340. void GoToDeck()
  341. {
  342. Sea_DeckStartNow(GetMainCharacterIndex(), GetCharacterShipQDeck(GetMainCharacter()));
  343. }
  344. // <-- KK
  345.  
  346. //#event_handler("LAi_anchor", "AnchorDrop");
  347. void AnchorDrop()
  348. {
  349. // KK -->
  350. ref mchr = GetMainCharacter();
  351. string sLocator = sIslandLocator;
  352. ClearDeck();//MAXIMUS
  353. if (CheckAttribute(mchr, "location.Fort")) {
  354. if (sti(mchr.location.Fort) == true) sLocator = sAbordageLocator;
  355. DeleteAttribute(mchr, "location.Fort");
  356. }
  357. Reload(arIslandReload, sLocator, sIslandID);
  358. bSeaActive = false;//MAXIMUS: used for new "Mutiny" [just to be sure]
  359. // <-- KK
  360. }
  361. // Maximus & PB: Lower sails and play sound when anchoring <--
  362.  
  363. // [abordage MOD] -->
  364. #event_handler("Ship_BranderDetonate", "Lai_ToBlowUp");
  365. void Lai_ToBlowUp()
  366. {
  367. aref blowingLoser = GetEventData();
  368. Ship_Detonate(blowingLoser, true, true);
  369. }
  370. // [abordage MOD] <--
  371.  
  372. void Sea_MapStartFade()
  373. {
  374. DelEventHandler("FaderEvent_StartFade", "Sea_MapStartFade");
  375. DeleteSeaEnvironment();
  376. }
  377.  
  378. void Sea_MapEndFade()
  379. {
  380. DelEventHandler("FaderEvent_EndFade", "Sea_MapEndFade");
  381.  
  382. wdmCreateMap(SeaMapLoadX, SeaMapLoadZ, SeaMapLoadAY);
  383.  
  384. // PB: Update Changed Flag -->
  385. int cc, compIdx;
  386. ref PChar = GetMainCharacter();
  387. if(CheckAttribute(PChar, "orgnation")) // checks if you just hoisted Jolly Roger
  388. {
  389. PChar.nation = PChar.orgnation;
  390.  
  391. for(cc = 1; cc < COMPANION_MAX; cc++)
  392. {
  393. compIdx = GetCompanionIndex(PChar, cc);
  394. if(compIdx < 0) continue;
  395. if(GetRemovable(GetCharacter(compIdx)))
  396. {
  397. Characters[compIdx].nation = PChar.orgnation;
  398. Characters[compIdx].Flags.DoRefresh = true;
  399. }
  400. }
  401. if (ENABLE_FLAGS == 1) {
  402. HoistFlag(PChar.orgnation);
  403. SetRelationsForFlag(PChar.orgnation);
  404. }
  405. DeleteAttribute(PChar,"orgnation"); // so that rel resetting runs only once after flaghoisting
  406. LogIt(TranslateString("", "You hide the Jolly Roger and hoist your former flag again"));
  407. }
  408. // PB: Update Changed Flag <--
  409. }
  410.  
  411. void Sea_MapLoadXZ_AY(float x, float z, float ay)
  412. {
  413. bSkipSeaLogin = true; // NK fix 05-07-16 to be sure we don't hit the getseatime<3 hack.
  414. Sea_MapLoad();
  415.  
  416. SeaMapLoadX = x;
  417. SeaMapLoadZ = z;
  418. SeaMapLoadAY = ay;
  419. }
  420.  
  421. void Sea_MapLoad()
  422. {
  423. //int tmpLangFileID = LanguageOpenFile("interface_strings.txt");
  424. if(GetSeaTime() < 3 && !bSkipSeaLogin) {
  425. LogIt(TranslateString("","Wait a sec while I get out the chart, captain!"));
  426. PlaySound("interface\knock.wav");
  427. return;
  428. } // NK so you must be on sea >= 3 seconds. 05-04-23
  429. bSeaReloadStarted = true;
  430. PauseAllSounds();
  431.  
  432. ResetSoundScheme();
  433.  
  434. SetEventHandler("FaderEvent_StartFade", "Sea_MapStartFade", 0);
  435. SetEventHandler("FaderEvent_EndFade", "Sea_MapEndFade", 0);
  436.  
  437. CreateEntity(&wdm_fader, "fader");
  438. SendMessage(&wdm_fader, "lfl", FADER_OUT, 0.7, true);
  439. SendMessage(&wdm_fader, "l", FADER_STARTFRAME);
  440. SendMessage(&wdm_fader, "ls", FADER_PICTURE, FindReloadPicture("sea.tga")); // KK
  441.  
  442. bSkipSeaLogin = true;
  443.  
  444. ref rPlayer = GetMainCharacter();
  445.  
  446. SeaMapLoadX = stf(rPlayer.Ship.Pos.x);
  447. SeaMapLoadZ = stf(rPlayer.Ship.Pos.z);
  448. SeaMapLoadAY = stf(rPlayer.Ship.Ang.y);
  449. //LanguageCloseFile(tmpLangFileID);
  450. // ResetTimeToNormal();//MAXIMUS: removes time-acceleration and sets normal time
  451. }
  452.  
  453. void Land_MapLoad()
  454. {
  455. bSeaReloadStarted = true;
  456. PauseAllSounds();
  457.  
  458. ResetSoundScheme();
  459.  
  460. SetEventHandler("FaderEvent_StartFade", "Land_MapStartFade", 0);
  461. SetEventHandler("FaderEvent_EndFade", "Sea_MapEndFade", 0);
  462.  
  463. CreateEntity(&wdm_fader, "fader");
  464. SendMessage(&wdm_fader, "lfl", FADER_OUT, 0.7, true);
  465. SendMessage(&wdm_fader, "l", FADER_STARTFRAME);
  466. SendMessage(&wdm_fader, "ls", FADER_PICTURE, FindReloadPicture("sea.tga"));
  467.  
  468. bSkipSeaLogin = true;
  469.  
  470. SeaMapLoadX = stf(characters[GetMainCharacterIndex()].Ship.Pos.x);
  471. SeaMapLoadZ = stf(characters[GetMainCharacterIndex()].Ship.Pos.z);
  472. SeaMapLoadAY = stf(characters[GetMainCharacterIndex()].Ship.Ang.y);
  473. }
  474.  
  475. void Land_MapStartFade()
  476. {
  477. DelEventHandler("FaderEvent_StartFade", "Land_MapStartFade");
  478. ref PChar = GetMainCharacter();
  479. if(CheckAttribute(PChar,"location") && PChar.location!="" && FindLocation(PChar.location)!=-1)
  480. {
  481. UnloadLocation(&locations[FindLocation(PChar.location)]);
  482. }
  483. // ResetTimeToNormal();
  484. }
  485.  
  486. string sTaskList[2];
  487.  
  488. void Sea_FreeTaskList()
  489. {
  490. ref rMassive;
  491. makeref(rMassive, sTaskList);
  492. SetArraySize(rMassive, 2);
  493. }
  494.  
  495. void Sea_AddGroup2TaskList(string sGroupID)
  496. {
  497. ref rMassive;
  498. makeref(rMassive, sTaskList);
  499. int iSize = GetArraySize(rMassive);
  500. SetArraySize(rMassive, iSize + 1);
  501. sTaskList[iSize-2] = sGroupID;
  502. }
  503.  
  504. void Sea_LoginGroupNow(string sGroupID)
  505. {
  506. LoginGroupsNow.QuestGroups = "";
  507. aref arGroups; makearef(arGroups, LoginGroupsNow.QuestGroups);
  508. string sID = "n" + GetAttributesNum(arGroups);
  509. arGroups.(sID) = sGroupID;
  510. }
  511.  
  512.  
  513. void SeaLogin(ref Login)
  514. {
  515. Trace("SEA: SeaLogin begin");
  516. int i, j, iShipType, iNumQCGroups, iNShips, iCharacterIndex;
  517. float x, y, z, ay;
  518. ref rCharacter, rGroup, rEncounter;
  519. aref rRawGroup, arQCGroups, arEncounters;
  520. string sGName, l;
  521. bool bDirectSail = CheckAttribute(Login, "DirectSail"); // KK
  522. bool bLoadSavedGame = CheckAttribute(Login, "LoadAtSea") && !bDirectSail; // KK
  523.  
  524. int iRDTSC = RDTSC_B();
  525.  
  526. // clear load groups now object
  527. DeleteAttribute(&LoginGroupsNow, "");
  528.  
  529. iStormLockSeconds = 0;
  530. iNumFantoms = 0;
  531. bSkipSeaLogin = false;
  532. bSeaReloadStarted = false;
  533. bSeaQuestGroupHere = false;
  534. bIslandLoaded = false;
  535.  
  536. fSeaExp = 0.0;
  537. fSeaExpTimer = 0.0;
  538. // NK 04-09-21 timeupdate
  539. if(TIMEUPDATE_BLOCK_LAND)
  540. {
  541. AddTimeToCurrent(0, (locTmpTime * TIMESCALAR_LAND)/60);
  542. }
  543. locTmpTime = 0.0;
  544. // NK <--
  545.  
  546. Sea_FreeTaskList();
  547. Encounter_DeleteDeadQuestMapEncounters();
  548.  
  549. // KK -->
  550. if (!bDirectSail) {
  551. // weather parameters
  552. if (!bLoadSavedGame) {
  553. WeatherParams.Tornado = false;
  554. WeatherParams.Storm = false;
  555. }
  556. if (CheckAttribute(Login,"Storm")) WeatherParams.Storm = Login.Storm;
  557. if (CheckAttribute(Login,"Tornado")) WeatherParams.Tornado = Login.Tornado;
  558. bStorm = sti(WeatherParams.Storm);
  559. bTornado = sti(WeatherParams.Tornado);
  560. if (bStorm) iStormLockSeconds = 60;
  561. }
  562.  
  563. // Island
  564. int iIslandIndex = FindIsland(Login.Island);
  565. //Trace("Island id = " + Login.Island + ", Island index = " + iIslandIndex);
  566. string sIslandID = "";
  567. if (iIslandIndex != -1) sIslandID = Islands[iIslandIndex].id;
  568.  
  569. // main character
  570. ref rPlayer = GetMainCharacter();
  571. rPlayer.Ship.Stopped = false;
  572. //DeleteAttribute(rPlayer, "LastSailState"); // NK 05-04-20 so it doesn't say it during loading
  573. rPlayer.Ship.POS.Mode = SHIP_SAIL;
  574. rPlayer.location = Login.Island;
  575.  
  576. if (bDirectSail) rPlayer.BaseCurrentTime = 0.0; //Screwface : fix to restart Sea ai update as soon as sea reload
  577.  
  578. // clear old fantom relations in our character
  579. if (!bLoadSavedGame && CheckAttribute(rPlayer, "Relation")) // KK
  580. {
  581. aref arRelations; makearef(arRelations, rPlayer.Relation);
  582. int iNumRelations = GetAttributesNum(arRelations);
  583. for (i=0; i<iNumRelations; i++)
  584. {
  585. aref arRelation = GetAttributeN(arRelations, i);
  586. string sRName = GetAttributeName(arRelation);
  587. if (sti(sRName) >= FANTOM_CHARACTERS)
  588. {
  589. DeleteAttribute(arRelations, sRName);
  590. iNumRelations--;
  591. i--;
  592. }
  593. }
  594. }
  595.  
  596. // Quest check
  597. if (!bLoadSavedGame) { // KK
  598. Event(EVENT_SEA_LOGIN, "");
  599. if (bSkipSeaLogin) return;
  600. }
  601.  
  602. // KK -->
  603. if (ENABLE_FLAGS && !bLoadSavedGame && !bDirectSail)
  604. {
  605. int MyFlag = GetCurrentFlag();
  606. bRecognized = false;
  607. if (iForceDetectionFalseFlag == 1)
  608. {
  609. MyFlag = PERSONAL_NATION;
  610. bRecognized = true;
  611. if (iRealismMode<2) Log_SetStringToLog(TranslateString("", "We are recognized, captain!"));
  612. }
  613. HoistFlag(MyFlag);
  614. SetRelationsForFlag(MyFlag);
  615. }
  616.  
  617. if (!bLoadSavedGame) {
  618. if (!IsEntity(&SeaFader)) {
  619. // Sea Fader start
  620. if (!CheckAttribute(&Login,"ImageName")) Login.ImageName = "sea.tga";
  621.  
  622. CreateEntity(&SeaFader, "fader");
  623. SendMessage(&SeaFader, "lfl", FADER_IN, 0.5, true);
  624. SendMessage(&SeaFader, "ls", FADER_PICTURE0, FindReloadPicture(Login.ImageName));
  625. }
  626. }
  627. // <-- KK
  628.  
  629. // create all sea modules
  630. CreateSeaEnvironment();
  631.  
  632. Sea.MaxSeaHeight = 50.0;
  633.  
  634. ReloadProgressUpdate();
  635.  
  636. float wdmBaseX, wdmBaseZ; // WM base coords for fleets 05-05-02
  637.  
  638. // login island if exist
  639. if (sIslandID != "")
  640. {
  641. trace("SEA: sealogin loading island " + sIslandID);
  642. CreateEntity(&Island, "Island");
  643. Island.LightingPath = GetLightingPath();
  644.  
  645. if (GetTargetPlatform() != "xbox")
  646. {
  647. //CreateEntity(&SeaLighter, "lighter"); // PB: Enable Loc Lighter at sea with this
  648. SendMessage(&SeaLighter, "ss", "ModelsPath", Islands[iIslandIndex].filespath.models);
  649. SendMessage(&SeaLighter, "ss", "LightPath", GetLightingPath());
  650. }
  651.  
  652. SendMessage(&Island, "lsss", MSG_ISLAND_LOAD_GEO, "islands", Islands[iIslandIndex].filespath.models, Islands[iIslandIndex].model);
  653. LayerAddObject(SEA_REALIZE, &Island, 65529);
  654. LayerAddObject("mast_island_trace", &Island, 1);
  655. LayerAddObject("sun_trace", &Island, 1);
  656.  
  657. CreateEntity(&IslandReflModel, "MODELR");
  658. string sReflModel = Islands[iIslandIndex].filespath.models + "\" + Islands[iIslandIndex].refl_model;
  659. SendMessage(&IslandReflModel, "ls", MSG_MODEL_SET_LIGHT_PATH, GetLightingPath());
  660. SendMessage(&IslandReflModel, "ls", MSG_MODEL_LOAD_GEO, sReflModel);
  661. LayerAddObject("sea_reflection", &IslandReflModel, -1);
  662. SendMessage(SeaLighter, "ssi", "AddModel", Islands[iIslandIndex].refl_model, &IslandReflModel);
  663.  
  664. bIslandLoaded = true;
  665.  
  666. SendMessage(&SeaLocatorShow, "a", &Islands[iIslandIndex]);
  667. Fort_Login(iIslandIndex);
  668.  
  669. if(!bstorm) Sea.MaxSeaHeight = 3.0; // screwface : allow big waves around island in storm conditions
  670. // WM base coords for fleets 05-05-02 -->
  671. // 05-05-03 get correct wdm name for island.
  672. string wdmisland = wdmGetIslandNameFromID(sIslandID);
  673. if (wdmisland != "" && CheckAttribute(worldMap,".islands."+wdmisland)) {
  674. wdmBaseX = MakeFloat(worldMap.islands.(wdmisland).position.rx);
  675. wdmBaseZ = MakeFloat(worldMap.islands.(wdmisland).position.rz);
  676. } else {
  677. wdmBaseX = makefloat(worldMap.playerShipX);
  678. wdmBaseZ = makefloat(worldMap.playerShipZ);
  679. }
  680. } else {
  681. wdmBaseX = makefloat(worldMap.playerShipX);
  682. wdmBaseZ = makefloat(worldMap.playerShipZ);
  683. } // WM base coords for fleets 05-05-02 <--
  684. AISea.Island = sIslandID;
  685.  
  686. // KK -->
  687. // clear some of group attributes
  688. for (i=0; i<MAX_SHIP_GROUPS; i++)
  689. {
  690. rGroup = Group_GetGroupByIndex(i);
  691. if (CheckAttribute(rGroup, "AlreadyLoaded")) DeleteAttribute(rGroup, "AlreadyLoaded");
  692. }
  693.  
  694. ReloadProgressUpdate();
  695.  
  696. // login main player and his friends
  697. int iMainCharacter = GetMainCharacterIndex();
  698. int iCompanionIndex = -1;
  699. ref rCompanion;
  700.  
  701. // delete our group
  702. Group_DeleteGroup(PLAYER_GROUP);
  703. Group_DeleteGroup(MUTINY_GROUP);
  704.  
  705. if(CheckAttribute(rPlayer,"fallen")) // Screwface : Need to restore the fallen mast(s) to avoid crashes with set flags
  706. {
  707. DeleteAttribute(rPlayer,"ship.sails");
  708. DeleteAttribute(rPlayer,"ship.masts");
  709. DeleteAttribute(rPlayer,"fallen");
  710. Trace("Player mast restored");
  711. }
  712.  
  713. // from coast check (move / stop)
  714. if (!bLoadSavedGame) {
  715. bFromCoast = false;
  716. if (CheckAttribute(Login, "FromCoast")) bFromCoast = sti(Login.FromCoast);
  717.  
  718. Group_AddCharacter(PLAYER_GROUP, rPlayer.id);
  719. // set commander to group
  720. Group_SetGroupCommander(PLAYER_GROUP, rPlayer.id);
  721. // set our group position
  722. Group_SetXZ_AY(PLAYER_GROUP, stf(Login.PlayerGroup.x), stf(Login.PlayerGroup.z), stf(Login.PlayerGroup.ay) );
  723. //Trace("Set group : " + PLAYER_GROUP + ", x = " + Login.PlayerGroup.x + ", z = " + Login.PlayerGroup.z + ", ay = " + Login.PlayerGroup.ay);
  724. rPlayer.SeaAI.Group.Name = PLAYER_GROUP;
  725. //rPlayer.Ship.Type = Characters[iMainCharacter].Ship.Type;
  726. rPlayer.Ship.Stopped = false;
  727. rPlayer.LastSailState = (!bFromCoast) * 2;
  728. Ship_Add2Sea(iMainCharacter, bFromCoast, "");
  729. trace("SEA: added pchar to sea");
  730. for (i = 1; i < COMPANION_MAX; i++)
  731. {
  732. iCompanionIndex = GetCompanionIndex(rPlayer, i);
  733. if (iCompanionIndex < 0) continue;
  734. if(CheckAttribute(&Characters[iCompanionIndex],"fallen")) // Screwface : Need to restore the fallen mast(s) to avoid crashes with set flags
  735. {
  736. DeleteAttribute(&Characters[iCompanionIndex],"ship.sails");
  737. DeleteAttribute(&Characters[iCompanionIndex],"ship.masts");
  738. DeleteAttribute(&Characters[iCompanionIndex],"fallen");
  739. Trace("Companion mast restored");
  740. }
  741. rCompanion = GetCharacter(iCompanionIndex);
  742. rCompanion.SeaAI.Group.Name = PLAYER_GROUP;
  743. Ship_Add2Sea(iCompanionIndex, bFromCoast, "");
  744. // add companion to player group
  745. Group_AddCharacter(PLAYER_GROUP, rCompanion.id);
  746. }
  747. //trace("added comps to sea");
  748.  
  749. // login encounters
  750. // login quest group if island exist
  751. ReloadProgressUpdate();
  752.  
  753. if (bDirectSail == false && sIslandID != "") { // ccc CR
  754. if (AUTOCREATE_CR == 1) SetCoastTraffic(sIslandID);
  755. trace("SEA: Did CRs");
  756. }
  757. if (bDirectSail && CheckAttribute(rPlayer,"directsail.toisland")) { // if DirectsailCheck() calls islandchange coastal ships are created
  758. if (AUTOCREATE_CR == 1) SetCoastTraffic(sIslandID);
  759. trace("SEA: Did CRs");
  760. }
  761.  
  762. if (sIslandID != "")
  763. {
  764. for (i=0; i<MAX_SHIP_GROUPS; i++)
  765. {
  766. rGroup = Group_GetGroupByIndex(i);
  767. if (!CheckAttribute(rGroup,"AlreadyLoaded")) DeleteAttribute(rGroup,"AlreadyLoaded"); // NK: HUH!?
  768.  
  769. if (!CheckAttribute(rGroup, "id")) { continue; }
  770. if (!CheckAttribute(rGroup, "location")) { continue; }
  771. if (rGroup.location != sIslandID) { continue; }
  772. Sea_LoginGroup(rGroup.id);
  773. }
  774. }
  775. trace("SEA: Did any groups");
  776.  
  777. // login quest groups to sea
  778. if (CheckAttribute(Login, "QuestGroups"))
  779. {
  780. arQCGroups; makearef(arQCGroups, Login.QuestGroups);
  781. iNumQCGroups = GetAttributesNum(arQCGroups);
  782. for (i=0; i<iNumQCGroups; i++)
  783. {
  784. Sea_LoginGroup(GetAttributeValue(GetAttributeN(arQCGroups, i)));
  785. }
  786. }
  787.  
  788. ReloadProgressUpdate();
  789.  
  790. // login quest groups to sea from LoginGroupsNow object
  791. if (CheckAttribute(&LoginGroupsNow, "QuestGroups"))
  792. {
  793. makearef(arQCGroups, LoginGroupsNow.QuestGroups);
  794. iNumQCGroups = GetAttributesNum(arQCGroups);
  795. for (i=0; i<iNumQCGroups; i++)
  796. {
  797. Sea_LoginGroup(GetAttributeValue(GetAttributeN(arQCGroups, i)));
  798. }
  799. }
  800. }
  801.  
  802. ReloadProgressUpdate();
  803.  
  804. if (!bDirectSail && !bLoadSavedGame) {
  805. // login fantom groups
  806. makearef(arEncounters,Login.Encounters);
  807. int iNumGroups = GetAttributesNum(arEncounters);
  808.  
  809. for (i=0; i<iNumGroups; i++)
  810. {
  811. rRawGroup = GetAttributeN(arEncounters, i);
  812. rEncounter = GetMapEncounterRef(sti(rRawGroup.type));
  813. sGName = rEncounter.GroupName;
  814.  
  815. x = stf(rRawGroup.x);
  816. z = stf(rRawGroup.z);
  817. ay = stf(rRawGroup.ay);
  818.  
  819. ReloadProgressUpdate();
  820.  
  821. // check for Quest fantom
  822. if (CheckAttribute(rEncounter, "qID"))
  823. {
  824. Trace("SEA: Login quest encounter " + rEncounter.qID);
  825. Group_SetAddressNone(rEncounter.qID);
  826. Group_SetXZ_AY(rEncounter.qID, x, z, ay);
  827. Sea_LoginGroup(rEncounter.qID);
  828.  
  829. continue;
  830. }
  831.  
  832. // NK disable this, it kills encounters if there are local ships -- if (bSeaQuestGroupHere) { continue; }
  833. Sea_AddGroup2TaskList(sGName);
  834.  
  835. rGroup = Group_GetGroupByIndex(Group_CreateGroup(sGName));
  836. Group_SetXZ_AY(sGName, x, z, ay);
  837. Group_SetType(sGName, rEncounter.Type);
  838. Group_DeleteAtEnd(sGName);
  839.  
  840. // copy task attributes from map encounter to fantom group
  841. if (CheckAttribute(rEncounter, "Task")) { rGroup.Task = rEncounter.Task; }
  842. if (CheckAttribute(rEncounter, "Task.Target")) { rGroup.Task.Target = rEncounter.Task.Target; }
  843. if (CheckAttribute(rEncounter, "Task.Pos"))
  844. {
  845. rGroup.Task.Target.Pos.x = rEncounter.Task.Pos.x;
  846. rGroup.Task.Target.Pos.z = rEncounter.Task.Pos.z;
  847. }
  848. if (CheckAttribute(rEncounter, "Lock") && sti(rEncounter.Lock)) { Group_LockTask(sGName); }
  849.  
  850. int iEncounterType = sti(rEncounter.RealEncounterType);
  851. int iNation = sti(rEncounter.Nation);
  852. iNShips = Fantom_GenerateEncounter(sGName, iEncounterType, iNation); // NK
  853.  
  854. Trace("SEA: Set group : " + sGName + ", x = " + x + ", z = " + z);
  855.  
  856. // load ship to sea
  857. if (iNShips > 0) {
  858. int iGeraldSails = -1;
  859. if (CheckAttribute(rEncounter, "GeraldSails")) iGeraldSails = sti(rEncounter.GeraldSails);
  860. LoadShipsToSea(iNShips, sGName, iNation, iGeraldSails);
  861. }
  862. }
  863. } else {
  864. if (bDirectSail && CheckAttribute(rPlayer, "directsail.encounter")) { // if set so in DirectsailCheck() random encounter ships are created
  865. rPlayer.ship.pos.x = stf(Login.PlayerGroup.x); // so that DirectEncounter doesn't use OLD coords
  866. rPlayer.ship.pos.z = stf(Login.PlayerGroup.z);
  867. DirectEncounter(stf(Login.PlayerGroup.ay));
  868. DeleteAttribute(rPlayer,"directsail"); // clears tags from player
  869. }
  870. if (bLoadSavedGame) {
  871. iNShips = sti(Login.Ship.Quantity);
  872. for (i = 0; i < iNShips; i++) {
  873. l = "l" + i;
  874. // Screwface : If you saved while a ship was sinking (still dead icon in Binterface menu) the next time you loaded your save
  875. // the l attribute was missing and icharacterIndex was set to 0 so you had a clone of you as temporary companion !!! The line below avoid that !
  876. if(!CheckAttribute(&Login,"Ship."+(l))) continue; // Screwface
  877. iCharacterIndex = sti(Login.Ship.(l).idx);
  878. if (iCharacterIndex < 0) continue;
  879. rCharacter = GetCharacter(iCharacterIndex);
  880. if (CharacterIsDead(rCharacter)) continue;
  881. Sea_LoginShip(rCharacter);
  882. Ship_Login(iCharacterIndex);
  883. }
  884. }
  885. }
  886. trace("SEA: added ships");
  887.  
  888. CreateFlagEnvironment();
  889.  
  890. // set ship for sea camera
  891. SeaCameras_SetShipForSeaCamera(rPlayer);
  892. // <-- KK
  893.  
  894. ReloadProgressUpdate();
  895.  
  896. // KK -->
  897. // set tasks 2 all groups
  898. int c, iRelation; //NK bugfix 5-1
  899. string sGroupID;
  900. if (!bLoadSavedGame) {
  901. for (i=0; i<GetArraySize(&sTaskList)-2; i++)
  902. {
  903. sGroupID = sTaskList[i];
  904. rGroup = Group_GetGroupByID(sGroupID);
  905.  
  906. // set task
  907. switch (sti(rGroup.Task))
  908. {
  909. case AITASK_RUNAWAY:
  910. Group_SetTaskRunAway(sGroupID);
  911. break;
  912. case AITASK_ATTACK:
  913. Group_SetTaskAttack(sGroupID, rGroup.Task.Target);
  914. break;
  915. case AITASK_MOVE:
  916. if (CheckAttribute(rGroup, "Task.Target.Pos"))
  917. {
  918. Group_SetTaskMove(sGroupID, stf(rGroup.Task.Target.Pos.x), stf(rGroup.Task.Target.Pos.z));
  919. }
  920. else
  921. {
  922. x = 10000.0 * sin(stf(rGroup.Pos.ay));
  923. z = 10000.0 * cos(stf(rGroup.Pos.ay));
  924. Group_SetTaskMove(sGroupID, x, z);
  925. }
  926. break;
  927. }
  928.  
  929. rCharacter = Group_GetGroupCommanderR(rGroup);
  930. iRelation = GetRelation(iMainCharacter, sti(rCharacter.index));
  931.  
  932. // set relations to all characters in this group
  933. c = 0; // NK bugfix, they used to use i (!!!) here.
  934. while (true)
  935. {
  936. iCharacterIndex = Group_GetCharacterIndexR(rGroup, c);
  937. c++;
  938. if (iCharacterIndex < 0) break;
  939. SetCharacterRelationBoth(iCharacterIndex, iMainCharacter, iRelation);
  940. }
  941. }
  942. } else {
  943. for (i = 0; i < iNumShips; i++) {
  944. iCharacterIndex = Ships[i];
  945. if (iCharacterIndex < 0) continue;
  946. rCharacter = GetCharacter(iCharacterIndex);
  947. if (CheckAttribute(rCharacter, "SeaAI.Group.MainCharacter") == true && sti(rCharacter.SeaAI.Group.MainCharacter) == true && iCharacterIndex != iMainCharacter) {
  948. sGroupID = GetGroupIDFromCharacter(rCharacter);
  949. switch (sti(rCharacter.SeaAI.Task))
  950. {
  951. case AITASK_ATTACK:
  952. iCompanionIndex = sti(rCharacter.SeaAI.Task.Target);
  953. trace("attack target="+rCharacter.SeaAI.Task.Target+" -> "+GetGroupIDFromCharacter(GetCharacter(iCompanionIndex)));
  954. if (iCompanionIndex >= 0) Group_SetTaskAttack(sGroupID, GetGroupIDFromCharacter(GetCharacter(iCompanionIndex)));
  955. break;
  956. case AITASK_RUNAWAY:
  957. trace("runaway");
  958. Group_SetTaskRunAway(sGroupID);
  959. break;
  960. case AITASK_MOVE:
  961. trace("move to x="+rCharacter.SeaAI.Task.Pos.x+", z="+rCharacter.SeaAI.Task.Pos.z);
  962. Group_SetTaskMove(sGroupID, stf(rCharacter.SeaAI.Task.Pos.x), stf(rCharacter.SeaAI.Task.Pos.z));
  963. break;
  964. }
  965.  
  966. iRelation = GetRelation(iMainCharacter, iCharacterIndex);
  967. // set relations to all characters in this group
  968. c = 0; // NK bugfix, they used to use i (!!!) here.
  969. while (true)
  970. {
  971. iCharacterIndex = Group_GetCharacterIndexR(Group_GetGroupByID(sGroupID), c);
  972. c++;
  973. if (iCharacterIndex < 0) break;
  974. SetCharacterRelationBoth(iCharacterIndex, iMainCharacter, iRelation);
  975. }
  976. }
  977. if (CheckAttribute(rCharacter, "SeaAI.Group.MainCharacter")) DeleteAttribute(rCharacter, "SeaAI.Group.MainCharacter");
  978. }
  979. }
  980. trace("SEA: Set tasks");
  981.  
  982. AISea.isDone = "";
  983. trace("updated AISea");
  984.  
  985. if (bLoadSavedGame) {
  986. for (c = 0; c < iNumShips; c++)
  987. {
  988. iCharacterIndex = Ships[c];
  989. if (iCharacterIndex < 0) continue;
  990. rCharacter = GetCharacter(iCharacterIndex);
  991. sGroupID = GetGroupIDFromCharacter(rCharacter);
  992. if (hasSubStr(sGroupID, "tmpgrp_")) {
  993. Group_DelCharacter(sGroupID, rCharacter.id);
  994. Group_DeleteGroup(sGroupID);
  995. sGroupID = strcut(sGroupID, 7, strlen(sGroupID) - 3);
  996. Group_AddCharacter(sGroupID, rCharacter.id);
  997. }
  998. }
  999. }
  1000. // <-- KK
  1001. // Screwface : Restored as original because of too many CTDs at sea login
  1002. InitBattleInterface(); ReloadProgressUpdate();
  1003. StartBattleInterface(); ReloadProgressUpdate();
  1004. RefreshBattleInterface(); ReloadProgressUpdate();
  1005. // Screwface : End
  1006.  
  1007. CreateEntity(&Seafoam,"Seafoam"); ReloadProgressUpdate();
  1008. LayerAddObject(SEA_EXECUTE, &Seafoam, -1);
  1009. LayerAddObject(SEA_REALIZE, &Seafoam, -1);
  1010. DeleteAttribute(rPlayer, "scrollchars"); // PB: For Cheatmode
  1011. for (c = 0; c <= GetCompanionQuantity(rPlayer); c++) {
  1012. rCharacter = GetCharacter(GetCompanionIndex(rPlayer, sti(c)));
  1013. DeleteAttribute(rCharacter, "Ship.Sink"); // PB: To make sure this is gone
  1014. }
  1015. if (Whr_IsStorm())
  1016. {
  1017. Seafoam.storm = "true";
  1018. rPlayer.Capsize.Warning = ROLL_ANGLE_WARNING; // PB: Reset capsize danger
  1019. }
  1020. InitOpenSeaMod(); // stljeffbb Jan 15 2012
  1021. trace("Seafoam done");
  1022.  
  1023. /*CreateEntity(&SeaOperator, "SEA_OPERATOR");
  1024. LayerAddObject(SEA_EXECUTE, &SeaOperator, -1);
  1025. LayerAddObject(SEA_REALIZE, &SeaOperator, 3);*/
  1026.  
  1027. SendMessage(&Telescope, "leee", MSG_TELESCOPE_INIT_ARRAYS, &Nations, &ShipsTypes, &Goods);
  1028. trace("Telescope initiated");
  1029.  
  1030. PostEvent(SHIP_CHECK_RELOAD_ENABLE, 100);
  1031.  
  1032. SetSchemeForSea(); ReloadProgressUpdate(); //Screwface : Restored and removed from Battleinterface.c because of CTD
  1033.  
  1034. SetCorrectWorldMapPosition(); //Screwface
  1035.  
  1036. iRDTSC = RDTSC_E(iRDTSC);
  1037. //Trace("SeaLogin RDTSC = " + iRDTSC);
  1038. //Trace("iNumShips = " + iNumShips);
  1039.  
  1040. PostEvent("Sea_FirstInit", 100);
  1041. Trace("SEA: SeaLogin end");
  1042. }
  1043.  
  1044. // KK -->
  1045. void LoadShipsToSea(int iNumShips, string sGName, int iNation, int iGeraldSails)
  1046. {
  1047. ref rPlayer = GetMainCharacter();
  1048. ref rCommander;
  1049. int nflag1, ntex1, nflag2, ntex2;
  1050. nflag2 = GetPirateFlag(rPlayer, &ntex2);
  1051. for (int j = 0; j < iNumShips; j++)
  1052. {
  1053. int iFantomIndex = FANTOM_CHARACTERS + iNumFantoms - iNumShips + j;
  1054. ref rFantom; makeref(rFantom, Characters[iFantomIndex]);
  1055.  
  1056. rFantom.id = "fenc_" + iFantomIndex;
  1057. rFantom.isFantom = true; // TIH used to easily tell a generated shipchar from a stored shipchar Aug27'06
  1058.  
  1059. // screwface : delete the recognized attribute
  1060. if(Checkattribute(rFantom,"recognized"))
  1061. {
  1062. DeleteAttribute(rFantom,"recognized");
  1063. DeleteAttribute(rFantom,"EnemyShipName");
  1064. DeleteAttribute(rFantom,"EnemyShipType");
  1065. } // Screwface : end
  1066.  
  1067. // set commander to group
  1068. if (j == 0) {
  1069. Group_SetGroupCommander(sGName, rFantom.id);
  1070. rCommander = rFantom;
  1071. }
  1072.  
  1073. // set random character and ship names, face id
  1074. rFantom.sex = "man";
  1075. rFantom.Nation = iNation;
  1076.  
  1077. // Screwface : We also need to reset relations with coastraiders groups if we are in island area to avoid groups of same nation firing each others
  1078. if(rPlayer.location != "" && rPlayer.location != "error")
  1079. {
  1080. string chrstr = "Cr" + rPlayer.location;
  1081. for(int k = 1; k <7; k++)
  1082. {
  1083. if(GetCharacterIndex(chrstr + k)==-1) continue;
  1084. ref cr2 = CharacterFromID(chrstr + k);
  1085. SetCharacterRelationBoth(sti(rFantom.index), sti(cr2.index), GetNationRelation(sti(rFantom.nation), sti(cr2.nation)));
  1086. }
  1087. } // Screwface : End
  1088.  
  1089. SetRandomNameToCharacter(rFantom);
  1090. SetRandomNameToShip(rFantom);
  1091. SetRandomFaceToCharacter(rFantom);
  1092.  
  1093. rFantom.location = "none";
  1094. rFantom.location.group = "";
  1095. rFantom.location.locator = "";
  1096.  
  1097. Fantom_SetRandomModel(rFantom, rFantom.fantomtype);
  1098. switch(Rand(7))
  1099. {
  1100. case 0: rFantom.quest.officertype = OFFIC_TYPE_BOATSWAIN; break;
  1101. case 1: rFantom.quest.officertype = OFFIC_TYPE_CANNONEER; break;
  1102. case 2: rFantom.quest.officertype = OFFIC_TYPE_QMASTER; break;
  1103. case 3: rFantom.quest.officertype = OFFIC_TYPE_NAVIGATOR; break;
  1104. case 4: rFantom.quest.officertype = OFFIC_TYPE_FIRSTMATE; break;
  1105. case 5: rFantom.quest.officertype = OFFIC_TYPE_CARPENTER; break;
  1106. case 6: rFantom.quest.officertype = OFFIC_TYPE_DOCTOR; break;
  1107. case 7: rFantom.quest.officertype = OFFIC_TYPE_ABORDAGE; break;
  1108. }
  1109. SetRandomNameToCharacter(rFantom); // KK
  1110. LAi_Create_Officer(rand(8), &rFantom);
  1111. rFantom.quest.officerprice = makeint((sti(rPlayer.rank) * 2 + 10)*100) - 330 + rand(40)*15 + rand(10);
  1112. LAi_NPC_Equip(rFantom, sti(rFantom.rank), true, 0.5);
  1113. // added by MAXIMUS <--
  1114. Fantom_SetRandomMoney(rFantom, rFantom.fantomtype);
  1115. if (iNation == PIRATE) {
  1116. if (j == 0) {
  1117. nflag1 = GetPirateFlag(rCommander, &ntex1);
  1118. if (nflag1 == nflag2 && ntex1 == ntex2) {
  1119. if (nflag1 == 0)
  1120. rCommander.Flags.Pirate = nflag1 + 1;
  1121. else
  1122. rCommander.Flags.Pirate = nflag1 - 1;
  1123. }
  1124. } else {
  1125. rFantom.Flags.Pirate = GetPirateFlag(rCommander, &nflag1);
  1126. rFantom.Flags.Pirate.texture = nflag1;
  1127. }
  1128. }
  1129. Ship_SetFantomData(rFantom);
  1130. Fantom_SetCannons(rFantom, rFantom.fantomtype);
  1131. Fantom_SetSails(rFantom, rFantom.fantomtype);
  1132.  
  1133. rFantom.SeaAI.Group.Name = sGName;
  1134.  
  1135. rFantom.Features.GeraldSails = false;
  1136. if (iGeraldSails > -1) rFantom.Features.GeraldSails = iGeraldSails;
  1137.  
  1138. if (CheckAttribute(rFantom, "after_1st_sailto")) DeleteAttribute(rFantom, "after_1st_sailto");
  1139. RestoreCharacter(rFantom);
  1140.  
  1141. // add fantom
  1142. Group_AddCharacter(sGName, rFantom.id);
  1143.  
  1144. // add to sea
  1145. Ship_Add2Sea(iFantomIndex, 0, rFantom.fantomtype);
  1146. }
  1147. }
  1148.  
  1149. void Sea_LoginShip(ref chr)
  1150. {
  1151. string chrid = chr.id;
  1152. if (!isEntity(&Sea)) {
  1153. trace("SEA: Error: Sea_LoginShip chrid = " + chrid + ", but Sea is not active!");
  1154. return;
  1155. }
  1156. if (!CheckAttribute(chr, "Ship.Pos.x") || !CheckAttribute(chr, "Ship.Pos.z")) {
  1157. trace("Sea_LoginShip: missing position attributes");
  1158. return;
  1159. }
  1160. if (!CheckAttribute(chr, "SeaAI.Group.name")) {
  1161. trace("Sea_LoginShip: missing group name");
  1162. return;
  1163. }
  1164.  
  1165. float x, z, ay;
  1166. x = stf(chr.Ship.Pos.x);
  1167. z = stf(chr.Ship.Pos.z);
  1168. ay = stf(chr.Ship.Ang.y);
  1169. string group = Ship_GetGroupID(chr);
  1170. if (isMainCharacter(CharacterFromID(chrid))) group = PLAYER_GROUP;
  1171. string tmpgrp = group;
  1172. if (CheckAttribute(chr, "SeaAI.Group.MainCharacter") == false || sti(chr.SeaAI.Group.MainCharacter) == false) {
  1173. int i = 1;
  1174. tmpgrp = "tmpgrp_" + group + "_" + i;
  1175. while (Group_FindGroup(tmpgrp) >= 0) {
  1176. i++;
  1177. tmpgrp = "tmpgrp_" + group + "_" + i;
  1178. }
  1179. }
  1180.  
  1181. if (Group_FindGroup(tmpgrp) >= 0) Group_DeleteGroup(tmpgrp);
  1182. Group_CreateGroup(tmpgrp);
  1183. Group_AddCharacter(tmpgrp, chrid);
  1184. Group_SetXZ_AY(tmpgrp, x, z, ay);
  1185. Group_SetGroupCommander(tmpgrp, chrid);
  1186. // Screwface : This section restore necessary attributes for the Sea AI update mod
  1187. Group_DeleteAtEnd(tmpgrp); // Important to avoid a CTD with DirectEncounters & Sea Ai Update
  1188. ref rGroup = Group_GetGroupByID(tmpgrp);
  1189. if(CheckAttribute(rGroup, "id") && !HasSubStr(rGroup.id, "Directenc"))
  1190. {
  1191. rGroup.AlreadyLoaded = "";
  1192. ref Pchar = GetMainCharacter();
  1193. //trace ("ile : " + Pchar.location);
  1194. if(Pchar.location != "" && Pchar.location != "error") rGroup.location = Pchar.location;
  1195. }
  1196. if(CheckAttribute(chr,"fallen")) // Screwface : Need to restore the fallen mast(s) to avoid crashes with set flags
  1197. {
  1198. DeleteAttribute(chr,"ship.sails");
  1199. DeleteAttribute(chr,"ship.masts");
  1200. DeleteAttribute(chr,"fallen");
  1201. Trace("Ship mast restored");
  1202. }
  1203. // Screwface : end
  1204. //trace("Set temporary group " + tmpgrp + " coords: x="+x+", z="+z+", ay="+ay);
  1205. }
  1206. // <-- KK
  1207.  
  1208. void Sea_LoginGroup(string sGroupID)
  1209. {
  1210. int iNumShips, i, iNumDeadCharacters, iCharacterIndex;
  1211. float x, z, ay;
  1212. bool bSailsState;
  1213. string sLocationGroup, sLocationLocator, sTst;
  1214. ref rGroup, rIsland, rCharacter, rGroupCommander;
  1215. aref arQuestShips, arShip;
  1216.  
  1217. if (!isEntity(&Sea)) {
  1218. trace("SEA: Error: Sea_LoginGroup sGroupID = " + sGroupID + ", but Sea is not active!");
  1219. return;
  1220. }
  1221.  
  1222. if (Group_FindGroup(sGroupID) < 0) {
  1223. trace("SEA: Not find group '" + sGroupID + "' in groups massive, but login try spotted");
  1224. return;
  1225. }
  1226.  
  1227. rGroup = Group_GetGroupByID(sGroupID);
  1228. if (!CheckAttribute(rGroup, "Quest"))
  1229. {
  1230. trace("SEA: Error: Sea_LoginGroup sGroupID = " + sGroupID + ", but group doesn't contain any quest ships!");
  1231. trace("SEA: I am deleting empty group '" + sGroupID +"'"); // LDH keep from having CTD for tasks 15Feb09
  1232. Group_DeleteAtEnd(sGroupID);
  1233. return;
  1234. }
  1235. if (CheckAttribute(rGroup, "AlreadyLoaded")) {
  1236. trace("SEA: Error: Group sGroupID = " + sGroupID + ", already loaded... check for duplicate group login");
  1237. return;
  1238. }
  1239.  
  1240. makearef(arQuestShips, rGroup.Quest);
  1241.  
  1242. iNumShips = GetAttributesNum(arQuestShips);
  1243. if (iNumShips == 0) return;
  1244.  
  1245. x = 0.0;
  1246. z = 0.0;
  1247. ay = 0.0;
  1248.  
  1249. // find group position
  1250. if (CheckAttribute(rGroup, "location") && CheckAttribute(rGroup, "location.group") && rGroup.location != "none") {
  1251. sLocationGroup = rGroup.location.group;
  1252. sLocationLocator = rGroup.location.locator;
  1253.  
  1254. rIsland = GetIslandByID(rGroup.location);
  1255.  
  1256. sTst = sLocationGroup + "." + sLocationLocator + ".x";
  1257. if (CheckAttribute(rIsland, sTst)) {
  1258. x = stf(rIsland.(sLocationGroup).(sLocationLocator).x);
  1259. z = stf(rIsland.(sLocationGroup).(sLocationLocator).z);
  1260. ay = stf(rIsland.(sLocationGroup).(sLocationLocator).ay);
  1261. } else {
  1262. x = 0.0; z = 0.0; ay = 0.0;
  1263. Trace("SEA: Error: Group " + sGroupID + ", Island " + rGroup.location);
  1264. Trace("SEA: Error: Find locators Group " + sLocationGroup + ", Locator " + sLocationLocator);
  1265. }
  1266. } else {
  1267. if (CheckAttribute(rGroup, "Pos")) {
  1268. x = stf(rGroup.Pos.x);
  1269. z = stf(rGroup.Pos.z);
  1270. ay = stf(rGroup.Pos.ay);
  1271. } else {
  1272. Trace("SEA: Error: Sea_LoginGroup sGroupID = " + sGroupID + ", I can't find any locators or position for this group, maybe you can check this???");
  1273. }
  1274. }
  1275.  
  1276. // set group position
  1277. Group_SetXZ_AY(sGroupID, x, z, ay);
  1278.  
  1279. // set group commander
  1280. rGroupCommander = Group_GetGroupCommander(sGroupID);
  1281. // update commander for SEA AI
  1282. Group_SetGroupCommander(sGroupID, rGroupCommander.id);
  1283.  
  1284. // KK -->
  1285. bSailsState = Group_GetSailsUp(sGroupID);
  1286. bSailsState = !bSailsState;
  1287. // <-- KK
  1288.  
  1289. // set location near
  1290. if (CheckAttribute(rGroup, "location.neargroup"))
  1291. {
  1292. Group_SetPursuitGroup(sGroupID, rGroup.location.neargroup);
  1293. }
  1294.  
  1295. // load group ships
  1296. iNumDeadCharacters = 0;
  1297. for (i=0; i<iNumShips; i++)
  1298. {
  1299. if(iNumShips >= MAX_SHIPS_ON_SEA)
  1300. {
  1301. Trace("SEA: Sea_LoginGroup iNumShips over MAX: "+ iNumShips);
  1302. return; // NK bugfix
  1303. }
  1304.  
  1305. arShip = GetAttributeN(arQuestShips, i);
  1306. rCharacter = GetCharacter(GetCharacterIndex(GetAttributeValue(arShip)));
  1307. iCharacterIndex = sti(rCharacter.index);
  1308.  
  1309. if (CharacterIsDead(rCharacter)) { iNumDeadCharacters++; continue; }
  1310. // LDH added corpses 15Feb09, added checkattribute 20Feb09
  1311. if (CheckAttribute(rCharacter, "chr_ai.group") && rCharacter.chr_ai.group == LAI_GROUP_CORPSES) { iNumDeadCharacters++; continue; }
  1312. if (CheckAttribute(rCharacter, "surrendered") == true && sti(rCharacter.surrendered) == true) { iNumDeadCharacters++; continue; } // KK
  1313. if (bAllies(rCharacter)) { Trace("SEA: Error: You assigned allied character " + GetMySimpleName(rCharacter) + " with ID " + rCharacter.id + " to quest group... This is an error!"); iNumDeadCharacters++; continue; } // PB: Attempted fix for CTDs due to allied characters being assigned to Sea AI groups
  1314.  
  1315. rCharacter.SeaAI.Group.Name = sGroupID;
  1316. Group_AddCharacter(sGroupID, rCharacter.id); // KK
  1317.  
  1318. if(CheckAttribute(rCharacter,"fallen")) // Screwface : Need to restore the fallen mast(s) to avoid crashes with set flags
  1319. {
  1320. DeleteAttribute(rCharacter,"ship.sails");
  1321. DeleteAttribute(rCharacter,"ship.masts");
  1322. DeleteAttribute(rCharacter,"fallen");
  1323. Trace("Ship mast restored");
  1324. }
  1325.  
  1326. Ship_Add2Sea(iCharacterIndex, bSailsState, "");
  1327.  
  1328. ReloadProgressUpdate();
  1329. }
  1330.  
  1331. rGroup.AlreadyLoaded = "";
  1332.  
  1333. if (iNumDeadCharacters == iNumShips)
  1334. {
  1335. Trace("SEA: Warn: I am automatically deleting group '" + sGroupID +"', because it's empty");
  1336. Group_DeleteAtEnd(sGroupID);
  1337. //Group_DeleteGroup(sGroupID);
  1338. return;
  1339. }
  1340.  
  1341. bSeaQuestGroupHere = true;
  1342.  
  1343. Sea_AddGroup2TaskList(sGroupID);
  1344. }
  1345.  
  1346. void Sea_FirstInit()
  1347. {
  1348. RefreshBattleInterface();
  1349.  
  1350. QuestsCheck(); // PB: For quests executing upon reloading to sea
  1351.  
  1352. // KK: Companion Mutiny -->
  1353. ref rPlayer = GetMainCharacter();
  1354. if (bShipMutiny) {
  1355. for (int i = 1; i < COMPANION_MAX; i++)
  1356. {
  1357. int iCompanionIndex = GetCompanionIndex(rPlayer, i);
  1358. if (iCompanionIndex < 0) continue;
  1359. ref rCompanion = GetCharacter(iCompanionIndex);
  1360. if (!IsMutineer(rCompanion)) continue;
  1361. SeaAI_SetCompanionEnemy(rCompanion); // PB: Use generic function
  1362. }
  1363. RefreshFlags();
  1364. bShipMutiny = false; // PB: Once is enough
  1365. }
  1366. // KK: Companion Mutiny <--
  1367.  
  1368. ResetTimeToNormal(); // PB: Reset Time Scale
  1369.  
  1370. trace("Sea_FirstInit done");
  1371. }
  1372.  
  1373. void Sea_Reload()
  1374. {
  1375. DelEventHandler("Sea_Reload", "Sea_Reload");
  1376.  
  1377. object Login;
  1378. Login.PlayerGroup.ay = 0.0;
  1379. Login.PlayerGroup.x = 0.0;
  1380. Login.PlayerGroup.y = 0.0;
  1381. Login.PlayerGroup.z = 0.0;
  1382. Login.Island = Characters[0].location;
  1383.  
  1384. ref rPlayer = GetMainCharacter(); // ccc Survival, NK 05-04-16 bugfix didn't have = GetMainCharacter();
  1385. //TIH -->
  1386. if (CheckAttribute(rPlayer, "lifeboatlaunch")) {
  1387. int testIsleIdx = FindIsland(Login.Island);
  1388. if (testIsleIdx != -1) {
  1389. Ship_SetSailState(GetMainCharacterIndex(), 0);//TIH - lowers the sails // KK
  1390. Login.FromCoast = true; //TIH - makes the lifeboat not run into the islands at full speed!
  1391. }
  1392. DeleteAttribute(rPlayer, "lifeboatlaunch");
  1393. }
  1394. //TIH <--
  1395. SeaLogin(&Login);
  1396. }
  1397.  
  1398. void Sea_ReloadStart()
  1399. {
  1400. if (!bSeaActive) { return; }
  1401. DeleteSeaEnvironment();
  1402. SetEventHandler("Sea_Reload", "Sea_Reload", 0);
  1403. PostEvent("Sea_Reload", 1);
  1404. }
  1405. // ccc CR ->
  1406. void SetCoastTraffic(string islandstr)
  1407. {
  1408. //int tmpLangFileID = LanguageOpenFile("interface_strings.txt");
  1409. // no longer needed if(islandstr == "KhaelRoa") return; // NK tempfix 04-09-09
  1410. if(GetCharacterIndex("Cr" + islandstr+"1") == -1) return; //if no CR chars, return
  1411. if(CheckAttribute(Islands[FindIsland(islandstr)],"skipCR")) { if(sti(Islands[FindIsland(islandstr)].skipCR)) return; } // NK 04-09-14
  1412. ref Pchar = GetMainCharacter();
  1413. ref CurIsland = GetIslandByIndex(FindIsland(islandstr));
  1414. string chrstr = "Cr" + islandstr;
  1415. string sFantomType;
  1416. int crnation, grpidx, j, nflag1, ntex1, nflag2, ntex2, crship;
  1417. int i = 1;
  1418.  
  1419. for( j = 1; j <7 ; j++) //Loop to reset relation BEFORE groupcreation
  1420. {
  1421. if(GetCharacterIndex(chrstr + j)==-1) continue;//MAXIMUS
  1422. SetCharacterRelationBoth(GetCharacterIndex(chrstr + j), GetMainCharacterIndex(), RELATION_NEUTRAL);
  1423. }
  1424.  
  1425. while(i < 6-((sti(CurIsland.smuggling_nation) == PIRATE)*2)) // 1st loop to create 3 groups for 2 ships each, NK to reduce at pirate islands
  1426. {
  1427. string crg = chrstr + i;
  1428. grpidx = Group_FindGroup(crg); // NK bugfix to not delete not-existing group 05-05-02
  1429. if(grpidx != -1) Group_DeleteGroup(crg); //to clear for SeaLogin
  1430.  
  1431. string pos = GetRandomQuestShipLocator(islandstr); // PB: Use all available quest ship locators
  1432. Group_CreateGroup(crg);
  1433. Group_SetGroupCommander(crg, crg);
  1434. Group_SetAddress(crg, islandstr, "Quest_Ships", pos);
  1435. if (frnd() < COASTRAIDER_CHANCE)
  1436. {
  1437. // NK 04-08-27 -->
  1438. if(frnd() < NAVYRAIDER_CHANCE)
  1439. {
  1440. crnation = FindEnemyNation2Nation(sti(CurIsland.smuggling_nation));
  1441. if(crnation != PIRATE) sFantomType = "war"; //have to check, because PIRATE is a nation
  1442. else sFantomType = "pirate";
  1443. }
  1444. else
  1445. {
  1446. crnation= PIRATE;
  1447. sFantomType = "pirate";
  1448. }
  1449. }
  1450. else
  1451. {
  1452. // NK 04-09-09 add coastguard and other trade nation cases
  1453. if(frnd() < COASTGUARD_CHANCE)
  1454. {
  1455. sFantomType = "war"; //NK now that PRS3 uses Fantom_GetShip call, must also choose whether trade or war
  1456. crnation = sti(CurIsland.smuggling_nation);
  1457. }
  1458. else
  1459. {
  1460. sFantomType = "trade";
  1461. crnation = FindFriendlyNation2Nation(sti(CurIsland.smuggling_nation));
  1462. if(frnd() < TRADE_OTHERNATIONCHANCE && crnation != -1)
  1463. {
  1464. //nothing
  1465. }
  1466. else { crnation = sti(CurIsland.smuggling_nation); }
  1467. if (GetRMRelationType(GetRMRelation(GetMainCharacter(),crnation)) == RELATION_ENEMY) // NK change to use RM
  1468. {
  1469. Group_SetTaskRunAway(crg);
  1470. Group_LockTask(crg);
  1471. }
  1472. else
  1473. {
  1474. Group_SetTaskMove(crg, 10000.0, 10000.0);
  1475. }
  1476. }
  1477. // NK 04-09-09 <--
  1478.  
  1479. // NK 04-08-27 <--
  1480. // crg is string, not object - crg.nation = crnation; //nation for group
  1481. }
  1482.  
  1483. nflag2 = GetPirateFlag(Pchar, &ntex2);
  1484. for( j = 0; j <2 ; j++) // 2nd loop to create 2 ships for each group
  1485. {
  1486. ref cr = CharacterFromID(chrstr + (i+j));
  1487. //trace(".");
  1488. string trstr = "SetCoastTraffic: Char " + cr.id + " of type " + sFantomType + " and nation " + GetNationNameByType(sti(cr.nation));
  1489. // NK to reuse existing if within a week 04-09-09
  1490. bool bDead = CharacterIsDead(cr); // KK
  1491. if (sti(cr.nation) == NEUTRAL_NATION)
  1492. {
  1493. trstr += " was neutral nation,";
  1494. bDead = true; // KK
  1495. }
  1496.  
  1497. if (CheckAttribute(cr, "surrendered"))
  1498. {
  1499. trstr += " was surrendered,";
  1500. bDead = true; // LDH - 05Feb09
  1501. }
  1502.  
  1503. if (cr.chr_ai.group == LAI_GROUP_CORPSES) // LDH - 14Feb09
  1504. {
  1505. trstr += " was a corpse,";
  1506. bDead = true;
  1507. }
  1508.  
  1509. if(bDead) trstr += " is dead";
  1510. // KK if(bDead) SetCharacterShipLocation(cr, "");
  1511. bool bgennew = bDead && frnd() < DEAD_GENNEW_CR;
  1512. if(bgennew) trstr += " and will be regen'd from dead.";
  1513. if(!bgennew)
  1514. {
  1515. trstr += " and we'll check to see if we regen";
  1516. bgennew = true;
  1517. if(CheckAttribute(cr, "crmonth") && CheckAttribute(cr, "crday"))
  1518. {
  1519. // LDH changed to use GetPastTime() 14Feb09
  1520. // days pass quicker with directsail, so CR_PERSIST will need to be longer. GetPastTime() makes calcs more accurate
  1521. int oldyear = GetDataYear(); if (sti(cr.crmonth) > GetDataMonth()) oldyear -= 1;
  1522. int days = GetPastTime("day", oldyear, sti(cr.crmonth), sti(cr.crday), 0.0, GetDataYear(), GetDataMonth(), GetDataDay(), 0.0);
  1523. // LDH faster calculation 20Feb09
  1524. // int days = GetDayOfYear(GetDataYear(), GetDataMonth(), GetDataDay()) - GetDayOfYear(oldyear, sti(cr.crmonth), sti(cr.crday);
  1525. // if (days < 0) days += 365; // Ignoring leap year here. It's close enough.
  1526. if(days < CR_PERSIST)
  1527. {
  1528. bgennew = false;
  1529. }
  1530. }
  1531. if(bgennew) trstr += ": yes.";
  1532. else trstr += ": no.";
  1533. }
  1534.  
  1535. CRTrace(trstr);
  1536. trstr = "";
  1537.  
  1538. if(GetCharacterShipType(&cr) == SHIP_NOTUSED && !bDead)
  1539. {
  1540. CRTrace("bgennew set to true anyway"); // LDH 15Feb09
  1541. bgennew = true;
  1542. }
  1543. if(bgennew)
  1544. {
  1545. // Screwface
  1546. if(Checkattribute(cr,"recognized"))
  1547. {
  1548. DeleteAttribute(cr,"recognized");
  1549. DeleteAttribute(cr,"EnemyShipName");
  1550. DeleteAttribute(cr,"EnemyShipType");
  1551. } // Screwface : end
  1552. if(CheckAttribute(cr,"fallen")){DeleteAttribute(cr,"fallen");} // Screwface
  1553. cr.crmonth = environment.date.month;
  1554. cr.crday = environment.date.day;
  1555. cr.nation = crnation; //nation for character
  1556. // KK -->
  1557. if (crnation == PIRATE) {
  1558. sFantomType = "pirate"; // NK 04-09-12 because for QC pirates are coastguard!
  1559. if (cr.id == crg) {
  1560. nflag1 = GetPirateFlag(cr, &ntex1);
  1561. if (nflag1 == nflag2 && ntex1 == ntex2) {
  1562. if (nflag1 == 0)
  1563. cr.Flags.Pirate = nflag1 + 1;
  1564. else
  1565. cr.Flags.Pirate = nflag1 - 1;
  1566. }
  1567. } else {
  1568. cr.Flags.Pirate = GetPirateFlag(CharacterFromID(crg), &ntex1);
  1569. cr.Flags.Pirate.texture = ntex1;
  1570. }
  1571. }
  1572. //trstr = "New dates!m" + cr.crmonth + " d" + cr.crday + ".";
  1573. // NK <--
  1574.  
  1575. cr.location = "none";
  1576. cr.location.group = "";
  1577. cr.location.locator = "";
  1578. // <-- KK
  1579.  
  1580. cr.quest.officertype = CaptainTypeFromFantomType(sFantomType); // NK 04-08-27
  1581. cr.FantomType = sFantomType;
  1582.  
  1583. // NK 04-09-09 move this till after find shiptype LAi_Create_Officer(0, cr);
  1584. //cr.rank = makeint(Pchar.rank) + Rand(5); //sets NEW rank! // NK, disabled, leads to weird XP bug...
  1585.  
  1586. // PRS3 now back to using Fantom_GetShipType, should be fast enough now.
  1587. /*int skip = -10 + sti(Pchar.rank) + GetDifficulty()*2;
  1588. if(skip > 30) skip = 30;
  1589.  
  1590. crship = skip + Rand(70 + GetDifficulty()*5) + Rand(70 + GetDifficulty()*5); //select shiptype
  1591. if (crship>150) crship = 162 + Rand(30);
  1592. if(crship < 0) crship = 0;
  1593. while(true)
  1594. {
  1595. if(crship < SHIP_TYPES_QUANTITY)
  1596. {
  1597. if(sti(ShipsTypes[crship].CanEncounter) && ShipsTypes[crship].id != "BlackPearl")
  1598. {
  1599. if(crnation != PIRATE) { break; }
  1600. if(sti(ShipsTypes[crship].class) >= MAXPIRATECLASS) { break; }
  1601. }
  1602. }
  1603. crship = skip + Rand(70 + GetDifficulty()*5) + Rand(70 + GetDifficulty()*5); //select shiptype
  1604. if (crship>150) crship = 162 + Rand(30);
  1605. if(crship < 0) crship = 0;
  1606. }*/
  1607. /*int crship = makeint(cr.rank)*10 + 20 -Rand(30) ; //select shiptype
  1608. if (crship>167) crship = makeint(170+Rand(15) );*/
  1609.  
  1610. // PRS3 new get ship call
  1611. int minclass = MIN_CLASS;
  1612. //scale minclass between 7 and CR_MAX_MINCLASS based on PChar level
  1613. if(GetLevel(&Pchar) < (MIN_CLASS-CR_MAX_MINCLASS)*CR_MINCLASS_PERLEVEL) minclass = (MIN_CLASS - makeint(makefloat(GetLevel(&Pchar)) / CR_MINCLASS_PERLEVEL));
  1614. int maxclass = MAX_CLASS;
  1615.  
  1616. switch(sFantomType)
  1617. {
  1618. case "pirate": maxclass = CR_MAXPIRATECLASS; break;
  1619. case "trade": maxclass = MAXMERCHANTCLASS; break;
  1620. case "war": if(crnation == sti(CurIsland.smuggling_nation)) { maxclass = MAXCOASTGUARDCLASS; } break;
  1621. }
  1622. // cap if GetShipCap()
  1623. if(GetShipCap() && maxclass < GetCharacterShipClass(Pchar) - CR_CLASS_ABOVE_PCHAR) maxclass = GetCharacterShipClass(Pchar) - CR_CLASS_ABOVE_PCHAR;
  1624. if(GetShipCap() && maxclass < (MIN_CLASS+1)-GetLevel(Pchar) - CR_CLASS_ABOVE_PCHAR) maxclass = (MIN_CLASS+1) - GetLevel(Pchar) - CR_CLASS_ABOVE_PCHAR;
  1625. if(maxclass < MAX_CLASS) maxclass = MAX_CLASS;
  1626. //trstr += " Maxclass " + maxclass + ", minclass " + minclass;
  1627. crship = Force_GetShipType(maxclass, minclass, sFantomType, crnation);
  1628. //trstr += ". Ship ID " + GetShipID(crship);
  1629. // KK -->
  1630. Ship_CreateForCharacter(cr, GetShipID(crship), "Coaster");
  1631.  
  1632. string sFantomTypeTmp = sFantomType;
  1633. if (GetCharacterShipClass(cr) <= 3 && sti(ShipsTypes[crship].type.war) == true && sti(cr.nation) != PIRATE) sFantomTypeTmp = "war";
  1634. Fantom_SetRandomModel(cr, sFantomTypeTmp);
  1635. SetRandomNameToCharacter(cr);
  1636. // <-- KK
  1637. LAi_Create_Officer(0, cr);
  1638. // NK PRS3 getshiptype <--
  1639.  
  1640. //equip ship
  1641. Ship_SetFantomData(cr);
  1642. Fantom_SetCannons(cr, sFantomType);
  1643. Fantom_SetSails(cr, sFantomType);
  1644. Fantom_ClearCargo(cr); // TIH clear out prior slot cargo
  1645. Fantom_SetBalls(cr, sFantomType);
  1646. Fantom_SetGoods(cr, sFantomType);
  1647. Fantom_SetRandomMoney(cr, sFantomType);
  1648.  
  1649. SetRandomNameToShip(cr);
  1650.  
  1651. if (crnation == PIRATE)
  1652. {
  1653. cr.perks.list.ShipSpeedUp = true;
  1654. cr.Ship.crew.quantity = GetMaxCrewQuantity(cr);
  1655. }
  1656.  
  1657. // LDH - regen'd characters won't be surrendered - 15Feb09
  1658. if (CheckAttribute(cr, "surrendered")) DeleteAttribute(cr, "surrendered"); // causes crash on set task?
  1659. RestoreCharacter(cr); // LDH fix corpses, needed for group processing - 15Feb09
  1660. // LDH added corpse group fix because it's not done in RestoreCharacter() - 15Feb09
  1661. // probably a good thing, because it's the only way we have left to determine if a character is a corpse
  1662. if (cr.chr_ai.group == LAI_GROUP_CORPSES)
  1663. {
  1664. LAi_group_MoveCharacter(cr, LAI_DEFAULT_GROUP);
  1665. }
  1666.  
  1667. // move down - SetCharacterRelationBoth(sti(cr.index), GetMainCharacterIndex(), GetRMRelationType(GetRMRelation(GetMainCharacter(), sti(cr.nation)))); // NK set base relation to avoid gray icon
  1668. //trace(trstr);
  1669. }
  1670. else {
  1671. crship = GetCharacterShipType(cr);
  1672. /*trace("resuming old ship type, " + cr.ship.type);*/
  1673. }
  1674.  
  1675. if(bDead && !bgennew) // 04-09-15 remove from group if dead. Seems to work OK without, but let's be sure. // LDH added !bgennew - 14Feb09
  1676. {
  1677. CRTrace("The " + cr.ship.name + " was deleted from the group"); // LDH 15Feb09
  1678. Group_DelCharacter(crg, cr.id);
  1679. // if this group is empty it will be deleted in Sea_LoginGroup() LDH 15Feb09
  1680. }
  1681. else
  1682. {
  1683. CRTrace(cr.id + " is not dead, adding.");
  1684. // NK 04-09-20 if group cmdr is not same nation
  1685. ref gcmdr = CharacterFromID(crg);
  1686. if(sti(gcmdr.index) != sti(cr.index))
  1687. {
  1688. CRTrace("cr is not group commander");
  1689. if(CharacterIsDead(gcmdr) ||
  1690. CheckAttribute(gcmdr, "surrendered") || // LDH added surendered - 14Feb09
  1691. gcmdr.chr_ai.group == LAI_GROUP_CORPSES || // LDH added corpses - 15Feb09
  1692. gcmdr.nation != cr.nation) // KK
  1693. {
  1694. CRTrace("create new grp");
  1695. Group_DelCharacter(crg, cr.id);
  1696. Group_AddCharacter(crg + "_1", cr.id);
  1697. Group_SetGroupCommander(crg + "_1", cr.id);
  1698. Group_SetType(crg + "_1", sFantomType);
  1699. Group_SetAddress(crg + "_1", islandstr, "Quest_Ships", pos);
  1700. }
  1701. else
  1702. {
  1703. CRTrace("do not need to create new group")
  1704. Group_ChangeCharacter(crg, cr.id);
  1705. //Group_SetGroupCommander(crg, cr.id);
  1706. bool t2 = Group_GetType(crg) != "war" || sFantomType == "war"; // KK
  1707. if(!t2) t2 = Group_GetType(crg) != "pirate" || sFantomType == "pirate"; // KK
  1708. if(t2) Group_SetType(crg, sFantomType);
  1709. }
  1710. }
  1711. else
  1712. {
  1713. CRTrace("cr is group commander");
  1714. Group_ChangeCharacter(crg, cr.id);
  1715. Group_SetGroupCommander(crg, cr.id);
  1716. Group_SetType(crg, sFantomType);
  1717. }
  1718. // changed by MAXIMUS -->
  1719. int chkNation;
  1720. if(CheckAttribute(cr,"nation")) chkNation = sti(cr.nation);
  1721. // LDH NATIONS_QUANTITY was hardcoded 6 - 05Feb09
  1722. if(chkNation<=NATIONS_QUANTITY) SetCharacterRelationBoth(sti(cr.index), GetMainCharacterIndex(), GetRMRelationType(GetRMRelation(GetMainCharacter(), sti(cr.nation)))); // NK set base relation to avoid gray icon
  1723. else
  1724. {
  1725. if(chkNation == sti(Pchar.nation)) SetCharacterRelationBoth(sti(cr.index), GetMainCharacterIndex(), RELATION_NEUTRAL);
  1726. else
  1727. {
  1728. // LDH - NEUTRAL_NATION was hardcoded 7 - 05Feb09
  1729. if(chkNation==NEUTRAL_NATION) SetCharacterRelationBoth(sti(cr.index), GetMainCharacterIndex(), RELATION_NEUTRAL);
  1730. else SetCharacterRelationBoth(sti(cr.index), GetMainCharacterIndex(), RELATION_ENEMY);
  1731. }
  1732. }
  1733. // changed by MAXIMUS <--
  1734. //UpdateRelations();
  1735. // NK 04-09-20 <--
  1736. if(sti(cr.Ship.Cannons.Type) != CANNON_TYPE_NONECANNON) cr.ship.cannons.charge.type = GOOD_BALLS; // NK 04-09-20 for ammo bugfix, KNB
  1737.  
  1738. // NK to convert shipname to nice string
  1739. if(LogsToggle >= LOG_NORMAL && iRealismMode == 0) { // Screwface
  1740. Log_SetStringToLog(XI_ConvertString("BA") + " " + XI_ConvertString(ShipsTypes[crship].sname) + " " + XI_ConvertString("flying") + " " + XI_ConvertString("1"+GetNationDescByType(sti(cr.nation))) + " " + TranslateString("","colors sighted at") + " " + FindIslandName(islandstr)); // KK
  1741. //Log_SetStringToLog("-");
  1742. }
  1743.  
  1744. if(bgennew)
  1745. {
  1746. // NK fix this to only do correct one. 05-07-11
  1747. switch(islandstr)
  1748. {
  1749. case "QuebradasCostillas": setCharacterShipLocation(cr,"QC_port"); break;
  1750. case "IslaMuelle": setCharacterShipLocation(cr,"Muelle_port"); break;
  1751. case "FalaiseDeFleur": setCharacterShipLocation(cr, "Falaise_de_fleur_port_01"); break;
  1752. case "Curacao": SetCharacterShipLocation(cr, "Willemstad_port"); break; // KK
  1753. case "Aruba": SetCharacterShipLocation(cr, "Oranjestad_port"); break; // KK
  1754. setCharacterShipLocation(cr, islandstr + "_port"); // default case
  1755. }
  1756. // NK <--
  1757. }
  1758. // KK -->
  1759. if (CheckAttribute(cr, "after_1st_sailto")) DeleteAttribute(cr, "after_1st_sailto");
  1760. // <-- KK
  1761. }
  1762. // NK <--
  1763.  
  1764. // Screwface : Fix for groups of same nation firing each others. We need to reset relations for each coastraider
  1765. for(int k = 1; k <7; k++)
  1766. {
  1767. if(GetCharacterIndex(chrstr + k)==-1) continue;
  1768. ref cr2 = CharacterFromID(chrstr + k);
  1769. SetCharacterRelationBoth(sti(cr.index), sti(cr2.index), GetNationRelation(sti(cr.nation), sti(cr2.nation)));
  1770. } // Screwface : End
  1771. }
  1772. //if (Group_GetCharactersNum(crg) == 0 && Group_FindGroup(crg) != -1) Group_DeleteGroup(crg); // KK
  1773.  
  1774. i=i+2 //doublestep for grouploop
  1775. }
  1776. //LanguageCloseFile(tmpLangFileID);
  1777. }
  1778. // ccc CR <-
  1779.  
  1780. void CRTrace(string str)
  1781. {
  1782. if (DEBUGCR) Trace(str);
  1783. }
  1784.  
  1785. // KK -->
  1786. void LoadAtSea()
  1787. {
  1788. int i, iNum;
  1789. aref artmp, arnode, arenc;
  1790. ref rtmp;
  1791. ref mc = GetMainCharacter();
  1792. float x, z;
  1793. object SLogin;
  1794. ref sl; makeref(sl, SLogin);
  1795.  
  1796. sl.location = mc.location;
  1797. sl.location.group = mc.location.group;
  1798. sl.location.locator = mc.location.locator;
  1799. sl.Island = mc.location;
  1800. rtmp = Group_FindOrCreateGroup(PLAYER_GROUP);
  1801. sl.PlayerGroup.x = rtmp.Pos.x;
  1802. sl.PlayerGroup.z = rtmp.Pos.z;
  1803. sl.PlayerGroup.ay = rtmp.Pos.ay;
  1804.  
  1805. for (i = 0; i < iNumShips; i++)
  1806. {
  1807. if (Ships[i] < 0) continue;
  1808. rtmp = GetCharacter(Ships[i]);
  1809. string l = "l" + i;
  1810. if (CharacterIsDead(rtmp)) {
  1811. sl.Ship.(l).idx = -1;
  1812. continue;
  1813. }
  1814. sl.Ship.(l).idx = Ships[i];
  1815. /*sl.Ship.(l).Pos.x = rtmp.Ship.Pos.x;
  1816. sl.Ship.(l).Pos.y = rtmp.Ship.Pos.y;
  1817. sl.Ship.(l).Pos.z = rtmp.Ship.Pos.z;
  1818. sl.Ship.(l).Pos.ay = GetAngleY(stf(rtmp.Ship.Pos.x), stf(rtmp.Ship.Pos.z));*/
  1819. sl.Ship.(l).Group = Ship_GetGroupID(rtmp);
  1820. if (GetCharacterIndex(rtmp.id) == Group_GetGroupCommanderIndex(Group_GetGroupByID(Ship_GetGroupID(rtmp)))) {
  1821. rtmp.SeaAI.Group.MainCharacter = true;
  1822. /*rtmp.SeaAI.Group.MainCharacter.Task = Group_GetTask(rtmp.SeaAI.Group.name);
  1823. rtmp.SeaAI.Group.MainCharacter.Target = Group_GetGroupTarget(rtmp.SeaAI.Group.name);
  1824. Group_GetGroupTargetPos(rtmp.SeaAI.Group.name, &x, &z);
  1825. rtmp.SeaAI.Group.MainCharacter.Target.Pos.x = x;
  1826. rtmp.SeaAI.Group.MainCharacter.Target.Pos.z = z;
  1827. Trace("LoadAtSea: chr.id="+rtmp.id+": task: "+rtmp.SeaAI.Group.MainCharacter.Task+", target: "+rtmp.SeaAI.Group.MainCharacter.Target+", pos: "+x+";"+z);*/
  1828. }
  1829. if (CheckAttribute(rtmp, "Ship.old.Masts")) {
  1830. if (CheckAttribute(rtmp, "Ship.Masts")) DeleteAttribute(rtmp, "Ship.Masts");
  1831. aref arOldMasts; makearef(arOldMasts, rtmp.Ship.old.Masts);
  1832. rtmp.Ship.Masts.Mast1 = 0;
  1833. aref arMasts; makearef(arMasts, rtmp.Ship.Masts);
  1834. DeleteAttribute(arMasts, "Mast1");
  1835. CopyAttributes(arMasts, arOldMasts);
  1836. DeleteAttribute(rtmp, "Ship.old");
  1837. }
  1838. }
  1839. sl.Ship.Quantity = iNumShips;
  1840.  
  1841. sl.LoadAtSea = true;
  1842.  
  1843. //DeleteAttribute(mc, "SaveData");
  1844. SendMessage(&AIBalls, "l", MSG_MODEL_RESTORE);
  1845.  
  1846. // Screwface : We restore the current load attributes to not loose balls & gunpowder
  1847. if(CheckAttribute(mc,"save"))
  1848. {
  1849. if(CANNONPOWDER_MOD)
  1850. {
  1851. AddCharacterGoods(mc,GOOD_GUNPOWDER,sti(mc.save.gunpowder));
  1852. }
  1853. AddCharacterGoods(mc,sti(mc.save.currentcharge),sti(mc.save.currentchargeqty));
  1854. DeleteAttribute(mc, "Save");
  1855. }
  1856. // Screwface : end
  1857.  
  1858. SeaLogin(sl);
  1859.  
  1860. //Fader
  1861. PostEvent("LoadSceneSound", 500);
  1862. }
  1863.  
  1864. void RestoreEncounters(ref Encounters)
  1865. {
  1866. int i, iNum;
  1867.  
  1868. iNumShips = 0;
  1869.  
  1870. iNum = GetAttributesNum(Encounters);
  1871. for (i = 0; i < iNum; i++)
  1872. {
  1873. aref arEncounter = GetAttributeN(Encounters, i);
  1874. int iFantomIndex = sti(arEncounter.index);
  1875. if (iFantomIndex < 0) continue;
  1876. ref rFantom = GetCharacter(iFantomIndex);
  1877. string FantomID = rFantom.id;
  1878. DeleteAttribute(rFantom, "");
  1879. CopyAttributes(rFantom, arEncounter);
  1880. rFantom.index = iFantomIndex;
  1881. rFantom.id = FantomID;
  1882. string sGroupID = Ship_GetGroupID(rFantom);
  1883. ref rGroup = Group_FindOrCreateGroup(sGroupID);
  1884. Group_AddCharacter(sGroupID, FantomID);
  1885. if (Group_GetGroupCommanderIndex(rGroup) == iFantomIndex) Group_SetGroupCommander(sGroupID, FantomID);
  1886. Ship_Login(iFantomIndex);
  1887. }
  1888. }
  1889.  
  1890. float GetVisibilityRange(int iRange)
  1891. {
  1892. float visibility_range;
  1893. switch (iRange)
  1894. {
  1895. case 1:
  1896. visibility_range = 1000.0;
  1897. break;
  1898. case 2:
  1899. visibility_range = 500.0;
  1900. break;
  1901. case 3:
  1902. visibility_range = 300.0;
  1903. break;
  1904. // default:
  1905. visibility_range = 3000.0;
  1906.  
  1907. }
  1908. visibility_range -= (stf(Weathers.Fog.SeaDensity) * 130 * visibility_range);
  1909. if (Whr_IsNight()) visibility_range /= 2.0;
  1910. return visibility_range;
  1911. }
  1912. // <-- KK
  1913.  
  1914. // Screwface
  1915. void SetCorrectWorldMapPosition()
  1916. {
  1917. ref Pchar = GetMaincharacter();
  1918.  
  1919. if(Pchar.location != "" && Pchar.location != "error")
  1920. {
  1921. string island = Pchar.location;
  1922. float psX = MakeFloat(pchar.Ship.Pos.x);
  1923. float psZ = MakeFloat(pchar.Ship.Pos.z);
  1924. float ix = MakeFloat(worldMap.islands.(Island).position.rx);
  1925. float iz = MakeFloat(worldMap.islands.(Island).position.rz);
  1926.  
  1927. //REAL CONVERTION OF YOUR SEAVIEW COORDS IN WORLD MAP COORDS
  1928. worldMap.playerShipX = (psX/WDM_MAP_TO_SEA_SCALE) + ix;
  1929. worldMap.playerShipZ = (psZ/WDM_MAP_TO_SEA_SCALE) + iz;
  1930. }
  1931. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement