Willkommen ~Gast!
Registrieren || Einloggen || Hilfe/FAQ || Staff
Probleme mit der Registrierung im Forum? Melde dich unter registerEin Bild.
Autor Beitrag
000
26.09.2006, 21:17
Fetti91



Gleich vorweg, ich programmier noch nicht wirklich lange C++, hab aber Erfahrungen mit anderen Sprachen, ein völliger Programmiernoob bin ich also (hoffentlich) nicht.
Ich wollte mal ein bischen mit dem SDK rumspielen, und gucken, was ich so zusammenbekomm, ein Item zum unsichtbar-werden etc. hab ich schon hinbekommen, jetzt hab ich allerdings ein Problem:

Ich will versuchen (wie bei HL2) einen Parentwert hinzubekommen, also habe ich zunächst einen String als zusätzliche Variable beim Cycler angelegt, die den Namen des Parententities speichern soll. Als ich diesen dann in der KeyValue Funktion mit dem Wert aus dem Editor fütterte, nahm er diesen Wert aus den Entitiy-Einstellungen auch an. Ich konnte das mit einem ALERT(); in der selben Funktion ja sehen. Rief ich dann wieder in der Spawn(); den selben alert auf, so bekam ich in der Konsole zu sehen, dass der String den Inhalt } habe.

Ausgabe der alerts ist also:

Zitat:
m_parent ist train1 in KeyValue();
m_parent ist } in Spawn();
Hier dann noch einmal der Quelltext:
Die Zeilen mit > habe ich hinzugefügt
Quellcode:class CCycler : public CBaseMonster
{
public:
    void GenericCyclerSpawn(char *szModel, Vector vecMin, Vector vecMax);
    virtual int    ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() | FCAP_IMPULSE_USE); }
    int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType );
    void Spawn( void );
    void Think( void );
    void KeyValue( KeyValueData *pkvd );
    //void Pain( float flDamage );
    void Use ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );

    // Don't treat as a live target
    virtual BOOL IsAlive( void ) { return FALSE; }

    virtual int        Save( CSave &save );
    virtual int        Restore( CRestore &restore );
    static    TYPEDESCRIPTION m_SaveData[];
    int            m_animate;

>private:
>    string_t    m_parent;
};

TYPEDESCRIPTION    CCycler::m_SaveData[] =
{
    DEFINE_FIELD( CCycler, m_animate, FIELD_INTEGER ),
};

IMPLEMENT_SAVERESTORE( CCycler, CBaseMonster );


//
// we should get rid of all the other cyclers and replace them with this.
//
class CGenericCycler : public CCycler
{
public:
    void Spawn( void ) { GenericCyclerSpawn( (char *)STRING(pev->model), Vector(-16, -16, 0), Vector(16, 16, 72) ); }
};
LINK_ENTITY_TO_CLASS( cycler, CGenericCycler );



// Probe droid imported for tech demo compatibility
//
// PROBE DROID
//
class CCyclerProbe : public CCycler
{
public:    
    void Spawn( void );
};
LINK_ENTITY_TO_CLASS( cycler_prdroid, CCyclerProbe );
void CCyclerProbe :: Spawn( void )
{
    pev->origin = pev->origin + Vector ( 0, 0, 16 );
    GenericCyclerSpawn( "models/prdroid.mdl", Vector(-16,-16,-16), Vector(16,16,16));
}



// Cycler member functions

void CCycler :: GenericCyclerSpawn(char *szModel, Vector vecMin, Vector vecMax)
{
    if (!szModel || !*szModel)
    {
        ALERT(at_error, "cycler at %.0f %.0f %0.f missing modelname", pev->origin.x, pev->origin.y, pev->origin.z );
        REMOVE_ENTITY(ENT(pev));
        return;
    }

    pev->classname = MAKE_STRING("cycler");
    PRECACHE_MODEL( szModel );
    SET_MODEL(ENT(pev),    szModel);

    CCycler::Spawn( );

    UTIL_SetSize(pev, vecMin, vecMax);
}


>void CCycler :: KeyValue(KeyValueData *pkvd)
>{
>    if(FStrEq(pkvd->szKeyName, "parententity"))
>    {
>        m_parent=(string_t)pkvd->szValue;
>        pkvd->fHandled    = TRUE;
>    }
>    else
>    {
>        CBaseMonster::KeyValue(pkvd);
>    }
>    ALERT(at_console, "m_parent ist %s in KeyValue();\n",m_parent);    //Hier bekomme ich "m_parent ist train1 in KeyValue();
>}

