Replacing a ship with another ship when a research topic is completed

Ugh, is there a better way of doing this? I’m trying to have it so when you research a certain research topic, it replaces that ship with another ship. It works as-is, mostly but it has a few annoying bugs like the lights on the “removed” ship don’t go out and you see a little bit of the death explosion just before it actually despawns. I’m using addCustomCode for this, which is working pretty well for it, really. Here’s the block of code that I have for replacing the ship at the moment:

	Volume_AddCube("NewSpawnVolume", SobGroup_GetPosition(CustomGroup),0.1)
	SobGroup_CreateIfNotExist("newgroup")
	SobGroup_SpawnNewShipInSobGroup(playerIndex, "Fed_LargeShipyard", "UpgradedStation", "newgroup","NewSpawnVolume")
	SobGroup_Clear("newgroup")
	SobGroup_Despawn(CustomGroup)
	SobGroup_SetHealth(CustomGroup, 0)
	Volume_Delete("NewSpawnVolume")

If there was a few sob functions that either let me completely remove a ship, rather than despawning and exploding it, or a replaceShip function or something, that’d be handy… Paging @BitVenom?

2 Likes

I would be interested too. I would like the substitution to be not noticeable by the player…

there are several mods that do something like this, but have “ship” replaced by “ship1” but I haven’t had the chance to trace down where they actually make the ship change.

I presume that you are doing that within a game rule that runs every few seconds and makes the specified substitution?

I’m actually using the new addCustomCode thing, which links to a script in the same folder as the ship. It’s useful, as it by default gives me the sobgroup of the ship in question and the player’s index and that. Seems to work pretty well, too, apart from the function’s I’d like.

that does seem really useful… how are you able to specify the event triggers and / or check that the desired research is done?

I can check for the desired research topic by using the Player_HasResearch function, like this: if Player_HasResearch(playerIndex,"whateverResearchTopic")==1 then do stuff
I imagine a lot of the inbuilt HW2 lua functions would work just fine. Shame there isn’t a totally complete Homeworld Remastered lua reference.

1 Like

I bet some sort of documentation is in the works given how responsive they’ve been to modding issues but with a lot of mod-support changes in flight, I bet they don’t want to put anything out yet.

btw, how would you check what subsystems a ship has or what race the player is (it would be ideal if you could also get information about the race, player index and research of the player from whom the ship had been captured).

I would like to substitute things using a table for each base build-Capable unit so that players of different races can capture and use build capable ships of another race and/or reverse engineer research from that race based on the captured ship and its subsystems.

table entries would be like this:
{ “hgn_tai_carrier”, “vgr_tai_carrier”, “kus_tai_carrier”, “tai_carrier” },
etc

the position in the table entry would match an index value for the race of the capturing player.

it would iterate through the table and find a match for the captured ship. let’s say the Vaygr player had captured or been given a Taiidan Carrier. This would be programmatically replaced by a vgr_tai_carrier. if a Kushan player later captured it, that ship would be replaced by a kus_tai_carrier.

this would be a game rule that would fire every 5 seconds.

We essentially replace two (or three) ships with one in STC when we do the Galaxy and Prometheus separation and re-connections. This might be something you could look at? It’s based on docking but it could work for you :smile:

If you do get it working this script could be helpful in a few different situations :smile:

1 Like

I think I’ve got it working as good as can be expected. With a fast enough update time in the add custom code function, the transition’s barely noticeable. It doesn’t help it still takes a tiny amount time for the navlights to go out on the station in question, but it’s barely noticeable. (Should the navlights even be on if a ship is despawned? It doesn’t quite matter when the ship in question is destroyed a few frames later, but still…)

I’ve uploaded the lua script for the upgrade to my dropbox here.

To use it, put it… anywhere, really, but in the same folder as the intended ship is a good place, then add this line to the ship in question:

addCustomCode(NewShipType,"data:locationofscript/fed_t2upgradescript.lua","","","Fed_Tier2UpgradeUpdate","","Fed_SmallShipyard",0.0001)

And in the script, replace FedFrigateResearch with whatever research topic you want to detect (or even replace the Player_HasResearch check with whatever you want to check for) and replace Fed_LargeShipyard with whatever ship you want it to spawn. It’s not the best script, but it does the job, really.

There are so many different LUA sobgroup functions I’d want for HWR, like ones to get what subsystems a given ship has,
ones to toggle a ships navlights, replace ships in a group, stuff like that.

2 Likes

Just made a quick video of my script in action, and actually, any tiny glitches aren’t that noticeable!

3 Likes

