Tracking Sub-Objects

Started by
6 comments, last by medevilenemy 16 years, 4 months ago
Sorry to bother everyone yet again, but I seem to have thoroughly borked a bit of code in my new game's weaponry routines. Relevant code posted below.

class Weapon : public Rotatable
{
    public:
    Weapon()
    {
    };
    ~Weapon()
    {
    };

    virtual void Fire(double time)
    {
    }
    virtual bool CheckLOS(Rotatable target, float tolerance)
    {
        SF3dVector wp_pos= Position+F3dVector(dx,dy,dz);
        SF3dVector locator=Normalize3dVector(target.GetPos()-wp_pos);
        float angle=acosf(locator*ViewDir);
        if(angle<=tolerance)
            return true;
        return false;

    }
    virtual void Update()
    {
    }

    protected:
    float damage; // Damage Per Projectile / Damage Per Second (for beams)
    float speed; // Velocity of each round
    int ammo; // How much ammo is available (use -1 if unlimited)
    int ammomax; // How much ammo the weapon can have in total (use -1 if unlimited)
    double timelastfired;  // Pretty self-explanitory, dont ya think?
    float reloadtime; // How long it takes for the weapon to reload between shots
    float dx; // X location relative to parent
    float dy; // Y location relative to parent
    float dz; // Z location relative to parent
    float pitch; // Pitch relative to parent (rotation about parent's X axis
    float yaw; // Yaw relative to parent (rotation about parent's Y axis
    Rotatable* parent; // A reference to the parent ship, to facilitate easier updates.
    SF3dVector *TView;
    SF3dVector *TUp;
    SF3dVector *TRight;
    SF3dVector *TPos;

    //etc
};
class KEW_Small_Gun : public Weapon
{
    public:
    KEW_Small_Gun(float vel, float dmg, SF3dVector view, SF3dVector up, SF3dVector right, SF3dVector pos,                   float dispx, float dispy, float dispz, float rx, float ry)
    {
        speed = vel;
        damage = dmg;
        dx = dispx;
        dy = dispy;
        dz = dispz;
        pitch = rx;
        yaw = ry;

        Position = pos;
        ViewDir = view;
        UpVector = up;
        RightVector = right;

        TPos = *pos;
        TView = *view;
        TUp = *up;
        TRight = *right;
        MoveForward(-dz);
        StrafeRight(dx);
        MoveUpward(dy);
        RotateX(pitch);
        RotateY(yaw);
    }
    void Fire()
    {
        if(timeGetTime()-timelastfired >= reloadtime && (ammo > 0 || ammo == -1))
        {
            allprojectiles.push_back(new KEW_Small(speed, damage, this));
            timelastfired = timeGetTime();
            if(ammo > 0)
            {
                ammo-=1;
            }
        }

    }
    bool CheckLOS()
    {
    }
    void Update() // Updates position
    {
        Position = TPos;
        ViewDir = TView;
        UpVector = TUp;
        RightVector = TRight;
        MoveForward(-dz);
        StrafeRight(dx);
        MoveUpward(dy);
        RotateX(pitch);
        RotateY(yaw);

        glPushMatrix();
        glTranslated(Position.x, Position.y, Position.z);
        glColor4d(1.0, 0.0, 0.0, 1.0);
        glBegin(GL_LINES);
           glVertex3d(GetX(), GetY(), GetZ());
           glVertex3d(GetX(), GetY(), GetZ()+5);
        glEnd();
        glPopMatrix();
    }
};

during parent ship creation, I create appropriate weapons on said ship as follows: Weapons.push_back(new KEW_Small_Gun(0.1, 10, this.GetPos(), this.GetUp(), this.GetRight(), this.GetPos(), -0.1, 0.0, 0.1, 0.0, 0.0)); // Just a test Later on, in my ship handling function, I iterate through all a ship's weapons and call its Update() function to update its position in the game world. The problem here is that I've rewritten the weapon code above trying to get it to work so many times that I have no Idea where to start anymore. The big problem is that I have yet to figure out how to update the weapon's position properly without some sort of convoluted reference to its parent or some of the parent's data (the vector arguments are supposed to be the positioning data from the parent ship). Anyone know an easier/functional way to track a parent object? I would really appreciate the help.
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
Advertisement
Quote:Original post by medevilenemy
The problem here is that I've rewritten the weapon code above trying to get it to work so many times that I have no Idea where to start anymore. The big problem is that I have yet to figure out how to update the weapon's position properly without some sort of convoluted reference to its parent or some of the parent's data (the vector arguments are supposed to be the positioning data from the parent ship).