void CCycler :: Spawn( )
{
    InitBoneControllers();
    pev->solid            = SOLID_SLIDEBOX;
    pev->movetype        = MOVETYPE_NONE;
    pev->takedamage        = DAMAGE_NO;
    pev->effects        = 0;
    pev->health            = 80000;// no cycler should die
    pev->yaw_speed        = 5;
    pev->ideal_yaw        = pev->angles.y;
    ChangeYaw( 360 );

>    ALERT(at_console,"m_parent ist %s in Spawn();\n",m_parent); //Hier bekomme ich "m_parent ist } in Spawn();

    m_flFrameRate        = 75;
    m_flGroundSpeed        = 0;

    
    pev->nextthink        += 1.0;

    ResetSequenceInfo( );

    if (pev->sequence != 0 || pev->frame != 0)
    {
        m_animate = 0;
        pev->framerate = 0;
    }
    else
    {
        m_animate = 1;
    }
}
So, ich hoffe, dass die Sachen hier ausreichend sind, dass ihr mir helfen könnt. Wäre nett ^^

Edit
Ich vergass zu erwähnen, dass wenn ich den String direkt zuweise, also
m_parent="train1";
der Wert auch noch in der Spawnfunktion besteht.

--


Dieser Beitrag wurde am 26.09.2006 um 21:35 von Fetti91 bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
001
26.09.2006, 21:46
theDon



Ich rate mal, dass pkvd nicht mehr existiert, wenn CCycler::Spawn() aufgerufen wird.

Versuch doch mal, den szValue zu kopieren...

--

\o tanz den naziprau! o/

And more than ever, I hope to never fall,
Where enough is not the same it was before

zum Seitenanfang zum Seitenende Profil || Suche
002
26.09.2006, 22:13
Fetti91



Jo, das geht, danke.
Allerdings nur unter der Bedingung, das m_parent ein char[32] ist, da strcpy(); was ich im Moment benutze, mit dem String nicht will. Bin halt bei C++ noch Anfänger, irgendwie ist das bestimmt möglich. ^^

Wenn noch einer Lust hat, kann ers noch schreiben, sonst gehts auch so. (Solange der Parent-Eintrag nicht länger als 32 Zeichen wird)

--

zum Seitenanfang zum Seitenende Profil || Suche
003
27.09.2006, 00:56
HammerBlade



HL hat eine etwa ungwöhnliche String Verwaltung (string_t). Ein string_t ist eigentlich ein Offset auf einen globalen char*-Pointer, der von der Engine verwaltet wird. Um damit zu arbeiten gibt es die Defines STRING, MAKE_STRING und ALLOC_STRING.

MAKE_STRING hast du schon verwendet:
Quellcode:pev->classname = MAKE_STRING("cycler"); Damit bekommt man aus einem String direkt im Code (hier "cycler") einen string_t.

Um dein Problem zu lösen brauchst du ALLOC_STRING:
Quellcode:m_parent = ALLOC_STRING(pkvd->szValue); Damit bekommt man aus einem char*-Pointer ein string_t, welches dann auch in Spawn() noch vaild ist.

Mit STRING bekommt man aus einem string_t ein char*-Pointer.

Du kannst also auf strcpy() verzichten, wenn du die Defines für string_t richtig benutzt.

--

"Mit C++ (noch besser mit C) kann man sich _sehr_ leicht in den Fuss schiessen." - theDon
Auspack und freu! - Auszug aus einer, aus dem japanischen übersetzten, Bedienugsanleitung für ein Spielzeugaquarium.
--
Photon Audio Player | Majestic42.net | How To Ask Questions The Smart Way

zum Seitenanfang zum Seitenende Profil || Suche
004
27.09.2006, 14:18
Fetti91



Erstmal Danke für die Erklärung, jez weiß ich auch wo der Unterschied zwischen alloc_string und make_string ist :D

ALLOC_STRING hatte ich allergings anfangs ausprobiert, mit dem Problem, dass m_parent direkt nach dem Befehl auch keinen Inhalt hatte, es entsteht einfach ein leerer String.

Benutze ich statt strcpy() ALLOC_STRING(pkvd->szValue) statt der strcpy zeile, bekomme als Ausgabe also:

Zitat:
m_parent ist in KeyValue();

--

zum Seitenanfang zum Seitenende Profil || Suche
005
30.09.2006, 00:36
Protector



Quellcode:TYPEDESCRIPTION    CCycler::m_SaveData[] =
{
    DEFINE_FIELD( CCycler, m_animate, FIELD_INTEGER ),
    DEFINE_FIELD( CCycler, m_parent, FIELD_STRING ),
};

--

zum Seitenanfang zum Seitenende Profil || Suche