Ship Spawning
-
The listing was generated by a customised PEReaDeR, which I’ve attached, since I should do a bit more on it before releasing the patch (I haven’t updated my first patches with Freddy’s better code). Use perdr -b common.dll >common.lst for the listing shown. I’ve also included the demangler:
[[url=http://adoxa.110mb.com/tde/]tde] c:/Projects/undec ??0DirectiveFollowOp@AI@pub@@QAE@XZ
public: __thiscall pub::AI::DirectiveFollowOp::DirectiveFollowOp(void) -
FriendlyFire wrote:
Excuse me while I go hang myself for being so blind. -_-Never do that.
Go blow away a criminal who escapes justice.
You will feel a lot better afterwards!
And then 8 years later they will let you out and you can do another one!
-
class IMPORT DirectiveGotoOp : public BaseOp { public: DirectiveGotoOp(class DirectiveGotoOp const &); DirectiveGotoOp(void); virtual bool validate(void); public: int x00; int iGotoType; // 1 = Vec, 0 = Ship Vector vPos; // pos int iTargetID; // id Vector vSpline1; // ? Vector vSpline2; // ? Vector vSpline3; // ? Vector vSpline4; // ? float fRange; float fThrust; bool x58; // in INIs, don't know what it does bool x59; // Always true? short iFlag; // 0 = goto, 1 = goto_cruise, 256 = goto_no_cruise int x5C; float x60; // 200 float x64; // 500 int x68; int x6C; };
-
Remove x00.
iGotoType also has 2 = spline, 3 = undefined (I guess, that’s what the constructor does).
short iFlag; is actually bool goto_cruise; bool goto_no_cruise; (“goto” is ignored).
x59 has no apparent reference in content (certainly not where it reads the Goto lines), maybe it gets used in common. -
I gathered as much for the types (I just hadn’t tested it). For the iFlag, I kinda guessed they’d be bools. It seems that goto_cruise overrides goto_no_cruise, too, if both are set to true inadvertently.
As for x00, I had to add that because of a hack I did to BaseOp. I can tell you it works perfectly right now so the definitions are proper
-
Hello everyone,
I’m very interested in this topic, and I follow it since its beginning. Thanks to your great work, I slowly understand how to make NPC’s spawning.
As Wodk4 said, It would be nice to give Waypoints to NPC. Unfortunately, I didn’t reach this objective.
Here the first thing I tried to do :
pub::AI::DirectiveGotoOp testOP; testOP.iGotoType = 1; testOP.vPos.x = -14507; testOP.vPos.y = 124; testOP.vPos.z = 11492; testOP.iFlag = 256; pub::AI::SubmitState(iSpaceObjID, (pub::AI::BaseOp*)&testOP);
but this does’nt work. (This would be too simple, you can laugh at me)
so I tried to use the Personality.cpp given by Adoxa, but unfortunately, I don’t know how to use it. I tried to place it into server.h, in the AI namespace, but I have some errors.
Can you help me to find what’s wrong ?
(No code required, but at least a little clue)Thanks a lot,
Kid -
pub::AI::DirectiveGotoOp testOP; ```Is wrong. It's waiting for a pointer (notice the *). Use
pub::AI::DirectiveGotoOp* go = new pub::AI::DirectiveGotoOp();
And remember to replace all the "." by "->". You also need to define fRange and fThrust.
-
Well, I tried to do as you said, but the spawning ship really doesn’t want to move. I think I haven’t the skill yet to understand it well, and don’t want to annoy you more than that. I don’t know what fThrust & fRange stand for, even playing with values.
(The weird thing, is that in the code quoted by Wodk4, it’s not a pointer which is used in the submit state line).Here’s my current code, according that iSpaceObjID represent a ship we’ve just created. The waypoint is approximatively 500 m away from the spawn point.
pub::AI::DirectiveGotoOp* testOP = new pub::AI::DirectiveGotoOp(); testOP->iGotoType = 1; testOP->vPos.x = -14507; testOP->vPos.y = 124; testOP->vPos.z = 11492; testOP->iFlag = 1; testOP->fRange = 1; testOP->fThrust = 1; pub::AI::SubmitState(iSpaceObjID, (pub::AI::BaseOp*)&testOP);
Really, if you don’t have the time / motivation to help me, no problem, I 'll try to go on by myself.
A huge Thanks anyway
-
fThrust is the speed at which the ship goes. -1 is the default value in the game and means full speed.
fRange is how far from the destination the ship has to go.
Did you define a pilot and a state graph?
-
You changed testOP to a pointer, but didn’t change it in the call.
pub::AI::SubmitState(iSpaceObjID, testOP); ```Although depending on just how DirectiveGotoOp has been defined, you might still need to cast it (it should have been derived, so there should be no need).
-
The older headers don’t have the inheritance. You’d need to add it to the definition of all Op classes.
-
I have set all the personality settings, but I either only get a standing ship (setting state_graph to -1) or an instant server crash.
int iStateGraph = pub::StateGraph::get_state_graph("FIGHTER", pub::StateGraph::TYPE_STANDARD); IStateGraph const *sg = pub::StateGraph::get_state_graph_internal(iStateGraph); pub::AI::SetPersonalityParams pp; pp.state_graph=(int) sg; pp.personality=p; pp.state_id=true; pub::AI::SubmitState(iSpaceObjID, (pub::AI::BaseOp*)&pp);
It doesn’t matter whether I set state_id to true or false or use iStateGraph for the state_graph variable.
Any hints?
-
Ok, I solved it by setting the stategraph afterwards using the BehaviorManager. But as long as you don’t know much about Freelancers internal objects you wont get that far ^^ Maybe there is an easier way?
-
I have no clue. For me, only setting it afterwards works.
Has anyone an idea how to set the enemies of the spawned ship differently from the rep group? E.g. if you want to make an escort they should attack everything which is not friendly to the escorted player.
-
There seem to be some errors regarding the ownerlist stuff:
First of all it has to be
template <class t=""> class IMPORT OwnerList { public: OwnerList(); virtual ~OwnerList(); class OwnerList & operator=(class OwnerList const &); void free(); };</class>
and then the structs are:
struct CargoDesc // Just quickly reversed, no clue about the types { int vft; int iUnk1; int iUnk2; int iUnk3; int iUnk4; }; struct ShipInfo { uint iFlag; // 4 uint iSystem; uint iShipArchetype; Vector vPos; Vector vUnk1; // all 0 Vector vUnk2; // all 0 Matrix mOrientation; uint iUnk1; // 0 uint iLoadout; OwnerList <pub::spaceobj::cargodesc>cargoDesc; uint unk1; // 0 uint unk2; // 0 float fUnk1; uint unk3; // 0 uint iLook1; uint iLook2; uint unk4; // 0 uint unk5; // 0 uint iComm; float fUnk2; float fUnk3; float fUnk4; float fUnk5; float fUnk6; float fUnk7; float fUnk8; uint iUnk2; uint iRep; // increases for each NPC spawned, starts at 0 or 1 uint iPilotVoice; uint unk6; // 0 int iHealth; // -1 = max health uint unk7; // 0 uint unk8; // 0 uint iLevel; };</pub::spaceobj::cargodesc>
After that there is no need to set si.cargoDesc. It will be automaticly initialised like in content.dll.
I still have no clue how to iterate through the list or whether it has anything to do with NPCs dropping all their stuff.
-
There is still an error in the reversed personality struct:
struct IMPORT DamageReactionStruct { DamageReactionStruct(); DamageReactionStruct& operator=(const DamageReactionStruct&); float evade_break_damage_trigger_percent; // 1 float evade_dodge_more_damage_trigger_percent; // 0.2 float drop_mines_damage_trigger_percent; // 1 float drop_mines_damage_trigger_time; // 1 float engine_kill_face_damage_trigger_percent; // 1 float engine_kill_face_damage_trigger_time; // 2 float roll_damage_trigger_percent; // 1 float roll_damage_trigger_time; // 1 float afterburner_damage_trigger_percent; // 1 float afterburner_damage_trigger_time; // 1.5 float brake_reverse_damage_trigger_percent; // 1 float fire_missiles_damage_trigger_percent; // 1 float fire_missiles_damage_trigger_time; // 0.5 float fire_guns_damage_trigger_percent; // 1 float fire_guns_damage_trigger_time; // 1 int iUnk1; int iUnk2; };
As you can see there are 2 more values at the end. I have checked the constructor and there are indeed 8 bytes more reserved as the original struct had. (Trust me this was not easy to find ^^)
I also noticed that my personality struct always hast the default values after submitting the personality params. I have to set it afterwars aswell as the stategraph. This way everything works perfectly. As soon as an NPC dies I destroy its equipment so that nothing stays it space but its cargo.
-
Yeah it worked. We’ve been spawning NPCs etc since some years now. I even tested some scripting sequences, but didn’t have the time to really develop that further. But it is planned.