Why do you think there's anything wrong with a reference to the parent? You're hiding it behind some abstract class (Rotatable), so there isn't unnecessary coupling.
The idea itself should work, but I've never managed to code it appropriately so as to work. This is not to say that this method is unacceptable. At this point I would just like a system that works.

Just for reference, The Heirarchy is:
Tier 1: Rotatable
Tier 2: Ship, Weapon, Projectile

In this case, an object of type Ship has within it a list of objects of type Weapon. The difficulty is with the weapon pointing back to internal data of the parent. Thanks for the prompt response.
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
So what's wrong with your current version? (I just glanced over it, so maybe I'm missing the obvious...)

Here are a few ways you could go about it:

1. Have the weapon store a reference to its parent (the player). This looks like what you're doing, more or less, except that I would recommend using smart pointers and have the weapon reference its parent weakly.

2. I assume the player 'knows' about the weapons, so that it can call the weapon 'fire' functions and whatnot. If so, perhaps the player could just 'tell' the weapons what the player's current transform is.

3. Use a messaging system.

I'm working on something similar (in fact, my weapon class looks a lot like yours :), and I've gone with number 3. There's a 'weapon control' message type, and whenever the player actor moves, it sends out an 'update weapon transforms' message. The weapons then receive this message and combine the player transform with their own local transform to yield their world transform.

If you don't already have a message system in place, this may not be so practical, in which case I'd go with one of the first two options (weapons and player reference each other in some way).

[Edit: Based on what was posted while I was writing this, it sounds like number 2, above, would be a good option - just have the player object tell its 'owned' weapons what the player transform is. That way, the reference is only one-way.]
Currently I do not have any form of messaging system, nor do I have (or know how to use) smart pointers. I've tried having the weapon store a reference to its parent, but I can never quite seem to get it right. The player's ship is technically not of type ship, its a completely different object type (which is far more sophisticated) but It has the same type of relationship with weapons.

The basic thing is I need to modify the code I posted so that I can mount weapons on ships, and somehow keep the weapon aligned properly with its parent ship. (Oh, and if you were wondering, the line being drawn in the update function is a temporary routine just so I can fine-tune placement of weapons on ships) Anyway, thanks very much for the suggestions, though I am still rather lost as to how to fix my code. How do you suggest fixing the code? (I do not have much faith in my ability to de-bork that mess)

BTW: I'll rate++ both of you as soon as I manage to get the GDNet plugin working again (vista + new version of firefox = problematic [grin])
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
Alright, I think I've managed to get it to work. I made another attempt at storing a reference to the parent object within the weapon, and it seems to work. I've also converted the player's ship into a subclass of type Ship. This should allow me to more easily deal with its weaponry. Now on to projectiles! I may post some screenies as soon as I get something entertaining running. Thanks again for the help!
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
Another way that could cover your needs:
I've derived the parent from an interface class (e.g. ISubsystemOwner) to provide a bit of decoupling. The interface provides things like WorldTransform() etc. Child has ref to an ISubsystemOwner which could be anything (I have vehicles and structures that could own subsystems.)
I went through the whole 'pass in transform when asking to fire' route, and settled on the 'have a ref to parent' in the end :)
The way I settled on doing it (it works, finally [grin]) is to store a reference to a parent object of type Rotatable within the child. That way its parent can be any rotatable object (including the player's ship or whatever). I've tested this by placing weapons within the player's ship, and test-fired projectiles. After some tweaking, it works to my satisfaction (there's even a little projectile arming sequence for the type of projectile I'm using). I'll probably get to work on collision detection soon.
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.

This topic is closed to new replies.

Advertisement