That’s cool! Also it awesome that STC isn’t the only Trek mod being worked on :smiley:

2 Likes

Right, quick warning to anyone who’s downloaded/using the script further up: I’ve updated it as it had a rather severe bug I only discovered in a bit of MP testing. As it turns out, any global variables are truly global, and not just local to individual ships using the script. So if you had two players using the same side, with the same ship, the script would fail to fire properly. I’ve fixed it by adding a table for a per-player stage counter, which seems to have fixed it. Will look in more later to see if can make it a per ship counter.

(Plus, I’ve realised something. If the ship in question is building something, you’ll end up losing the money that you invested in the build if it replaces it. I might stop it from replacing the ship if the ship is building.)

4 Likes

I grabbed that script when you put it there and only just got round to looking at it. My question is: how does the new ship spawn in the correct orientation? I see that the volume makes sure it spawns in the right location, but what about the rotation? Does the game automatically get it right, or are those stations always at a fixed orientation?

EDIT: the script isn’t that big, so here it is:

--StageNumber = 0
StageNumber = {0,0,0,0,0,0,0,0}

function Fed_Tier2UpgradeUpdate(CustomGroup, playerIndex, shipID)
	
	if Player_HasResearch(playerIndex,"FedTier2UpgradeResearch")==1 then
		-- this hides the old station first.
		if StageNumber[playerIndex + 1] == 0 then
			print("Research has been aquired by player ".. playerIndex .. " !")
			print("Stage 1: Despawning the old station")
			SobGroup_Despawn(CustomGroup)
			--SobGroup_EnterHyperSpaceOffMap(CustomGroup)
		end
		
		-- this spawns the new station. THIS MUST BE DONE BEFORE DESTRUCTION. OTHERWISE THE SCRIPT NEVER REACHES THIS STAGE.
		if StageNumber[playerIndex + 1] == 1 then
			print("Stage 2: Adding new station")
			-- set the new spawn position
			Volume_AddCube("NewSpawnVolume"..playerIndex, SobGroup_GetPosition(CustomGroup),0.1)
			-- make a temp sobgroup to store the new spawned station in
			SobGroup_CreateIfNotExist("newgroup"..playerIndex)
			-- spawn the new station into the empty temp sobgroup at the spawn position volume.
			SobGroup_SpawnNewShipInSobGroup(playerIndex, "Fed_Battlestation", "UpgradedStation"..playerIndex, "newgroup"..playerIndex,"NewSpawnVolume"..playerIndex)
			-- clear the temp sobgroup
			SobGroup_Clear("newgroup"..playerIndex)
			-- remove the temporary spawn position volume
			Volume_Delete("NewSpawnVolume"..playerIndex)

		end
		-- this finally destroys the old station for good.
		if StageNumber[playerIndex + 1] == 2 then
			print("Stage 3: Destroying old station")
			SobGroup_SetHealth(CustomGroup, 0)
		end 
		
		-- increment the stage counter. If we're less than three, then increment, otherwise, don't.
		if StageNumber[playerIndex + 1] < 3 then
			StageNumber[playerIndex + 1] = StageNumber[playerIndex + 1] + 1
		end
		
	end

end

You can use a SobGroup_ParadeSobGroup() to align the new ship with the old ship.
Also, you may use SobGroup_MakeDead() instead of SobGroup_SetHealth, because it seems that SobGroup_MakeDead won’t trigger death FX.

1 Like

How? Parade the new one to the old one?

Yes, using a special parade formation

paradeSlot("misc", {0, 0, 0}, {0, 0, 1}, {1, 0, 0}, 0);

1 Like

Does that happen instantly?

SobGroup_ParadeSobGroup(<sSobGroupName>, <sSobGroupParadeRoundName>, <iParadeMode>)

Description
Makes all ships in <sSobGroupName> parade around either the first valid ship in <sSobGroupParadeRoundName> or the nearest ship (if <sSobGroupParadeRoundName> is invalid).

Example
SobGroup_ParadeSobGroup("Player0AdditionalShips", "Player0OriginalShips", 1)

Arguments
<sSobGroupName>: the name of the sobgroup that will be doing the parading.
<sParadeRoundName>: the sobgroup to parade around.
<iParadeMode>: 0 = normal, 1 = instant parade with hyperspace effects, 2 = instant parade withot hyperspace effects (make sure that the screen is black or that the camera is looking elsewhere).
Note: for the instant modes, the squadrons will be ripped out of whatever they are doing, even if that activity normally can't be interrupted.
Note: the instant modes cause damage to small ships.

(From Karos Graveyard)

So just use 2 for iParadeMode

2 Likes

Thanks!