Changing ship position
-
Assuming you’re using the following class definitions (taken from FLHook)
class Vector { public: float x,y,z; }; class Matrix { public: float data[3][3]; }; ```you can change positions by multiplying the distance by the corresponding column in the Matrix. Column 0 = x, 1 = y, and 2 = z. For example, this will move the position 500 m forwards (from the perspective of the player).
Matrix orientation;
Vector position;
//Other code here…
position.x -= orientation.data[0][2] * 500;
position.y -= orientation.data[1][2] * 500;
position.z -= orientation.data[2][2] * 500; -
First you need to calculate the vector that points from your position to your target’s position. This is done by a simple subtraction of the player’s vector components from the target’s vector components. Now that you have the pointing vector you can pass it to the LookMatrixYup utility function in common.dll. This will return the Matrix that faces in the direction of the given Vector, which is what you want.
For example:Vector vTarget, vPlayer; //Other code here... Vector vPointing; vPointing.x = vTarget.x - vPlayer.x; vPointing.y = vTarget.y - vPlayer.y; vPointing.z = vTarget.z - vPlayer.z; Matrix mPointing = LookMatrixYup(vPointing);
-
Excellent! I figured there’d be a function for it. And it looks like I’ve got IsPosEmpty figured out, too, so I should be able to prevent jumping into occupied space (atmosphere in particular, for bases like Trenton when you’re on the other side of the planet).
That just leaves changing system. My experiments with SystemSwitchOutComplete and JumpIn[Complete] didn’t work. Can you make it three out of three and tell me how I can jump to a different system? (To be clear, I mean jumping in space; I’ve already used ForceLand to go to any base.) At the least, I should be able to do it with save game trickery, but I’d rather a more direct method.
-
Apologies for not replying sooner; I was working on getting it to work, but I didn’t finish figuring everything out and got sidetracked with fixing bugs in Flak’s FLHook. So instead of posting a completely working solution I’m going to outline what I’ve done so far and what’s working/not working.
What is working:
1. Changing systems on the client. There’s a magical address at 0x67977C (in freelancer.exe) that’s normally 0. If you change it to the hash of a system then FL will change to it no questions asked. IServerImpl::SystemSwitchOutComplete will also be called.
2. Switching out of the system on the server. I essentially rewrote SystemSwitchOutComplete to not rely on jumping into a jump hole/gate in the new system.
SystemSwitchOutComplete handles the whole switching systems part of the change as far as I can tell. If you prevent JumpInComplete from doing anything the only negative side effect is the player that switched systems cannot be damaged.What isn’t working:
Switching into the system on the server. For some reason the server thinks the player hasn’t completely jumped into the system - it won’t spawn NPCs around the player or allow the player to dock. Other players can see the player, but the player has 0 health and cannot be damaged. The server also crashes upon shutdown. I believe the problem is either I’m not doing all the needed function calls or one of the functions is bailing out and not doing what it’s supposed to.Here’s the code (FLHook only, but SwitchSys.dll is only changing 0x67977C in response to the ChangeSys chat message) + binaries if you want to take a look. All of the code for actually changing the system is in the HkSwitchSystem function in HkFuncPlayers.cpp. I’m guessing that you’ll have to do something similar to what I’m doing server-side client-side on the local server.
EDIT: forgot to mention how to actually test out the code. Enter “.test <system nickname=”“>” in the chat to jump to the system; you must be a FLHook admin for this to work. For example, “.test li01” will jump you to New York.</system>
-
M0tah wrote:
What is working:
1. Changing systems on the client. There’s a magical address at <…> that’s normally 0. If you change it to the hash of a system then FL will change to it no questions asked.Do i get it right that this alone is working, so far - without bugs?
if so - excellent! ^^ -
Yes, changing systems on the client seems to be working perfectly using that offset. It’s getting the server to also change systems that’s the problem.
I don’t think the offset needs to be in the private section - it’s pretty useless if the server doesn’t change systems along with the client.
-
M0tah wrote:
Yes, changing systems on the client seems to be working perfectly using that offset. It’s getting the server to also change systems that’s the problem.I don’t think the offset needs to be in the private section - it’s pretty useless if the server doesn’t change systems along with the client.
Ah, i meant that first part is sufficient to init system change sequence both on server and in client. So as i understand it’s not, and then in private section, right.
Well… keeps fingers crossed -
I don’t believe just the offset is sufficient, since it doesn’t update the system in the playerdata. When I tried it the first time, I was able to jump right through objects, but that didn’t happen with a later test. Changing the playerdata directly didn’t quite work (seemed to be the same as what happened with multiplayer), although perhaps changing it after the system might work. Anyway, I have the luxury of working with single-player, so I ended up patching SystemSwitchOutComplete to work without the “goto” objects. So now I can type s Cal 30k,0,20k,90,45,-90 and jump to California, setting position and rotation. Brilliant! By this time tomorrow I should be able to say s Cal Dock and jump right in front of the Planet Los Angeles Docking Ring…
-
What you’re describing is eerily similar to what happens when you have a base setup in two different systems. No NPC spawn, no player interaction, no collision… You were shown the new system, but you “were” still in the old one. I believe you could even die if you entered in a death zone in the old system
-
lea ecx, vVelocity push ecx push ship mov eax, 0x6D0D100
It’s not velocity, but a far bigger structure:
struct ShipProperties // or something { float mass; float linear_damping; Vector angular_damping; // angular_drag / rotation_inertia uint system; uint iDunno; // 2 uchar bDunno1; bool enable_collisions_r; char sDunno2[8]; // something to do with collision groups bool bDunno3; Vector rotation_intertia; }; ```The structure is initialised by a call to 6d0d000 (system is set to 0); the 100 call at least sets system and bDunno3.