Page 9 of 10

Re: Galactic Almanac OXZ - Full Version 0.92 - Now on the Expansion Pack Manager (Updated 12.08.23)

Posted: Sat Aug 26, 2023 2:31 pm
by LittleBear
The only change made is to the displayName at line 4008, which reads:-

Code: Select all

if(ship.hasRole("planetFall_mainSurface_FSRoyalCourt")) ship.displayName = ""+expandDescription("[named_stations_planetFall_mainSurface_FSRoyalCourt_name]"); 
This shouldn't break the script as the test is for role rather than displayName name. Does Feudal States run properly at the orbital hunting lodges?

To test it, could you comment out line 4008 so it now reads:

Code: Select all

//if(ship.hasRole("planetFall_mainSurface_FSRoyalCourt")) ship.displayName = ""+expandDescription("[named_stations_planetFall_mainSurface_FSRoyalCourt_name]");


Does the Royal Court now appear with this change?

Can't reproduce the bug myself as landed on the main planet, the script appears to run normally and I am landed at the royal court:

Image
Image

Re: Galactic Almanac OXZ - Full Version 0.92 - Now on the Expansion Pack Manager (Updated 12.08.23)

Posted: Sat Aug 26, 2023 10:32 pm
by Cholmondely
LittleBear wrote: Sat Aug 26, 2023 2:31 pm
The only change made is to the displayName at line 4008, which reads:-

Code: Select all

if(ship.hasRole("planetFall_mainSurface_FSRoyalCourt")) ship.displayName = ""+expandDescription("[named_stations_planetFall_mainSurface_FSRoyalCourt_name]"); 
This shouldn't break the script as the test is for role rather than displayName name. Does Feudal States run properly at the orbital hunting lodges?

To test it, could you comment out line 4008 so it now reads:

Code: Select all

//if(ship.hasRole("planetFall_mainSurface_FSRoyalCourt")) ship.displayName = ""+expandDescription("[named_stations_planetFall_mainSurface_FSRoyalCourt_name]");


Does the Royal Court now appear with this change?

Can't reproduce the bug myself as landed on the main planet, the script appears to run normally and I am landed at the royal court:

Image
Image
The Royal Hunting Lodges work just fine.

On landing on the planets I was not finding the Royal Palace - either renamed or not - just all those other bizarre locations.

From v.1.4 (I'm now using your up-to-date version):

Code: Select all

// Keys to Generate names for PlanetFall Landing Sites.
// As Planet Fall generates Landing Sites at Random, they are not peristant and so as with the Ship Names above,
// These are generated on the fly with an expandDescription.
// A different style is used for each type of landing site.

// General Opening Words used for different types of Landing Site.

	"named_stations_planetFall_opening_words1" =
	(
	"[named_stations_planetFall_opening_words1_alt5] Control",
	"[named_stations_planetFall_opening_words1_alt5] Control",
	"Tourist [named_stations_planetFall_opening_words1_alt]",
	"[named_stations_planetFall_opening_words1_alt3] of [named_stations_planetFall_opening_words1_alt4]",
	"Visitors [named_stations_planetFall_opening_words1_alt]",
	"[named_stations_planetFall_opening_words1_alt6] Embassy",
	"Planatary Capital",
	"Trading [named_stations_planetFall_opening_words1_alt]",
	);

	"named_stations_planetFall_opening_words1_alt" =
	(
	"Centre",
	"Hub",
	"Facility",
	);

	"named_stations_planetFall_opening_words1_alt3" =
	(
	"Ministry",
	"Department",
	);

	"named_stations_planetFall_opening_words1_alt4" =
	(
	"Information",
	"Trade",
	"Tourism",
	"Commerce",
	);

	"named_stations_planetFall_opening_words1_alt5" =
	(
	"Ground",
	"Immigration",
	"Traffic",
	"Passport",
	"Customs",
	);

	"named_stations_planetFall_opening_words1_alt6" =
	(
	"GalCop",
	"Imperial",
	"Federation",
	"Planetary",
	);

	"named_stations_planetFall_opening_words2" =
	(
	"Repair [named_stations_planetFall_opening_words2_alt]",
	"Servicing [named_stations_planetFall_opening_words2_alt]",
	"Upgrade [named_stations_planetFall_opening_words2_alt]",
	"Spare Parts [named_stations_planetFall_opening_words2_alt]",
	"Armaments [named_stations_planetFall_opening_words2_alt]",
	"Munitions [named_stations_planetFall_opening_words2_alt]",
	"Refurbishment [named_stations_planetFall_opening_words2_alt]",
	"Weapons [named_stations_planetFall_opening_words2_alt]",
	"Spacecraft Dealership",
	"Maintenance [named_stations_planetFall_opening_words2_alt]",
	);

	"named_stations_planetFall_opening_words2_alt" =
	(
	"Facility",
	"Complex",
	"Centre",
	"Depot",
	);

	"named_stations_planetFall_opening_words3" =
	(
	"[named_stations_planetFall_opening_words3_alt] [named_stations_planetFall_opening_words3_alt2]",
	);

	"named_stations_planetFall_opening_words3_alt" =
	(
	"Military",
	"Naval",
	"Airforce",
	"Army",
	);

	"named_stations_planetFall_opening_words3_alt2" =
	(
	"Base",
	"Compound",
	"Headquarters",
	"Outpost",
	);

	"named_stations_planetFall_opening_words4" =
	(
	"Public [named_stations_planetFall_opening_words4_alt3a]",
	"Strip [named_stations_planetFall_opening_words4_alt3]",
	"Drinking Den",
	"Licensed [named_stations_planetFall_opening_words4_alt]",
	"[named_stations_planetFall_opening_words4_alt2] Nightclub",
	"[named_stations_planetFall_opening_words4_alt2] Discotech",
	"[named_stations_planetFall_opening_words4_alt2] Speakeasy",
	"[named_stations_planetFall_opening_words4_alt2] Saloon",
	"[named_stations_planetFall_opening_words4_alt2] [named_stations_planetFall_opening_words4_alt4]",
	"[named_stations_planetFall_opening_words4_alt2] Roadhouse",
	"[named_stations_planetFall_opening_words4_alt2] Motel",
	"[named_stations_planetFall_opening_words4_alt2] Hotel",
	);

	"named_stations_planetFall_opening_words4_alt" =
	(
	"Cafe",
	"Restaurant",
	);

	"named_stations_planetFall_opening_words4_alt2" =
	(
	"Seedy",
	"Underground",
	"Disreputable",
	"Insalubrious",
	"Sketchy",
	);

	"named_stations_planetFall_opening_words4_alt3" =
	(
	"Joint",
	"Club",
	);

	"named_stations_planetFall_opening_words4_alt3a" =
	(
	"House",
	"Bar",
	);

	"named_stations_planetFall_opening_words4_alt4" =
	(
	"Tavern",
	"Establishment",
	);

	"named_stations_planetFall_opening_words5" =
	(
	"[named_stations_planetFall_opening_words5a] [named_stations_planetFall_opening_words5b]",
	);

	"named_stations_planetFall_opening_words5a" =
	(
	"Industrial",
	"Manufacturing",
	"Urban",
	);

	"named_stations_planetFall_opening_words5b" =
	(
	"Zone",
	"District",
	"Complex",
	"Area",
	"Heartland",
	"Sector",
	"Region",
	"Quadrant",
	);

	"named_stations_planetFall_opening_words6" =
	(
	"[named_stations_planetFall_opening_words6a] [named_stations_planetFall_opening_words6b]",
	);

	"named_stations_planetFall_opening_words6a" =
	(
	"Agricultural",
	"Rural",
	"Pastoral",
	"Horticultural",
	"Arable",
	);

	"named_stations_planetFall_opening_words6b" =
	(
	"Zone",
	"District",
	"Area",
	"Sector",
	"Region",
	"Quadrant",
	);

	"named_stations_planetFall_opening_words7" =
	(
	"[named_stations_planetFall_opening_words7a] [named_stations_planetFall_opening_words7b]",
	"[named_stations_planetFall_opening_words7c] [named_stations_planetFall_opening_words7d]",
	"[named_stations_planetFall_opening_words7c] [named_stations_planetFall_opening_words7d]",
	);

	"named_stations_planetFall_opening_words7a" =
	(
	"Corn",
	"Rice",
	"Barley",
	"Poppy",
	"Tulip",
	"Orchid",
	"Potato",
	"Tobacco",
	);

	"named_stations_planetFall_opening_words7b" =
	(
	"Field",
	"Plantation",
	);

	"named_stations_planetFall_opening_words7c" =
	(
	"Windswept",
	"Fertile",
	"Cultivated",
	"Marshy",
	"Barren",
	"Swampy",
	);

	"named_stations_planetFall_opening_words7d" =
	(
	"Fields",
	"Meadows",
	"Farmland",
	"Grassland",
	"Pastures",
	"Countryside",
	"Wetlands",
	);

	"named_stations_planetFall_opening_words8" =
	(
	"[named_stations_planetFall_opening_words8a] [named_stations_planetFall_opening_words6b]",
	);

	"named_stations_planetFall_opening_words8a" =
	(
	"Radioactive",
	"Biohazardous",
	"Recycling",
	"Disposal",
	"Contaminated",
	"Infected",
	"Quarantined",
	);

	"named_stations_planetFall_opening_words9" =
	(
	"[named_stations_planetFall_opening_words9_alt] [named_stations_planetFall_opening_words9_ending]",
	"[named_stations_planetFall_opening_words9_alt2] [named_stations_planetFall_opening_words9_ending]",
	"[named_stations_planetFall_opening_words9_alt3] [named_stations_planetFall_opening_words9_ending2]",
	);

	"named_stations_planetFall_opening_words9_alt" =
	(
	"Retail",
	"Mercantile",
	"Diplomatic",
	"Demilitarized",
	"Urban",
	);
	
	....etc.
	

Anyways, I'll give your tweak a bash!



NB:

The Palace of Daring at Digebiti? I see that I never came up with a decent name for the palace.

I'll have to have a ponder. Unless Cody beats me to it. The Cocktail Throne was one of his...

Re: Galactic Almanac OXZ - Full Version 0.92 - Now on the Expansion Pack Manager (Updated 12.08.23)

Posted: Sat Aug 26, 2023 11:12 pm
by LittleBear
Planetfall generates random landing sites each time you land from its own 'deck' of different types of landing site (shipyards, military bases, dumps etc). The Almanac gives them names appropriate to the type of landing site, but it is planetfall's code that generates the landing sites. If you have the feudal states, black monks, oo-haul or random hits planetfall extensions installed then these cards are added to the deck (if conditions on tech level or government are met). However, they are just one card added to planetfall's pack of random landing sites. So you won't persistently land at a royal lodge or black monk monastery each time you land on the same planet. The Almanac adds names to the planetfall landing sites, but its intended behaviour of planetfall that you are dealt a random location each time you land.

Re: Galactic Almanac OXZ - Full Version 0.92 - Now on the Expansion Pack Manager (Updated 12.08.23)

Posted: Sat Aug 26, 2023 11:48 pm
by Cholmondely
LittleBear wrote: Sat Aug 26, 2023 11:12 pm
Planetfall generates random landing sites each time you land from its own 'deck' of different types of landing site. If you have the feudal states, black monks, oo-haul or random hits planetfall extensions installed then these cards are added to the deck (if conditions on tech level or government are met). However, they are just one card added to planetfall's pack of random landing sites. So you won't persistently land at a royal lodge or black monk monastery each time you land on the same planet. The Almanac adds names to the planetfall landing sites, but its intended behaviour of planetfall that you are dealt a random location each time you land.
So how does one ensure that one visits the Royal Court on landing at a Feudal State? Is there some sort of built-in mechanism which allows this?

Eg: I end up landing at the Shipyard/Leisure Complex/Shenony customs control etc. - how do I get from these to the commodity markets? Or from customs control to the Shipyards? Or from any of them to the Royal Courts?

LitF?

Maybe Stranger addressed this in his PlanetLand?
Instructions:

To lock PLC homing system onto PlanetLand port just lock Advanced Astro Compass onto planet/moon of destination.
Locking Advanced Astro Compass onto any other target will override PlanetLand port with external OXP port (Royal Court in The Feudal Systems for example) or with fields by default.
Excess landing speed > 0.25 of max speed (beyond green sector) will cause missed approach and landing in fields too.
Precise landing is result of joint effort of ship avionics and ground service. Sometimes missed approach may be result of malfunction of ship avionics (risk increased with PLC tear and wear) or ground service failure (risk increased in low tech systems with unstable governments).

After landing on surface port you may call pictures (just for fun!):

F3 -> F7 Port view
F4 -> F7 Port terminal view
F5 -> F7 Planet/moon landscape
F8 -> F7 City/station view

To view system data screen call F7 screen from F6 screen as usual.

Невидимый геймеру Оониверсум
Локации, о которых пойдет речь ниже, теперь недоступны для непосредственного посещения. Тем не менее я решил остатить информацию о них, чтобы дать представление о скрытых механизмах, формирующих видимый геймеру рынок столичного порта или планетной/лунной колонии.
Mine Complex — горно-обогатительный комплекс
Горно-обогатительные комплексы (шахты) — основание техно- логической пирамиды Оониверсума. Несмотря на то, что большая часть сырья добывается на астероидных приисках, лунные и планетные шахты сохраняют свое стратегическое значение как альтернативные источники сырья для обеспечения независимости систем в случае военной блокады или экономических санкций.
В низкоразвитых мирах с сырьевой экономикой шахты — основной источник пополнения бюджета. В мирах с развитой аграрной или сбалансированной экономикой деятельность горнодобывающих компаний подпадает под жесткие нормы охраны окружающей среды, добыча сырья ведется только на лунах и внешних планетах. Высокоразвитые системы с постиндустриальной экономикой также предпочитают выносить грязные производства за пределы главной планеты, чтобы снизить давление техносферы на окружающую среду.
Изначально шахты на главных планетах специализировались на добыче сырья для промышленности, на лунах — обеспечивали добычу гелия-3 для термоядерной энергетики. С переходом энергетики на квирий лунные шахты также перепрофилировались на добычу минералов, радиоизотопов и драгоценных металлов.
Большим спросом на шахтах пользуются продукты питания и особенно алкоголь. Шахты также нуждаются в большом количестве механизмов, однако в развитых индустриальных мирах налажено
снабжение шахт механизмами, произведенными на местных заводах.
Шахты — основной потребитель неквалифицированной рабочей силы из низкоразвитых миров. В нестабильных системах существует развитая сеть работорговли, поставляющая рабочие руки владельцам шахт в обход центрального рынка.
Спрос на электронику, предметы роскоши, меха на шахтах отсутствует.
Горно-обогатительный комплекс на луне Орерве (Orerve). Старый комбайн для сбора гелия-3 из грунта, переоборудованный под цех рудного процессинга.

Factory Complex — завод
В индустриальных мирах заводы — это стержень экономики системы и градообразующие предприятия. Колонизация мало- пригодных для жизни пустынных планет обычно начиналась со временных лагерей вокруг рудников и металлургических заводов, где персонал работал вахтовым методом. Со временем временные лагеря обустраивались и дали начало постоянным поселениям.
В индустриальных среднеразвитых и развитых системах основная продукция заводов — машины, механизмы и инструменты. Индус- триальные зоны в этих системах представляют собой экологически неблагополучные регионы с высокой смертностью и хроническими заболеваниями. Роботизированные заводские комплексы в высокоразвитых постиндустриальных системах, производящие электронику, изолированы от окружающей среды под герметич- ными куполами дня снижения нагрузки на окружающую среду.
Как и шахты, заводы испытывают потребность в продуктах питания. Большим спросом пользуется алкоголь.
Потребность в рабочей силе, особенно неквалифицированной, на современных заводах практически отсутствует вследствие высокой автоматизации производства.
Значительную долю продукции заводов составляет оружие. Нелегальный рынок оружия — существенная составляющая поступ- лений в бюджет нестабильных систем. Емкость нелегального рынка оружия по оценкам экспертов более чем достаточна не только для оснащения незаконных вооруженных формирований, но и для ведения активных военных действий регионального масштаба.
Индустриальный район на Куатор II (Quator II) держит мрачный рекорд минимальной продолжительности жизни в Первом секторе. Оранжереи на башнях атмосферного процес- синга — единственное место, где заводской персонал может находиться без дыхательных аппаратов замкнутого цикла.
PlanetLand.oxp

Farm — ферма
Виноградные плантации Дисо (Diso), питомники древесного червя Лэйв (Lave), плантации ксенокоралла Анарлаку (Anarlaqu) — продукция этих фермерских хозяйств пользуется популярностью в самых изысканных ресторанах восьми секторов Галактики, а пасторальные пейзажи аграрных планет привлекают нескончаемые потоки туристов. Истина, однако, такова, что массовое производство продуктов питания в плотно населенных мирах производится интенсивным способом на аквапонных фермах. Аквапоника в традиционном понимании — высокотехнологичный способ ведения сельского хозяйства, сочетающий аквакультуру (выращивание водных животных) и гидропонику (выращивание растений без грунта). Успехи биоинженерии привели к тому, что текстиль не производится на ткацких станках, а тоже выращивается.
Ассортимент сельскохозяйственной продукции зависит от технологического уровня системы.
В аграрных мирах низкого технологического уровня преобладает производство продуктов питания и очищенной питьевой воды, которое не требует больших инвестиций в дорогостоящее высокотехнологичное оборудование и квалифицированного труда высокоооплачиваемого персонала. Повышенным спросом в низкоразвитых аграрных системах пользуются сельскохозяйст- венные механизмы, а также стрелковое оружие. Фермеры исполь- зуют оружие для защиты от хищной фауны и бандитов, а также для охоты на зверя и на человека. По докладу экспертов организации “Межгалактическая амнистия”, нищие низкоразвитые аграрные миры поставляют основную часть человеческого материала работорговцам.
В среднеразвитых аграрных мирах основная доля экспорта приходится на продукцию с высокой добавленной стоимостью — алкоголь и меха, а в развитых аграрных системах — на биофармацевтику, использующую ресурсы местных экосистем.
В таких системах пользуется большим спросом электроника, которая используется для контроля производственного процесса в биоинженерии и биофармацевтике.
На рынках внешних планет и лун меха отсутствуют, а производи- мый там алкоголь яваляется очищенным и купажированным спиртом из растительной биомассы (да, мой юный Джеймсон, знаменитый листианский “дьявольский сок” — это то самое).
Купола аквапонных ферм на Дисо III (Diso III).

Research Complex — научная станция
Научная станция — первый объект, который появляется на неосвоенных небесных телах, и зачастую он остается единственным объектом в недружественной для жизни среде. В густозаселенных колонизированных мирах научная станция сохраняет свое значение исследовательского центра. Темы исследований много- образны, как многообразна окружающая среда: от изучения автохтонных биотопов до масштабных проектов терраформинга, от этнолингвистических исследований до разработки уникальных технологий, от изучения вирусных инфекций до картирования Галактики. Вакцина против смертоносного вируса красной гнили, наноботы, навигация и связь через гиперпространство, Q-энергетика — новая реальность Оониверсума родилась в стенах научных станций.
Научные станции имеют статус представительства Галактического Содружества, их многорасовый персонал находится под защитой Галкопа и неподконтролен местным властям. Обратная сторона ситуации — персоналу научных станции запрещено заниматься коммерческой деятельностью и заключать какие-либо контракты на исследования в интересах властей и частных компаний без согласования с Научным советом Галкопа. Руководство научных станций, однако, имеет право закупать необходимые припасы, снаряжение и оборудование у частных поставщиков.
Научная станция на внешней планете или луне, где может не быть постоянной колонии — изолированное автономное поселение. На рынке научной станции пользуются большим спросом продукты питания и в особенности алкоголь. Повышенным спросом также пользуются механизмы и электроника.
Ходят неподтвержденные слухи, что значительная доля исследований приходится на “черные” проекты в интересах Галкопа и Галактического флота. По частным сообщениям премиальные выплаты за подобранных в открытом пространстве таргонов
значительно выше, чем на рынках прочих объектов.
В мастерских научной станции производится лишь жизненно важный ремонт и дооснащение корабля. Вы можете отремонтиро- вать поврежденный в бою корпус корабля и дозаправиться топливом. На внешних планетах вам также предложат подвесные топливный бак для возвращения к главной планете, если система
имеет соответствующий минимальный технологический уровень. Сервисные услуги на научной станции обходятся дороже, чем в
главном порту.
Научно-исследовательский комплекс в составе колонии на луне Тионислы (Tionisla) - ведущий центр астрофизических исследований. Именно в этом центре были созданы карты дальней навигации.


Aerostatic Research Complex — атмосферная научная станция
Научная станция в атмосфере планеты-гиганта играет роль, аналогичную роли научных станций на внешних планетах и лунах системы. Вследствие своего расположения, однако, эти дрейфую- щие в атмосфере комплексы имеют дело со специфической средой. В свое время активно обсуждались проекты сбора квирия из верхней атмосферы планет-гигантов (проект Gas Giant Skimming корпорации Deep Horizon), однако успешное внедрение технологии сбора звездного ветра радикально изменило экономическую коньюктуру и персонал атмосферных станций в наше время занят в основном фундаментальными исследованиями в астрофизике и планетологии. Ходят слухи, однако, что изолированное положение этих объектов и их неподконтрольный правительствам системы статус как нельзя лучше подходит для работы над “черными” проектами наивысшей степени секретности.
Как и прочие научные станции на внешних планетах, атмосферные научные комплексы нуждаются в продуктах питания, алкоголе, механизмах и электронике. Сервис ограниченный, как и на всех научных станциях доступны лишь неотложные ремонтные работы и дозаправка корабля топливом.
Посадка на атмосферный комплекс имеет свои особенности. Так как это единственный порт на планете-гиганте, посадка вне его исключена. Учитывая специфику внешней среды, к надежности системы привода предъявляются чрезвычайно жесткие требования и вероятность срыва захвата практически равна нулю. Неисправ- ность теплозащиты корабля, может, однако, привести к его разрушении при вхождении в плотные слои атмосферы, поэтому при сообщении о неисправности PLC незамедлительно переходите в набор высоты.
Научная станция в атмосфере газового гиганта Онрира III (Onrira III) — признанный центр исследований атмосфер планет- гигантов. По слухам, именно эта станция была избрана как полигон для первого испытания каскадной бомбы.
PlanetLand.oxp

Leisure Complex — центр досуга
Индустрия туризма и развлечений составляет значительную долю бюджета многих систем, а порой и его основную. Коммунистические историки уверяют, что идея культурно-развлекательного центра — подражание старой идее парка культуры и отдыха (ПКО). Их демократические оппоненты оспаривают это мнение, ссылаясь на легендарный Диснейлэнд старой Гайи (теперь уже невозможно сказать с уверенностью, была ли это страна или остров). Во всяком случае, даже самые захудалые малоразвитые миры не скупятся на средства для привлечения туристов, строя курортные зоны, куда нет доступа простым неимущим гражданам. Ярким примером курорта планетарного масштаба является главная планета системы Заонце (Zaonce), превращенная местными властями в огромный центр досуга (смотрите соответствующую главу “Путевых набросок по Оониверсуму” — Rough Guide to the Ooniverse by Disembodied).
Взыскательный искатель приключений, гурман и сибарит найдут в центрах досуга все для того, чтобы время отпуска утекло приятно и незаметно. Во многочисленных гипермаркетах, бутиках, салонах и сувенирных лавочках заезжий турист так же приятно и незаметно расстанется с карманной наличностью.
Не столь давно местные власти систем зачастую игнорировали нелегальную частную торговлю в зонах отдыха - она гласно не поощрялась, но в общем и не преследовалась. Лишь недавно в этой области совместными усилиями администрации Галкопа и местных властей наведен относительный порядок и теперь центры досуга доступны для посещения лишь по туристической визе, а вывоз товара из них декларируется как приобретение для личного пользования.
В богемной обстановке центров отдыха еда, текстиль, алкоголь, меха, предметы роскоши ценятся дорого — с точки зрения рядового потребителя, непомерно дорого — и пользуются большим спросом.
индустрия секс-услуг. Молодые привлекательные рабыни в центрах досуга ценятся значительно выше, чем здоровые мускулистые рабы на рудниках.
На лунах и внешних планетах центры досуга выполняют функцию психологической разгрузки персонала. Приток туристов в эти заведения немногочислен, но если вам придется заглянуть в такое заведение, это лучшее место для уютного отдыха и пересыпа между утомительными перелетами.
Грандиозное голографическое этнокультурное щоу в храмовом комплексе на Реорте (Reorte).
Etc, etc... 19 page illustrated brochure!

Re: Galactic Almanac OXZ - Full Version 0.92 - Now on the Expansion Pack Manager (Updated 12.08.23)

Posted: Sun Aug 27, 2023 12:00 am
by Cholmondely
I think that this contains Stranger's code for choosing one's landing site (nabbed from Roolite).

See // ENTER COMPASS CHECK HERE

Code: Select all

"use strict";
this.name			= "PlanetFall";
this.author			= "Stranger";
this.copyright		= "Creative Commons Attribution - Non-Commercial - Share Alike 3.0 license with clauses - see readme.txt.";
this.description	= "Enables planetary landing.  Tightly based on Thargoid's PlanetFall v 1.51.1";
this.version		= "2.6.1";

//Main events

this.startUp = function()
	{
	this.$lastPlanet = system.mainPlanet; // details of the last planet to be landed on, so we know what to move the player away from on launch
	this.$planetFallLaunch = false; // as in 1.77 the alert condition is still set on launch - need a mask
	this.$lastPlanetType = "Prime"; // what type of planet/moon we landed on
	this.$messageBlock = false; // flag to stop request/cancel messages at launch from planet
	this.$planetCount = 1; // default setting
	this.$moonCount = 0; // default setting
	this.$systemScan(); // set up the initial planet and moon count
	this.planetFallOverride = false; // flag to allow other OXPs to override PlanetFall locations
	this.overrideRole = "default"; // if other OXPs want to ensure a specific role is used
	this.$checkForSpecialPlanets();
    this.$gasGiantRadius = 100000;  // set filter fo giant planets
    this.$planetTerranRadius = 40000; // set filter to planets with dense atmosphere
    this.$systemState();
    this.$trafficState();
    this.$sectorOnePlanetList = [0,1,2,3,4,7,8,10,11,13,16,17,18,19,20,21,23,28,29,35,36,39,42,44,46,50,55,62,66,73,86,89,90,93,99,100,101,111,118,124,126,129,131,132,141,147,150,153,154,172,177,186,188,198,200,221,222,227,228,241,246,250]; // Famous Planets Sector One
    this.$sectorTwoPlanetList = [6,23,24,29,33,42,45,48,53,54,57,58,65,66,74,78,82,88,94,109,113,114,115,122,127,136,140,144,178,188,189,193,202,204,207,221,236]; // Famous Planets Sector Two

/* For convenience of mission writers, access for other OXPs is via "worldScripts.PlanetFall.lastPlanet" and "worldScripts.PlanetFall.lastPlanetType". 
Values for lastPlanetType are "Prime" for the main planet, "Sub" for every other planet, "Moon" for any moon and "Sun" / "GasGiant" for a sun or a Solar System OXP 
gas giant (for completeness - cannot land on either of the last two). */
	}

this.shipWillLaunchFromStation = function(station)
	{
	if(station)
		{ 
		this.$planetFallLaunch = true;
        player.ship.hudHidden = false;
		if(station.hasRole("planetFall_surface"))
			{
			this.fx = system.addVisualEffect("planetFall_launchFX",player.ship.position.add(player.ship.vectorForward.multiply(150)));
			this.fx.orientation = player.ship.orientation;
			}
		} 
	}

this.shipLaunchedFromStation = function(station)
	{
	if(EquipmentInfo.infoForKey("EQ_FRAME_SAVE") != null) // if launch is for Save Anywhere, don't want to move the player or nuke the station
		{ return; }

	if(station && station.hasRole("planetFall_surface"))
		{
		if(this.$landingTimer) 
			{ delete this.$landingTimer; }	
		player.commsMessage(system.name + " Planetary Control - orbital boost complete.",5);
		player.commsMessage("Farewell Commander " + player.name + ".",5);
		this.$removePort(station); // remove the surface-simulating station
		this.$messageBlock = false;
		missionVariables.planetFallBreak += 0.001; // 0.1% cumulative chance of equipment failure 
		if(Math.random() < missionVariables.planetFallBreak) // landing equipment needs maintenance
			{
			player.ship.setEquipmentStatus("EQ_PLANETFALL", "EQUIPMENT_DAMAGED");
			player.consoleMessage("ALERT - Planetary landing modifications require urgent maintenance.", 10);
			player.consoleMessage("Do not attempt to land again before they are repaired!", 10);
			missionVariables.planetFallBreak = 0; // used equipment, no guarantee
			}
		}

	this.$systemScan();
	}

this.shipExitedWitchspace = function()
	{
	this.$checkForSpecialPlanets();
	this.overrideRole = "default";
	this.$systemScan();
    this.$systemState();
    this.$trafficState();
	}

this.shipEnteredPlanetaryVicinity = function(planet)
	{
	if(!planet) { return; }

    this.$trafficState();
	this.$lastPlanet = planet;
	if(!planet.isSun && !planet.hasOwnProperty("solarGasGiant") && !planet.hasOwnProperty("isGasGiant") && !planet.hasOwnProperty("PFNoLand") && !planet.hasOwnProperty("PFNoLandQuiet") && player.ship.equipmentStatus("EQ_PLANETFALL") == "EQUIPMENT_OK")
		{
		player.commsMessage(system.name + " Planetary Control - for planetfall please approach and request landing clearance.",5);
		}
	else
		{
		if(planet.isSun)
			{ player.consoleMessage("ALERT - Approaching the Sun. Temperature monitoring is critical!", 10); }
		if(planet.hasOwnProperty("solarGasGiant") || planet.hasOwnProperty("isGasGiant"))
			{ player.consoleMessage("ALERT - You are approaching a Gas Giant. Landing here is not possible!", 10); }
		if(planet.hasOwnProperty("PFNoLand"))
			{ player.commsMessage("ALERT - Landing is not possible here, please pull up!", 10); }
		}
	}

this.shipExitedPlanetaryVicinity = function()
	{ 
	this.$messageBlock = false; 
	this.shipDied(); // clean-up of any unremoved surface stations.
	}

this.alertConditionChanged = function()
	{
	if(this.$planetFallLaunch)
		{
		this.$planetFallLaunch = false;
		return;
		}

	if(player.alertAltitude && !this.$lastPlanet.isSun && !this.$lastPlanet.hasOwnProperty("solarGasGiant") && !this.$lastPlanet.hasOwnProperty("PFNoLand") && !this.$lastPlanet.hasOwnProperty("PFNoLandQuiet") && !this.$lastPlanet.hasOwnProperty("isGasGiant"))
		{
		if(player.ship.equipmentStatus("EQ_PLANETFALL") != "EQUIPMENT_OK")
			{
			player.commsMessage(system.name + " Planetary Control - Your ship is not equipped for planetfall.", 10);
			player.commsMessage("Do not attempt landing, your ship will be destroyed!", 10);
			}
		else
			{
			if(!this.$messageBlock)
				{
				player.commsMessage(system.name + " Planetary Control - Landing clearance request received.", 6);
				player.commsMessage("Please await confirmation before beginning final approach.", 6);
				}
            if(Math.random() > 0.75 - 0.5 * missionVariables.planetFallBreak + 0.25 * this.$serviceLevel) // malfuncttion of homing beacon
                {
                this.$homingLock = 0;
                }
			else
                {
                this.$homingLock = 1;
                }
            this.$clearanceDelay = 5 + Math.ceil(Math.random() * 15); // delay between 6 and 20 seconds
			this.$landingTimer = new Timer(this, this.$landingClearance, this.$clearanceDelay);
            // a bit surprice...
            if(Math.random() > 0.90 + 0.025 * system.government && this.$lastPlanet.radius < this.$gasGiantRadius)
                {
                system.addShips("pirate", 4, player.ship.position, 15000);
                }
			}
		}

	if(player.alertAltitude && (this.$lastPlanet.hasOwnProperty("solarGasGiant") || this.$lastPlanet.hasOwnProperty("isGasGiant")))
		{ player.consoleMessage("ALERT - You are approaching a Gas Giant. Landing here is not possible!", 10); 	}

	if(player.alertAltitude && this.$lastPlanet.hasOwnProperty("PFNoLand"))
		{ 
		player.consoleMessage("ALERT - Landing here is not possible!", 10); 
		return;
		}
		
	if(!player.alertAltitude && this.$landingTimer && this.$landingTimer.isRunning && !player.ship.docked && EquipmentInfo.infoForKey("EQ_FRAME_SAVE") == null)
		{
		this.$landingTimer.stop();
		delete this.$landingTimer;
		missionVariables.planetFallBreak += 0.001; // 0.1% cumulative chance of equipment failure
		if(!this.$messageBlock)
			{
			player.commsMessage(system.name + " Planetary Control - Landing clearance request cancelled.", 6);
			player.commsMessage("Goodbye Commander " + player.name + ".", 6);
			this.$messageBlock = false;
			}
		}
	}

this.shipApproachingPlanetSurface = function(planet) 
	{
	if(!planet || player.ship.equipmentStatus("EQ_PLANETFALL") != "EQUIPMENT_OK" || planet.hasOwnProperty("PFNoLandQuiet"))
		{
		return;
		}

	if(planet.hasOwnProperty("PFNoLand"))
		{
		player.commsMessage(system.name + " Planetary Control - Urgent warning - landing is not possible here!", 6);
		return;	
		}	
	
	this.$lastPlanet = planet;	

    var landingFlag;
    if(player.ship.speed > 0.25 * player.ship.maxSpeed)
        {
        landingFlag = 2; // excess speed - missed approach
        }
    else
        {
        landingFlag = 1;
        }    

    // ENTER COMPASS CHECK HERE
    var targetVector = new Vector3D(player.ship.position.subtract(player.ship.compassTarget.position));
    var targetDistance = Math.floor(targetVector.magnitude());            
    var targetDistanceMax = this.$lastPlanet.radius + 500;
    if(targetDistance < this.$lastPlanet.radius || targetDistance > targetDistanceMax)
        {
        this.$landingChoice = 0;
        }
    else
        {
        this.$landingChoice = landingFlag;
        }

    if(this.$landingChoice != 0)
        {
        this.planetFallOverride = false;
        }

	if(!this.$landingTimer)  
		{
		if(!planet.isSun && !planet.hasOwnProperty("solarGasGiant") && !planet.hasOwnProperty("isGasGiant"))
			{
			this.$messageBlock = true;
			if(planet === system.mainPlanet)
				{
				this.$lastPlanetType = "Prime";
				if(this.planetFallOverride)
					{
					if(this.overrideRole === "default")
						{ this.overrideRole = "planetFall_mainSurface_externalOXP" };
					this.$port = player.ship.spawnOne(this.overrideRole);
					this.$turnStation(this.$port);
					this.overrideRole = "default";
					}
				else                
					{
					if(this.$landingChoice == 1) // spawn capital city
						{
						this.$port = player.ship.spawnOne(this.$mainPort1); 
						this.$turnStation(this.$port);
						}
					if(this.$landingChoice == 2 || this.$homingLock == 0) // spawn open fields
						{
						this.$port = player.ship.spawnOne(this.$mainPort2); 
						this.$turnStation(this.$port);
						}
					if(this.$landingChoice == 0) // spawn external OXP location, or if none then open fields
						{
						if(this.overrideRole !== "default") 
							{ this.$port = player.ship.spawnOne(this.overrideRole); }
							else
							{ this.$port = player.ship.spawnOne("planetFall_mainSurface_externalOXP"); }
						if(!this.$port)
							{
							log(this.name, "Main surface external spawn failure");
							this.$port = player.ship.spawnOne(this.$mainPort2); 
							}					
						this.$turnStation(this.$port);
						this.overrideRole = "default";
						}
					}

                if(this.$lastPlanet.radius >= this.$gasGiantRadius)
                    {
                    this.$port = player.ship.spawnOne(this.$mainPort3); 
                    this.$turnStation(this.$port);
                    }
					
				if(this.$lastPlanet.name)
					{ this.$port.displayName = this.$lastPlanet.name + " - " + this.$port.displayName; }
				else
					{ this.$port.displayName = system.name + " Prime - " + this.$port.displayName; } // set the name to the surface of the prime planet in the system
				}
			else
				{
				if(planet.hasAtmosphere)
					{
					this.$lastPlanetType = "Sub";
					if(this.planetFallOverride)
						{
						if(this.overrideRole == "default") { this.overrideRole = "planetFall_subSurface_externalOXP"; };
						this.$port = player.ship.spawnOne(this.overrideRole);
						this.$turnStation(this.$port);
						this.overrideRole = "default";
						}
					else
						{ 
						if(this.$landingChoice == 1) // spawn colony city
                            {
                            this.$port = player.ship.spawnOne(this.$minorPort1); 
                            this.$turnStation(this.$port);
                            }
                        if(this.$landingChoice == 2 || this.$homingLock == 0) // spawn open fields
                            {
                            this.$port = player.ship.spawnOne(this.$minorPort2); 
                            this.$turnStation(this.$port);
                            }
						if(this.$landingChoice == 0) // spawn external OXP location, or if none then open fields
							{
							if(this.overrideRole !== "default") 
								{ this.$port = player.ship.spawnOne(this.overrideRole); }
								else
								{ this.$port = player.ship.spawnOne("planetFall_subSurface_externalOXP"); }
							if(!this.$port)
								{
								log(this.name, "Sub surface external spawn failure");
								this.$port = player.ship.spawnOne(this.$minorPort2);
								}	
                            this.$turnStation(this.$port);
							this.overrideRole = "default";
							}
                            
                        if(this.$lastPlanet.radius >= this.$gasGiantRadius)
                            {
                            this.$port = player.ship.spawnOne(this.$minorPort3); 
                            this.$turnStation(this.$port);
                            }
						}

					if(this.$lastPlanet.name)
						{ this.$port.displayName = this.$lastPlanet.name + " - " + this.$port.displayName; }
					else
						{ this.$port.displayName = system.name + " Minor - " + this.$port.displayName; } // set the name to just the surface, so we can identify easily the main planet
					}
				else
					{
					this.$lastPlanetType = "Moon";
					if(this.planetFallOverride)
						{
						if(this.overrideRole == "default") { this.overrideRole = "planetFall_moonSurface_externalOXP" };
						this.$port = player.ship.spawnOne(this.overrideRole);
						this.$turnStation(this.$port);
						this.overrideRole = "default";
						}
					else
						{
						if(this.$landingChoice == 1) // spawn lunar colony
							{
                            this.$port = player.ship.spawnOne(this.$moonPort1); 
                            this.$turnStation(this.$port);
                            }
                        if(this.$landingChoice == 2 || this.$homingLock == 0) // spawn open fields
                            {
                            this.$port = player.ship.spawnOne(this.$moonPort2); 
                            this.$turnStation(this.$port);
                            }
						if(this.$landingChoice == 0) // spawn external OXP location, or if none then open fields
							{
							if(this.overrideRole !== "default") 
								{ this.$port = player.ship.spawnOne(this.overrideRole); }
								else
								{ this.$port = player.ship.spawnOne("planetFall_moonSurface_externalOXP"); }
							if(!this.$port)
								{
								log(this.name, "Moon external spawn failure");
								this.$port = player.ship.spawnOne(this.$moonPort2); 
								}	
							this.$turnStation(this.$port);
							this.overrideRole = "default";
							}
						}

					if(this.$lastPlanet.name)
						{ this.$port.displayName = this.$lastPlanet.name + " - " + this.$port.displayName; }
					else
						{ this.$port.displayName = "Moon of " + system.name + " - " + this.$port.displayName; } // set the name to the moon, so we can identify it as a moon
					}
				}
			this.fx = system.addVisualEffect("planetFall_landingFX",player.ship.position.add(player.ship.vectorForward.multiply(170)));	
			this.$port.dockPlayer();	
			}
		else
			{
			if(planet.hasOwnProperty("solarGasGiant") || planet.hasOwnProperty("isGasGiant"))
				{
				this.$lastPlanetType = "GasGiant";
				}
			else
				{
				this.$lastPlanetType = "Sun";
				}
			}
		}
	else
		{ // if the PF landing timer is still running
		player.commsMessage(system.name + " Planetary Control - Pull up, you have no landing clearance!", 6);
		player.commsMessage("Return to orbit and approach again.", 6);
		this.$landingTimer.stop();
		delete this.$landingTimer;
		}
	}

this.shipWillDockWithStation = function(station)
	{
	if(station.hasRole("planetFall_surface") || station.hasRole("planetFall_mainSurface_externalOXP") || station.hasRole("planetFall_subSurface_externalOXP") || station.hasRole("planetFall_moonSurface_externalOXP"))
		{
		if(!this.fx) { this.fx = system.addVisualEffect("planetFall_landingFX",player.ship.position.add(player.ship.vectorForward.multiply(170))); }
        this.fx.setMaterials({"planetFall_planet1.png": {diffuse_map: "planetFall_planet1.png" }});
        }
	}

this.shipDockedWithStation = function(station)
    {
    if(this.$landingChoice == 0)
        { return; }
    if(station.hasRole("planetFall_surface"))
        {
        this.$portImage();
        player.ship.hudHidden = true;
        }
    else
        {
        player.ship.hudHidden = false;
        }    

    // main planet - functional port
    if(player.ship.dockedStation.hasRole("planetFall_mainSurface_city" + this.$mainPortFlag))
        {
        this.$portTitle = "Capital City Port";
        this.$portImageCaptured = this.$mainPortImage;
        this.$terminalImageCaptured = this.$mainTerminalImage;
        this.$cityImageCaptured = this.$mainCityImage;
        this.$fieldImageCaptured = this.$mainFieldImage;
        }

    // main planet - fields
    if(player.ship.dockedStation.hasRole("planetFall_mainSurface_fields"))
        {
        missionVariables.planetFallBreak += 0.001; // additional tear and wear
        this.$portTitle = "Open Fields";
        this.$portImageCaptured = this.$mainFieldImage;
        this.$terminalImageCaptured = this.$mainFieldImage;
        this.$cityImageCaptured = this.$mainFieldImage;
        this.$fieldImageCaptured = this.$mainFieldImage;
        }

    // main planet - derelict ports
    if(player.ship.dockedStation.hasRole("planetFall_mainSurface_cityDerelict"))
        {
        missionVariables.planetFallBreak += 0.001; // additional tear and wear
        this.$portTitle = "Derelict City";
        this.$portImageCaptured = this.$mainPortDerelictImage;
        this.$terminalImageCaptured = this.$mainTerminalDerelictImage;
        this.$cityImageCaptured = this.$mainCityDerelictImage;
        this.$fieldImageCaptured = this.$mainFieldImage;
        }

    // minor planet - functional port
    if(player.ship.dockedStation.hasRole("planetFall_subSurface_colony" + this.$minorPortFlag))
        {
        this.$portTitle = "Colony City Port";
        this.$portImageCaptured = this.$minorPortImage;
        this.$terminalImageCaptured = this.$minorTerminalImage;
        this.$cityImageCaptured = this.$minorCityImage;
        this.$fieldImageCaptured = this.$minorFieldImage;
        }

    if(player.ship.dockedStation.hasRole("planetFall_subSurface_researchStation"))
        {
        this.$portTitle = "Research Station";
        this.$portImageCaptured = this.$minorPortImage;
        this.$terminalImageCaptured = this.$minorTerminalImage;
        this.$cityImageCaptured = this.$minorLabImage;
        this.$fieldImageCaptured = this.$minorFieldImage;
        }

    // minor planet - fields
    if(player.ship.dockedStation.hasRole("planetFall_subSurface_fields"))
        {
        missionVariables.planetFallBreak += 0.001; // additional tear and wear
        this.$portTitle = "Open Fields";
        this.$portImageCaptured = this.$minorFieldImage;
        this.$terminalImageCaptured = this.$minorFieldImage;
        this.$cityImageCaptured = this.$minorFieldImage;
        this.$fieldImageCaptured = this.$minorFieldImage;
        }

    // minor planet - derelict ports
    if(player.ship.dockedStation.hasRole("planetFall_subSurface_colonyDerelict"))
        {
        missionVariables.planetFallBreak += 0.001; // additional tear and wear
        this.$portTitle = "Derelict City";
        this.$portImageCaptured = this.$minorPortDerelictImage;
        this.$terminalImageCaptured = this.$minorTerminalDerelictImage;
        this.$cityImageCaptured = this.$minorCityDerelictImage;
        this.$fieldImageCaptured = this.$minorFieldImage;
        }

    // moon - ports
    if(player.ship.dockedStation.hasRole("planetFall_moonSurface_dome" + this.$moonPortFlag))
        {
        this.$portTitle = "Lunar Colony Port";
        this.$portImageCaptured = this.$moonPortImage;
        this.$terminalImageCaptured = this.$moonTerminalImage;
        this.$cityImageCaptured = this.$moonCityImage;
        this.$fieldImageCaptured = this.$moonFieldImage;
        }
    if(player.ship.dockedStation.hasRole("planetFall_moonSurface_researchStation"))
        {
        this.$portTitle = "Research Station";
        this.$portImageCaptured = this.$moonPortImage;
        this.$terminalImageCaptured = this.$moonTerminalImage;
        this.$cityImageCaptured = this.$moonLabImage;
        this.$fieldImageCaptured = this.$moonFieldImage;
        }

    // moon - fields
    if(player.ship.dockedStation.hasRole("planetFall_moonSurface_fields"))
        {
        missionVariables.planetFallBreak += 0.001; // additional tear and wear
        this.$portTitle = "Lunar Field";
        this.$portImageCaptured = this.$moonFieldImage;
        this.$terminalImageCaptured = this.$moonFieldImage;
        this.$cityImageCaptured = this.$moonFieldImage;
        this.$fieldImageCaptured = this.$moonFieldImage;
        }

    // moon - derelict ports
    if(player.ship.dockedStation.hasRole("planetFall_moonSurface_domeDerelict"))
        {
        missionVariables.planetFallBreak += 0.001; // additional tear and wear
        this.$portTitle = "Derelict Colony Dome";
        this.$portImageCaptured = this.$moonPortDerelictImage;
        this.$terminalImageCaptured = this.$moonTerminalDerelictImage;
        this.$cityImageCaptured = this.$moonColonyDerelictImage;
        this.$fieldImageCaptured = this.$moonFieldImage;
        }

    if(station.hasRole("planetFall_surface"))
        {
        mission.runScreen({
            title: this.$portTitle,
            background: {name: this.$portImageCaptured, height: 480 },
            }
            );
        }

    }

this.shipLeavingPlanetSurface = function(planet)
	{
	this.$lastPlanet = planet;
	this.$messageBlock = false;
	}

this.guiScreenChanged = function(to,from)
	{
	if(!player.ship.docked) // for GUI screen changes whilst in flight, which we can ignore
		{ return; }

	if(!player.ship.dockedStation.hasRole("planetFall_surface")) // if we're at a trunk or other OXP's station
		{ return; }

    if(this.$landingChoice == 0) // if we're at a trunk or surface ports of external OXP's such as Feudal States
        { return; }
        
    if(guiScreen == "GUI_SCREEN_EQUIP_SHIP" || guiScreen == "GUI_SCREEN_MARKET" || guiScreen == "GUI_SCREEN_SHIPYARD" || guiScreen == "GUI_SCREEN_STATUS")
        {
        player.ship.hudHidden = false;
        }
    else
        {
        player.ship.hudHidden = true;
        }

    if (to === "GUI_SCREEN_SYSTEM_DATA" && from === "GUI_SCREEN_STATUS")
        {
        mission.runScreen({
            title: "Planet view",
            background: {name: this.$fieldImageCaptured, height: 480 },});       
        }

    if (to === "GUI_SCREEN_SYSTEM_DATA" && from === "GUI_SCREEN_MARKET")
        {
        mission.runScreen({
            title: "City view",
            background: {name: this.$cityImageCaptured, height: 480 },});       
        }

    if (to === "GUI_SCREEN_SYSTEM_DATA" && from === "GUI_SCREEN_EQUIP_SHIP")
        {
        mission.runScreen({
            title: "Port view",
            background: {name: this.$portImageCaptured, height: 480 },});       
        }

    if (to === "GUI_SCREEN_SYSTEM_DATA" && from === "GUI_SCREEN_INTERFACES")
        {
        mission.runScreen({
            title: "Terminal view",
            background: {name: this.$terminalImageCaptured, height: 480 },});       
        }

	if(!player.ship.dockedStation.hasRole("planetFall_noTrade")) // if we're at a location where trading is possible
		{ return; }

	 // no-one to trade with in empty fields
	if(player.ship.dockedStation.hasRole("planetFall_mainSurface_fields")) 
		{
		if(guiScreen == "GUI_SCREEN_EQUIP_SHIP" || guiScreen == "GUI_SCREEN_MARKET")
			{
            mission.runScreen({
                title: "Open fields",
                messageKey: "planetFall_noTrade",
                background: {name: this.$mainFieldImage, height: 480 },});
			}
		}

    // wartime is a hard time for regular trade, but sometimes your help is needed!
    if (this.$civilWarState == 1)
        {
        if(player.ship.dockedStation.hasRole("planetFall_mainSurface_cityDerelict")) 
            {
            if(guiScreen == "GUI_SCREEN_EQUIP_SHIP")
                {
                mission.runScreen({
                    title: "Derelict Port",
                    messageKey: "planetFall_cityDerelictWar",
                    background: {name: this.$mainPortDerelictImage, height: 480 },});
                }
            }
        }

	// no-one to trade with in empty fields
	if(player.ship.dockedStation.hasRole("planetFall_subSurface_fields")) 
		{
		if(guiScreen == "GUI_SCREEN_EQUIP_SHIP" || guiScreen == "GUI_SCREEN_MARKET" || guiScreen == "GUI_SCREEN_SHIPYARD")
			{
			mission.runScreen({
            title:"Open fields",
            messageKey:"planetFall_noTrade",
            background: {name: this.$minorFieldImage, height: 480 },});
			}
		}

	 // no-one to trade with in derelict object
	if(player.ship.dockedStation.hasRole("planetFall_subSurface_colonyDerelict")) 
		{
		if(guiScreen == "GUI_SCREEN_EQUIP_SHIP" || guiScreen == "GUI_SCREEN_MARKET")
			{
            mission.runScreen({
                title: "Derelict Colony City",
                messageKey: "planetFall_minorColonyDerelict",
                background: {name: this.$minorCityDerelictImage, height: 480 },});
			}
		}

	// no-one to trade with on the empty lunar surface
	if(player.ship.dockedStation.hasRole("planetFall_moonSurface_fields")) 
		{
		if(guiScreen == "GUI_SCREEN_EQUIP_SHIP" || guiScreen == "GUI_SCREEN_MARKET")
			{
			mission.runScreen({
                title:"Open fields",
                messageKey:"planetFall_noTrade",
                background: {name: this.$moonFieldImage, height: 480 },});
			}
		}

	 // no-one to trade with in derelict object
	if(player.ship.dockedStation.hasRole("planetFall_moonSurface_domeDerelict")) 
		{
		if(guiScreen == "GUI_SCREEN_EQUIP_SHIP" || guiScreen == "GUI_SCREEN_MARKET")
			{
            mission.runScreen({
                title: "Derelict Colony Dome",
                messageKey: "planetFall_moonColonyDerelict",
                background: {name: this.$moonColonyDerelictImage, height: 480 },});
			}
		}

	}

this.playerBoughtEquipment = function(equipment)  // regular maintenance
	{
	if(equipment == "EQ_PLANETFALL")
		{ missionVariables.planetFallBreak = 0; }
	if(equipment == "EQ_RENOVATION" && player.ship.equipmentStatus ("EQ_PLANETFALL") == "EQUIPMENT_OK")
		{ missionVariables.planetFallBreak = 0; }
	}

this.$landingClearance = function()
	{
	this.$landingTimer.stop();
	delete this.$landingTimer;
	player.commsMessage(system.name + " Planetary Control - Landing clearance granted.",6);
	player.commsMessage("Please approach the surface slowly.", 6);
	}

this.shipDied = function()
	{
	let ports = system.shipsWithRole("planetFall_surface"); // an array of any rogue "surface stations" in the system
	this.$portCount = ports.length; // how many rogues we have that need to be removed
	if(this.$portCount > 0) for (let i = 0; i < this.$portCount; i++) // if there are any, loop through and remove them
		{ this.$removePort(ports[i]); }
	if(this.$landingTimer && this.$landingTimer.isRunning)
		{
		this.$landingTimer.stop();
		delete this.$landingTimer;	
		}
	}

this.$systemScan = function()
	{
	function isMoon(entity) {return (entity.isPlanet && !entity.hasAtmosphere) };
	this.$systemArray = system.planets;
	this.$systemCount = this.$systemArray.length;
	this.$moonCount = system.filteredEntities(this.$systemArray, isMoon).length;
	this.$planetCount = this.$systemCount - this.$moonCount;
	}

this.$removePort = function(port)
	{	
	if(port.hasRole("planetFall_surface"))
		{ port.remove(); };
	}

this.$checkForSpecialPlanets = function()
	{ this.$scriptDelay = new Timer(this, this.$setFlags, 0.25); }

this.$setFlags = function()
	{	
	if(galaxyNumber === 0 && system.ID === 246) // if we're at Tianve (G0, S227), set up the pulsar
		{
		for (let i = 0; i < system.planets.length; i++) 
			{ 
			if(system.planets[i].texture === "tianve_pulsar.png") 
				{ system.planets[i].PFNoLand = true; } 
			}
		}
	}

this.$turnStation = function(tempStation)
	{
	if(!tempStation) { return; } // just in case the station doesn't survive spawning.
	let stationVector = tempStation.position.subtract(this.$lastPlanet.position).direction(); // unit vector pointing away from the planet
	let angle = tempStation.heading.angleTo(stationVector); // angle between current heading and target heading
	let cross = tempStation.heading.cross(stationVector).direction(); // set the plane where we should rotate in
	tempStation.orientation = tempStation.orientation.rotate(cross, -angle); // re-orient the station away from the planet
	tempStation.position = tempStation.position.add(stationVector.multiply(3000));
	tempStation.breakPattern = false;
	}

// set system TL, EL & GNP flags
this.$systemState = function()
    {

    // define tech level
    if(system.techLevel < 4)
        {
        this.$techFlag = "ArchaicTech";
        }
    else
        {
        if(system.techLevel < 7)
            {
            this.$techFlag = "LowTech";
            }
        else
            {
            if(system.techLevel < 10)
                {
                this.$techFlag = "CommonTech";
                }
            else
                {
                this.$techFlag = "HighTech";
                }
            }
        }

    // define economy
    if(system.economy < 3)
        {
        this.$economyFlag = "Industrial";
        }
    else
        {
        if(system.economy < 5)
            {
            this.$economyFlag = "Mixed";
            }
        else
            {
            this.$economyFlag = "Agro";
            }
        }    

    this.$mainPortFlag = this.$techFlag + this.$economyFlag;

    // define space activity via GNP level
    this.$spaceActivity = system.productivity * (0.75 + 0.5 * system.scrambledPseudoRandomNumber(135));

    // moons
    if(this.$spaceActivity < 20000)
        {
        this.$moonPortFlag = "Minimal";
        }
    else
        {
        if(this.$spaceActivity < 30000)
            {
            this.$moonPortFlag = "Basic";
            }
        else
            {
            this.$moonPortFlag = "Advanced";
            }
        }

    // and minor planets
    if(this.$spaceActivity < 25000)
        {
        this.$minorPortFlag = "Minimal";
        }
    else
        {
        if(this.$spaceActivity < 35000)
            {
            this.$minorPortFlag = "Basic";
            }
        else
            {
            this.$minorPortFlag = "Advanced";
            }
        }

    }

// set war & traffic state
this.$trafficState = function()
    {
    if (system.isInterstellarSpace) return;
    // main planet - civil war
    var planetInfo = system.description;
    var civilWarKeyword1 = "civil";
    this.$civilWarFlag1 = planetInfo.indexOf(civilWarKeyword1);    
    var civilWarKeyword2 = "war";
    this.$civilWarFlag2 = planetInfo.indexOf(civilWarKeyword2);
    if(this.$civilWarFlag1 != -1 && this.$civilWarFlag2 != -1)
        {
        this.$civilWarFlag = 1;
        }
    else
        {
        this.$civilWarFlag = 0;
        }
    this.$civilWarLevel = 0.75 + 0.025 * system.government + 0.025 * system.techLevel - 0.25 * this.$civilWarFlag; // threshold of war conflicts (high value - reduced risk)
    if(Math.random() >  this.$civilWarLevel)
        {
        this.$civilWarState = 1;
        }
    else
        {
        this.$civilWarState = 0;
        }
    this.$serviceLevel = 0.05 * system.techLevel + 0.05 * system.government; // level of ground control competence - reduced in low-tech unstable systems
    if(this.$civilWarState == 1)
        {
        this.$serviceLevel = 0;// service dropped in wartime
        }


    this.$selectPort();
    }

// set port type
this.$selectPort = function()
    {

    // main ports
    this.$mainPort1 = "planetFall_mainSurface_city" + this.$mainPortFlag;
    this.$mainPort3 = "planetFall_mainSurface_city" + this.$mainPortFlag;

    // minor ports - colony complex
    if(this.$minorPortFlag != "Minimal")
        {
        this.$minorPort1 = "planetFall_subSurface_colony" + this.$minorPortFlag;
        }
    else
        {
        this.$minorPort1 = "planetFall_subSurface_researchStation";            
        }
    this.$minorPort3 = "planetFall_subSurface_researchStation";

    // moon ports - colony complex
    if(this.$moonPortFlag != "Minimal")
        {
        this.$moonPort1 = "planetFall_moonSurface_dome" + this.$moonPortFlag;
        }
    else
        {
        this.$moonPort1 = "planetFall_moonSurface_researchStation";            
        }

    // open fields
    this.$mainPort2 = "planetFall_mainSurface_fields";
    this.$minorPort2 = "planetFall_subSurface_fields";
    this.$moonPort2 = "planetFall_moonSurface_fields";

    // civil war - affects all system ports!
    if(this.$civilWarState == 1)
        {
        this.$mainPort1 = "planetFall_mainSurface_cityDerelict";
        this.$minorPort1 = "planetFall_subSurface_colonyDerelict";
        this.$moonPort1 = "planetFall_moonSurface_domeDerelict";
        }

    }

// set planet port view
this.$portImage = function()
    {
    var w = worldScripts.AstroLibrary;
    // main planet temperature
    var sunRadius = system.sun.radius;
    var sunTemperature = w.$astroLib_sunTemperature(sunRadius);
    var sunLuminosity = w.$astroLib_sunLuminosity(sunTemperature,sunRadius);
    var mainPlanetTemperature = w.$astroLib_mainPlanetTemperature(sunLuminosity);

    // Famous Planets landscapes
    // Sector One
    if(system.info.galaxyID == 0)
        {
        var countSectorOne = this.$sectorOnePlanetList.length;
        var flagSectorOne = -1;
        for (let i = 0; i < countSectorOne; i++) 
            { 
            if(this.$sectorOnePlanetList[i] == system.info.systemID)
                {
                flagSectorOne = this.$sectorOnePlanetList[i];
                }
            }
        }
    // Sector Two
    if(system.info.galaxyID == 1)
        {
        var countSectorTwo = this.$sectorTwoPlanetList.length;
        var flagSectorTwo = -1;
        for (let i = 0; i < countSectorTwo; i++) 
            { 
            if(this.$sectorTwoPlanetList[i] == system.info.systemID)
                {
                flagSectorTwo = this.$sectorTwoPlanetList[i];
                } 
            }        
        }

    var mainCityFlag;
    var tagPlanet;
    if(flagSectorOne >= 0 || flagSectorTwo >= 0)
        {
        tagPlanet = system.name;    // selecting Famous Planet landscape          
        this.$mainFieldImage = ('fieldFP_' + tagPlanet + '.png');
        mainCityFlag = -1;
        }
    else
        {
        var info = system.info;
        var s = worldScripts.Planet_Makeup;
        tagPlanet = s.$home_planet_makeup(info);  // selecting generic planet landscape
        this.$mainFieldImage = ('field_home_planet' + tagPlanet + '.png');
        mainCityFlag = tagPlanet;
        }

    var cityImageShift = 0;
    if(system.government == 0 || system.government == 2)
        {
        cityImageShift = 1;
        }
    if(system.government == 3 || system.government == 4)
        {
        cityImageShift = 2;
        }
    if(system.government > 4)
        {
        cityImageShift = 3;
        }

    // main ports - regular case
    this.$mainCityImage = "mainCity" + this.$mainPortFlag + (1 + cityImageShift) + ".png";
    this.$mainPortImage = "mainPort" + this.$techFlag + ".png";
    this.$mainTerminalImage = "mainTerminal" + this.$techFlag + ".png";

    // desert worlds
    if(mainCityFlag != -1 && mainCityFlag > 64 && system.economy > 2)
        {
        this.$mainCityImage = "mainCityGenericDesert.png";
        } 

    // arctic ports
    if(mainCityFlag != -1 && mainCityFlag < 13 || mainPlanetTemperature < 273)
        {
        this.$mainCityImage = "mainCityGenericWinter.png";
        this.$mainPortImage = "mainPortWinter.png";
        this.$mainTerminalImage = "mainTerminalWinter.png";
        }   

    // main derelict port
    this.$mainCityDerelictImage = "mainCityDerelict" + this.$techFlag + ".png";
    this.$mainPortDerelictImage = "mainPortDerelict.png";
    this.$mainTerminalDerelictImage = "mainTerminalDerelict.png";
      
    // top level worlds
    if(system.techLevel > 13)
        {
        this.$mainPortImage = "mainPortUltraHighTech.png";
        this.$mainFieldImage = "field_home_planet128.png";
        }

    // minor planet - inner OR outer?
    var planetOrbit = 0;    
    var sunDistance = player.ship.position.distanceTo(system.sun).toFixed(0);
    if(sunDistance > system.info.sun_distance)
        {
        planetOrbit = 1;
        }
    else
        {
        planetOrbit = 0;
        }

    // minor planet landscapes
    this.$minorFieldImage = "field_planet_Ares.png";
    // Pluto or Mercury
    if(this.$lastPlanet.radius >= 25000 && this.$lastPlanet.radius < 30000 && this.$lastPlanet != system.mainPlanet)
        {
        if(planetOrbit == 1)
            {
            this.$minorFieldImage = "field_planet_Hades.png";
            }
        else
            {
            this.$minorFieldImage = "field_planet_Hermes.png";
            }
        }    
    // Cold Mars OR Hot Mars 
    if(this.$lastPlanet.radius >= 30000 && this.$lastPlanet.radius < 50000 && this.$lastPlanet != system.mainPlanet)
        {
        if(planetOrbit == 1)
            {
            this.$minorFieldImage = "field_planet_Ares.png";
            }
        else
            {
            this.$minorFieldImage = "field_planet_Phaethon.png";
            }
        }
    // Cold Terra or Venus
    if(this.$lastPlanet.radius >= 50000 && this.$lastPlanet.radius < 75000 && this.$lastPlanet != system.mainPlanet)
        {
        if(planetOrbit == 1)
            {
            this.$minorFieldImage = "field_planet_Ares.png";
            }
        else
            {
            this.$minorFieldImage = "field_planet_Aphrodite.png";
            }
        }
    // Superterra
    if(this.$lastPlanet.radius >= 75000 && this.$lastPlanet.radius < 100000 && this.$lastPlanet != system.mainPlanet)
        {
        this.$minorFieldImage = "field_planet_Aphrodite.png";
        }


    // minor ports
    if(this.$minorFieldImage == "field_planet_Hermes.png" || this.$minorFieldImage == "field_planet_Hades.png")
        {
        if(this.$minorPortFlag != "Minimal")
            {
            this.$minorCityImage = "minorCityLunar" + this.$minorPortFlag + ".png";
            this.$minorPortImage = "minorPortLunar" + this.$minorPortFlag + ".png";
            this.$minorTerminalImage = "minorTerminalLunar" + this.$minorPortFlag + ".png";            
            }
        else
            {
            this.$minorCityImage = "minorLabLunar.png";
            this.$minorPortImage = "minorLabLunar.png";
            this.$minorTerminalImage = "minorTerminalLunar.png";
            }
        this.$minorLabImage = "minorLabLunar.png";
        this.$minorCityDerelictImage = "minorCityDerelictLunar.png";
        }
    if(this.$minorFieldImage == "field_planet_Ares.png" || this.$minorFieldImage == "field_planet_Phaethon.png")
        {
        if(this.$minorPortFlag != "Minimal")
            {
            this.$minorCityImage = "minorCityMartian" + this.$minorPortFlag + ".png";
            this.$minorPortImage = "minorPortMartian" + this.$minorPortFlag + ".png";
            this.$minorTerminalImage = "minorTerminalMartian" + this.$minorPortFlag + ".png";            
            }
        else
            {
            this.$minorCityImage = "minorLabMartian.png";
            this.$minorPortImage = "minorLabMartian.png";
            this.$minorTerminalImage = "minorTerminalMartian.png";
            }
        this.$minorLabImage = "minorLabMartian.png";
        this.$minorCityDerelictImage = "minorCityDerelictMartian.png";
        }
    if(this.$minorFieldImage == "field_planet_Aphrodite.png")
        {
        if(this.$minorPortFlag != "Minimal")
            {
            this.$minorCityImage = "minorCityVenusian" + this.$minorPortFlag + ".png";
            this.$minorPortImage = "minorPortVenusian" + this.$minorPortFlag + ".png";
            this.$minorTerminalImage = "minorTerminalVenusian" + this.$minorPortFlag + ".png";           
            }
        else
            {
            this.$minorCityImage = "minorLabVenusian.png";
            this.$minorPortImage = "minorTerminalVenusian.png";
            this.$minorTerminalImage = "minorTerminalVenusian.png";
            }
        this.$minorLabImage = "minorLabVenusian.png";     
        this.$minorCityDerelictImage = "minorCityDerelictVenusian.png";
        }
    this.$minorPortDerelictImage = "minorPortDerelict.png";
    this.$minorTerminalDerelictImage = "minorTerminalDerelict.png";

    // moon landscapes
    this.$moonFieldImage = "field_moon_Luna.png";
    var paintMoonInner = system.scrambledPseudoRandomNumber(143);
    var paintMoonOuter = system.scrambledPseudoRandomNumber(159);
    if(this.$lastPlanet.radius >= 17500 && this.$lastPlanet.radius < 20000)
        {
        this.$moonFieldImage = "field_moon_Selene.png";
        }
    if(this.$lastPlanet.radius >= 12500 && this.$lastPlanet.radius < 15000)
        {
        this.$moonFieldImage = "field_moon_Luna.png";
        }
    if(this.$lastPlanet.radius >= 15000 && this.$lastPlanet.radius < 17500)
        {
        if (paintMoonInner < 0.5)
            {
            this.$moonFieldImage = "field_moon_Io.png";
            }
        else
            {
            this.$moonFieldImage = "field_moon_Europa.png";
            }        
        }
    if(this.$lastPlanet.radius >= 20000 && this.$lastPlanet.radius < 25000)
        {
        if (paintMoonOuter < 0.5)
            {
            this.$moonFieldImage = "field_moon_Ganymede.png";
            }
        else
            {
            this.$moonFieldImage = "field_moon_Callisto.png";
            }        
        }

    // moon ports    
    if(this.$moonPortFlag != "Minimal")
        {          
        this.$moonCityImage = "moonColony" + this.$moonPortFlag + ".png";
        this.$moonPortImage = "moonPort" + this.$moonPortFlag + ".png";        
        this.$moonTerminalImage = "moonTerminal" + this.$moonPortFlag + ".png";
        }
    else
        {
        this.$moonCityImage = "moonLab.png";
        this.$moonPortImage = "moonLab.png";        
        this.$moonTerminalImage = "moonTerminal.png";
        }
    this.$moonLabImage = "moonLab.png";
    this.$moonColonyDerelictImage = "minorCityDerelictLunar.png";
    this.$moonPortDerelictImage = "minorPortDerelict.png";
    this.$moonTerminalDerelictImage = "minorTerminalDerelict.png";

    // gas giants
    if(this.$lastPlanet.radius >= this.$gasGiantRadius)
        {
        this.$mainPortImage = "gasGiantPort.png";
        this.$mainTerminalImage = "gasGiantTerminal.png";
        this.mainLabImage = "gasGiantStation.png";
        this.$mainFieldImage = "gasGiantStation.png";
        this.$minorPortImage = "gasGiantPort.png";
        this.$minorTerminalImage = "gasGiantTerminal.png";        
        this.$minorLabImage = "gasGiantStation.png";
        this.$minorFieldImage = "gasGiantStation.png";
        }

    }

Re: Galactic Almanac OXZ - Full Version 0.92 - Now on the Expansion Pack Manager (Updated 12.08.23)

Posted: Sun Aug 27, 2023 12:22 am
by LittleBear
The entry in the Feudal States OXZ's shipdata sets the planetfall override property to true when in a feudal system, but only (I think) at the main planet. If you land on any other planet or moon even in a feudal system then it's random chance which landing site you get. I think its only at the main planet that you are guaranteed to land at a royal lodge. The Almanac only names the port if it has been generated by another OXZ. If Feudal States hasn't spawned one then the Almanac won't have executed any script in relation to it. The Almanac script won't stop them appearing, since it only adds a name to the display name of a port that has already been spawned. The Stranger's world planetfall script isn't doing anything in relation to the Royal Courts. These are added by Feudal States. Its the planetfall script that is adding Shipyard/Leisure Complex/Shenony customs control etc that you are landing at. The landing site is random each time you land as all the landing sites have a common role. You can't choose the landing site or travel between them as each landing site is in game terms a separate station and a random type of station is spawned each time you land.

Re: Galactic Almanac OXZ - Full Version 0.92 - Now on the Expansion Pack Manager (Updated 12.08.23)

Posted: Sat Nov 18, 2023 5:05 am
by Nite Owl
Would it be possible to change the way Planets and Moons get numbered? Currently they get numbered in order from the Main Planet and its Moon(s) on out through the system. We currently have Planet I, Moon II, Moon III, etc. all of which are located within the Main Planetary System. My suggestion would be to number the Planets and Moons separately. The Main Planet would be Planet I, the next Planet would be Planet II, etc. The Moons would start with the Main Planetary System and then move through the remaining Planetary Systems. The Main Planet's Moon(s) would be Moon I, Moon II, etc. while the next Planetary System would then pick up the numbering where the Main Planetary System left off. Probably a nightmare to code so if this is not a possibility that is fully understandable as the current numbering system, while not as intuitive, can be figured out and reinterpreted by carefully reading distances.

Re: Galactic Almanac OXZ - Full Version 0.92 - Now on the Expansion Pack Manager (Updated 12.08.23)

Posted: Sat Nov 18, 2023 10:41 am
by LittleBear
It would be fairly easy to do in code, the difficulty is more in keeping the Almanac's classifications and numbering consistent with the native game and the other OXPs that name and number planets and moons (particularly planetary compass, in-system distances, Stanger's world, planetary systems, moons, extra planets, orbits and system redux). IRL a moon orbits a planet but in Oolite a moon is anything that does not have an atmosphere. Extra Planets adds planets and moons, but IRL all the moons would be classed as planets as they all orbit the star. Strangers world on the other hand adds planets in orbit round the sun and then (if the moons oxz is also installed) adds moons near those planets. Moons added by strangers world also be moons IRL, but moons added by other OXZs would not. In code if you added your object with addMoon then its a moon (even if its actually a pulsar, black hole or other object in terms of story). If you add with addPlanet then likewise its a planet in code. Also, in native Oolite, the main planet is always numbered as the [name of the system] I, regardless of where it actually is in terms of orbital position. I didn't want the Almanac to use different numberings and classifications to the other OXPS as that would get really confusing in terms of gameplay!

The numbering is done by the this.nameplanetsandmoons function. It numbers all oxp added objects in terms of their distance from the sun with a:-

var oxps = system.filteredEntities(this, oxps, system.sun);
where: function oxps(entity) {return (entity.isPlanet && !entity.isMainPlanet)};

As a moon is a subset of the isPlanet entity, this returns a list of all the objects added that are not the main planet in order of how far they are from the sun. I could change this to distance from the mainplanet but then the numbering conflicts with planetary compass (and as some OXZs depend on this being installed I need to accommodate it) as planetary compass and in-system distances both number by distance from the sun.

Then a loop like this names and numbers the list of oxz objects:

Code: Select all

if (oxps.length !== 0) {
for (i = 0; i < oxps.length; i++) {
var roman = objectnumbers[oxpCount];
if (oxpCount  > 200) var roman = ""+displayCount;
var type = "(Moon)"; // Default for an object with no atmosphere and not flagged as a planet, gas giant, star or main planet. If it's none of the above then it's a moon!
if (oxps[i].hasAtmosphere) var type = "(Planet)";
if (oxps[i].isGasGiant) var type = "(Gas Giant)";
if (oxps[i].solarGasGiant) var type = "(Gas Giant)";
if (oxps[i].displayName === "Black Hole") var type = "(Black Hole)";
// Test for Planet Classes used by Stanger's World Planetary Systems.
if ( missionVariables.random_station_names_planetengine === "Yes") {
// Only Check Actual Planets. Moons are always named as Moons even if they would meet the tests for Planet Catagories.
if (oxps[i].displayName !== "Cosmic String" && type !== "(Moon)" && type !=="(Nomadic Moon)" && type !=="(Stellar Remnant)") {
if(oxps[i].radius <= 28000) var type = "(Dwarf Planet)";
if(oxps[i].radius > 28000 && oxps[i].radius < 30000) var type = "(Dwarf Planet)";
if(oxps[i].radius >= 30000 && oxps[i].radius < 50000) var type = "(Sub Terran)";
if(oxps[i].radius >= 50000 && oxps[i].radius < 75000) var type = "(Terran Planet)";
if(oxps[i].radius >= 75000 && oxps[i].radius < 100000) var type = "(Super Terran)";
if(oxps[i].radius >= 100000 && oxps[i].radius < 125000) var type = "(Ice Giant)";
if(oxps[i].radius >= 125000) var type = "(Gas Giant)";
// Sanity Check to ensure a Black Hole (which is a planet in terms of code) is always classified as a black hole.
if (oxps[i].displayName === "Black Hole") var type = "(Black Hole)";
// Closing Bracket for Check of Planet Catagories
}
// Sanity Check - If a planet has the flag is Gas Giant then it is always catagories as a gas giant even if it would meet the above tests.
if (oxps[i].isGasGiant) var type = "(Gas Giant)";
if (oxps[i].solarGasGiant) var type = "(Gas Giant)";
//Closing Bracket for Stranger's World Check.
}
if (oxps[i].hasAtmosphere) planetCount++;
if (type === "(Moon)") moonCount++;
// Default of Describing by the System Name (IE Lave I, Lave II etc) if unnamed and Random Station Names is Off.
var planetdisplay = system.name;
var moondisplay = system.name;
var nameobject = "Yes";
// Check to see if another OXP has named the Object.
if (oxps[i].beaconCode) 
{
var planetdisplay  = oxps[i].beaconCode;
var moondisplay  = oxps[i].beaconCode;
}
if (oxps[i].beacon) {
var planetdisplay  = oxps[i].beacon;
var moondisplay  = oxps[i].beacon;
}
if (oxps[i].beaconLabel) 
{
var planetdisplay  = oxps[i].beaconLabel;
var moondisplay  = oxps[i].beaconLabel;
}
if (oxps[i].displayName) {
var planetdisplay  = oxps[i].displayName;
var moondisplay  = oxps[i].displayName;
}
// Check the object wasnt already Classified on a previous run of the this.nameplanetsandmoons function.
// Name the Object if Naming is On.
if (missionVariables.random_station_names_planets === "On")  {
var planetGrid  = Math.floor(system.ID+(256 * galaxyNumber));
// The first OXP 5 planets to appear in any system use their own name pools (10,240 names).
if (planetCount === 1) var planetdisplay = planetpool1[planetGrid&2047];
if (planetCount === 2) var planetdisplay = planetpool2[planetGrid&2047];
if (planetCount === 3) var planetdisplay = planetpool3[planetGrid&2047];
if (planetCount === 4) var planetdisplay = planetpool4[planetGrid&2047];
if (planetCount === 5) var planetdisplay = planetpool5[planetGrid&2047];
// There are only a handful of systems with 4 or more OXP planets, so most of the names in pools 1 to 3 will be seen somewhere but pools 4 and 5 are very rarley used.
// If more than 5 planets are present therefore, the OXP will loop using names from pool 5 two Galaxies ahead of the current position.
// A total of 2,053 planets in a single system will be named if present before the names repeat.
if (planetCount > 5) {
var planetjumpGrid = Math.floor(planetCount+512+system.ID+(256 * galaxyNumber));
var planetdisplay = planetpool5[planetjumpGrid&2047];
}
// Same method for Moons. Moons uses their own seperate 5 pools, so the OXP will name a total of 20,480 planets and moons before looping.
if (moonCount === 1) var moondisplay = moonpool1[planetGrid&2047];
if (moonCount === 2) var moondisplay = moonpool2[planetGrid&2047];
if (moonCount === 3) var moondisplay = moonpool3[planetGrid&2047];
if (moonCount === 4) var moondisplay = moonpool4[planetGrid&2047];
if (moonCount === 5) var moondisplay = moonpool5[planetGrid&2047];
if (moonCount > 5) {
// Looks 5 Galaxies ahead for Moons in order to sequence break.
var moonjumpGrid = Math.floor(moonCount+1280+system.ID+(256 * galaxyNumber));
var moondisplay = moonpool5[moonjumpGrid&2047];
}
// Sanity Check for Interstellar Space. If another OXP does add planets or moons to interstella space, but has not give them a name, then they will be classed as
// "Uncharted World" as these planets and moons are undiscovered and not yet in the Almanac.
if (system.isInterstellarSpace) {
var planetdisplay = "Uncharted World";
var moondisplay = "Uncharted World";
}}
// Name the Object using the Object's name if it has one or if unnamed use the name from the Random Station Names Arrays.
if (nameobject !== ("No")) {
oxps[i].displayName = "Cosmic String";
if (type === "(Moon)") oxps[i].displayName = ""+moondisplay+" "+roman+" "+type;
if (oxps[i].hasAtmosphere) oxps[i].displayName = ""+planetdisplay+" "+roman+" "+type;
if (oxps[i].isGasGiant) oxps[i].displayName = ""+planetdisplay+" "+roman+" "+type;
if (oxps[i].solarGasGiant) oxps[i].displayName = ""+planetdisplay+" "+roman+" "+type;
if (oxps[i].displayName !== "Cosmic String") {
oxpCount++;
displayCount++;
var roman = objectnumbers[oxpCount];
if (type === "(Moon)") oxps[i].displayName = ""+moondisplay+" "+roman+" "+type;
if (oxps[i].hasAtmosphere) oxps[i].displayName = ""+planetdisplay+" "+roman+" "+type;
if (oxps[i].isGasGiant) oxps[i].displayName = ""+planetdisplay+" "+roman+" "+type;
if (oxps[i].solarGasGiant) oxps[i].displayName = ""+planetdisplay+" "+roman+" "+type;
// Detect Special OXP Planets and set their names to the Name given to them by their OXP
// Although I've done a test above in case this is used by another OXP in the future, no OXP yet released sets the name to the name of any of the planets or moons they add..
// Only Triave Pulsar and my own Assassins OXP actually refer to any planets they add by name in their mission text or F7 description.
// Neither me or Drew set the names to the names of the planets / Pulsar we'd added.
// The Code below just tidies this up, so these Celestial Objects appear on the Almananc Screen and the ASC with their correct names.
if (oxps[i].texture === "tianve_pulsar.png") oxps[i].displayName = "The Tianve Pulsar " +roman+" (Stellar Remnant)";
if (oxps[i].texture === "murgh-lunar.png") oxps[i].displayName = "Basta " +roman+" (Nomadic Moon)"; // Hand Name Lave's Moon if Lave OXP is installed.
// Add the Names and Classifications for the moons, planets and gas giants added by Assassins OXP. 
if (oxps[i].texture === "hitsplanet1.png") oxps[i].displayName = "Apollodorus " +roman+" (Planet)";
if (oxps[i].texture === "hitsplanet2.png") oxps[i].displayName = "Cerberus " +roman+" (Gas Giant)";
if (oxps[i].texture === "hitsplanet3.png") oxps[i].displayName = "Diomedes " +roman+" (Planet)";
if (oxps[i].texture === "hitsplanet4.png") oxps[i].displayName = "Augeas " +roman+" (Moon)";
if (oxps[i].texture === "hitsplanet5.png") oxps[i].displayName = "Hercules " +roman+" (Planet)";
if (oxps[i].texture === "hitsplanet6.png") oxps[i].displayName = "Stymphal " +roman+" (Planet)";
if (oxps[i].texture === "hitsplanet7.png") oxps[i].displayName = "Hippolyte " +roman+" (Planet)";
if (oxps[i].texture === "hitsplanet8.png") oxps[i].displayName = "Hesperides " +roman+" (Moon)";
if (oxps[i].texture === "hitsplanet9.png") oxps[i].displayName = "Nemean " +roman+" (Moon)";
if (oxps[i].texture === "hitsplanet10.png") oxps[i].displayName = "Columba " +roman+" (Moon)";
if (oxps[i].texture === "hitsplanet11.png") oxps[i].displayName = "Hades "+roman+" (Gas Giant)";
if (oxps[i].texture === "hitsplanet12.png") oxps[i].displayName = "Lernean " +roman+" (Gas Giant)";
}
// Closing Bracked for Name Object Test.
}  
As I use different naming pools for moons and planets, the loop is keeping a separate count of moons and planets, so they could have different numbering systems but then the way of numbering contradicts the base game and other OXZ. The way it actually numbers is therefore a bit of a compromise in that:-

The Main Planet is always I
All other objects and numbered from II onwards based on how far they are from the sun.

In terms of gameplay (particularly for new players) it is always handy to know which planet is the Main Planet on the compass. If you are playing the basic game then its Lave I. If you install the Almanac it becomes Lave I (Capital Planet) so you still know where you are. If you then install planet or moon adding OXZ these new objects in your game become II onwards. Some OXZs can send the player on missions to particular planets and moons using the numbering from Planetary Compass, so I needed to stay consistent its numbering system. Setting up the ASC in this way also means that the Stations in a system appear first and then the moons and planets, which is also quite handy when you are flipping through the ASC in flight looking for a particular station, planet or moon and the oxp objects cycle through on the compass in number order and how far out from the sun they are in terms of distance and in numerical order as the ASC will list the beacons in order from the sun even if they are numbered in a different way..

Re: Galactic Almanac OXZ - Full Version 0.92 - Now on the Expansion Pack Manager (Updated 12.08.23)

Posted: Sun Nov 19, 2023 1:53 am
by Nite Owl
Did not realize the conflicts involved. My thoughts on it did not go into that amount of detail and depth. Thank You for the thorough explanation. As stated previously the current Galactic Almanac Planet and Moon numbering system works in my Ooniverse if an eye is kept towards the distances involved. Please keep up the great work you are doing with this OXZ.

Re: Galactic Almanac OXZ - Full Version 0.92 - Now on the Expansion Pack Manager (Updated 12.08.23)

Posted: Mon Nov 20, 2023 3:13 am
by phkb
Small issue: I think the MFD is including the Witchpoint beacon when compiling the count of "Orbitals".
As an example, here's the content of the MFD in my current system:
Image
and here's a list of beacons:

Code: Select all

[Ship "Navigation Buoy" position: (2496.53, -85281.4, 717091) scanClass: CLASS_BUOY status: STATUS_IN_FLIGHT]
[Ship "Witchpoint Beacon" position: (0, 0, 0) scanClass: CLASS_BUOY status: STATUS_IN_FLIGHT]
[Station "Kiota Habitat" "Kiota Habitat" position: (-23673, -813342, 896769) scanClass: CLASS_STATION status: STATUS_IN_FLIGHT]
[Station "Kiota Relay" "Kiota Relay" position: (-96489.5, -2.28156e+006, 649450) scanClass: CLASS_STATION status: STATUS_IN_FLIGHT]
[Station "Kiota Biosphere" "Kiota Biosphere" position: (-132064, -3.83473e+006, 1.45079e+006) scanClass: CLASS_STATION status: STATUS_IN_FLIGHT]
The first beacon is for the main station, and the last three are fine (all WildShip stations). But the only way to get to "5" is to include the Witchpoint beacon, which isn't linked to a station.

Re: Galactic Almanac OXZ - Full Version 0.92 - Now on the Expansion Pack Manager (Updated 12.08.23)

Posted: Fri Jan 05, 2024 10:01 am
by Cholmondely
Considerations for future releases:

1) F4 Screen settings menu: Background (BGS/Better Screens/Xenon/Classic) The ability to select "off" to allow other options (eg: Xenon Amber/SW Economy AddOn/KW's various HUDs etc. to show).

2) The ability to "opt-out" of being presented with the mission. (Possibly via Library.oxp's "Config for AddOns" as doing so is "anti-immersive")



This is a superb OXP. Very impressive. And the names are a delight!

Thank you for going to all the effort.

Re: Galactic Almanac OXZ - Full Version 0.92 - Now on the Expansion Pack Manager (Updated 12.08.23)

Posted: Fri Mar 01, 2024 2:00 pm
by phkb
There's a kind of significant bug in the "shipSpawned" function, which is preventing the station/entity renaming process to function.

The current code looks like this:

Code: Select all

this.shipSpawned = function (ship) {
    // If an OXZ has set the Almanac Naming to Off with a Script Info Key, then the whole naming code is skipped for this Station or Ship.
    if (ship.scriptInfo.hasOwnProperty("almanac_object_naming") && ship.scriptInfo.almanac_object_naming !== "Off") {
The problem with the "if" statement is, most ships will not have the "almanac_object_naming" property set in the script_info section. However, both criteria in the "if" statement have to be true for it to trigger (because of the "&&" between them). What this means is, the first element (ship.scriptInfo.hasOwnProperty("almanac_object_naming")) is almost always going to be false, so the rest of the criteria are ignored and nothing will end up happening.

What you need to change this to is this:

Code: Select all

    if (!ship.scriptInfo.hasOwnProperty("almanac_object_naming") || ship.scriptInfo.almanac_object_naming !== "Off") {
What the if statement is saying now, is: if the ship doesn't have the alamanc_object_naming property, *OR* it does and it's not "Off", then do the renaming process that follows.

Re: Galactic Almanac OXZ - Full Version 0.92 - Now on the Expansion Pack Manager (Updated 12.08.23)

Posted: Fri Mar 01, 2024 4:00 pm
by LittleBear
Added that fix for the next release. I've been kinda waiting for Commander Arquebus to complete the mission to correct all my typos and spelling errors in the mission screens. :wink: Including the Witchpoint beacon in the number of orbitals was deliberate, so the list of orbitals should be all the stations in the system which have a beacon plus the witchpoint beacon. The code gets a list of all the objects with beacons, but then excludes station buoys where the station also has a beacon (so stations such as Sothis and Griff's Trading outpost don't get counted twice) and also excludes mission stations, and things like tournament buoys. The reason for this is that the Witchpoint buoy is included on the list of orbitals on the F4 screen and I needed to do a count up of the total number of objects shown on the F4 screen to do the page breaks every ten objects. So the same count is used for both the F4 screen and MFD.

I've mainly worked on improving the name pools but also fixed for the next version are: 1) Removed the script entry from the Galactic Almanac MFD in equipment.plist so that it is no longer listed as primable equipment (as the MFD works automatically and does not need priming). 2) Adds a check to stop script timers which are already running before they are restarted.3) Adds a check for OXZ such as Here Be Dragons or ZeroMap, If installed, the names of unvisited planets and the stars they orbit are now hidden on the F7 screen.4) Further improves the naming pools for HoOpy Casinos, Penal Colonies, Pirate Coves, Extra Stations for Extra Planets, Stranger’s World Orbitals and the automatic naming pool. Adds a naming pool for the Isis Interstellar Station.5) Improves the optimisation under this.ship.spawned checking for whether auto-naming is off (solution by PHKB).

I'll add an option to have no background on the almanac screens for the next release.

Re: Galactic Almanac OXZ - Full Version 0.92 - Now on the Expansion Pack Manager (Updated 12.08.23)

Posted: Mon Mar 04, 2024 12:18 am
by phkb
Another bug. Current code:

Code: Select all

    // Other OXZs can set custom Descriptions in ShipData.
    // If any of the three Text Strings has been set by Script Info, this will be used by the Almanac MFD.
    if (player.ship.compassTarget || player.ship.target) {
        if (player.ship.compassTarget) var currenttarget = player.ship.compassTarget;
        if (player.ship.target) var currenttarget = player.ship.target;
        if (!currenttarget.isMainPlanet && !currenttarget.isSun) {
            if (currenttarget.scriptInfo.almanac_mfd_object_type) missionVariables.random_station_names_mfd_objectType = currenttarget.scriptInfo.almanac_mfd_object_type;
            if (currenttarget.scriptInfo.almanac_mfd_object_data_name) missionVariables.random_station_names_mfd_objectDataName = currenttarget.scriptInfo.almanac_mfd_object_data_name;
            if (currenttarget.scriptInfo.almanac_mfd_object_details) missionVariables.random_station_names_mfd_objectDetails = currenttarget.scriptInfo.almanac_mfd_object_details;
            // Closing Bracket to exclude the Sun and Main Planet.
        }
        // Closing Bracket for Valid Target Check.
    }
After checking if the currenttarget is not the main planet or the sun, the IF statement then checks the content of a property inside the currenttargets scriptInfo object. However, many compass targets will not have a scriptInfo object, and so any attempt to access it will generate an error.

I would suggest this fix:

Code: Select all

    // Other OXZs can set custom Descriptions in ShipData.
    // If any of the three Text Strings has been set by Script Info, this will be used by the Almanac MFD.
    if (player.ship.compassTarget || player.ship.target) {
        if (player.ship.compassTarget) var currenttarget = player.ship.compassTarget;
        if (player.ship.target) var currenttarget = player.ship.target;
        if (!currenttarget.isMainPlanet && !currenttarget.isSun && currenttarget.scriptInfo) {
            if (currenttarget.scriptInfo.almanac_mfd_object_type) missionVariables.random_station_names_mfd_objectType = currenttarget.scriptInfo.almanac_mfd_object_type;
            if (currenttarget.scriptInfo.almanac_mfd_object_data_name) missionVariables.random_station_names_mfd_objectDataName = currenttarget.scriptInfo.almanac_mfd_object_data_name;
            if (currenttarget.scriptInfo.almanac_mfd_object_details) missionVariables.random_station_names_mfd_objectDetails = currenttarget.scriptInfo.almanac_mfd_object_details;
            // Closing Bracket to exclude the Sun and Main Planet.
        }
        // Closing Bracket for Valid Target Check.
    }

Re: Galactic Almanac OXZ - Full Version 0.92 - Now on the Expansion Pack Manager (Updated 12.08.23)

Posted: Mon Mar 04, 2024 8:08 pm
by Cholmondely
Just a reminder about changing the category on the F4 docked screen from "Atlas" to "Informational"!