Willkommen ~Gast!
Registrieren || Einloggen || Hilfe/FAQ || Staff
Probleme mit der Registrierung im Forum? Melde dich unter registerEin Bild.
Autor Beitrag
000
02.04.2005, 15:53
GcDesign



Hi wieder mal

Ich hab jetzt im Laufe meiner "ersten Schritte" ein Entity erstellt, das ein eigenes Model besitzt (Combine Console) und beim Benutzen ("Use") erst mal einfach dem Spieler eine Waffe (in diesem Fall z.B. die AR2) geben soll.

Soweit so gut.
Ich hab mir also das model Tutorial Entity zum Vorbild genommen und es genauso angelegt und dann eben unnötige Sachen wir "movethink" rausgenommen - nach einigen Veränderung is das Folgende dabei rausgekommen:

Quellcode://===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ========
//
// Purpose: Terminal Screen from where the player can buys equipment.
//
//
//=============================================================================

#include "cbase.h"

class CPropTerminal: public CBaseAnimating
{
public:
    DECLARE_CLASS( CPropTerminal, CBaseAnimating );
    DECLARE_DATADESC();

    void Spawn( void );
    void Precache( void );

    void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );

    // Input functions
    void InputToggle( inputdata_t &inputData );

private:

    bool    m_bActive;
    float    m_flNextChangeTime;
};

LINK_ENTITY_TO_CLASS( prop_terminal, CPropTerminal );

// Start of our data description for the class
BEGIN_DATADESC( CPropTerminal )
    
    // Save/restore our active state
    DEFINE_FIELD( m_bActive, FIELD_BOOLEAN ),
    DEFINE_FIELD( m_flNextChangeTime, FIELD_TIME ),

    // Links our input name from Hammer to our input member function
    DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ),

END_DATADESC()

// Name of our entity's model
#define    ENTITY_MODEL    "models/props_combine/combine_interface002.mdl"

//-----------------------------------------------------------------------------
// Purpose: Precache assets used by the entity
//-----------------------------------------------------------------------------
void CPropTerminal::Precache( void )
{
    PrecacheModel( ENTITY_MODEL );
}

//-----------------------------------------------------------------------------
// Purpose: Sets up the entity's initial state
//-----------------------------------------------------------------------------
void CPropTerminal::Spawn( void )
{
    Precache();

    SetModel( ENTITY_MODEL );
    SetSolid( SOLID_VPHYSICS );
    //UTIL_SetSize( this, -Vector(20,20,20), Vector(20,20,20) );

    m_bActive = false;
}

//-----------------------------------------------------------------------------
// Purpose: Toggle the movement of the entity
//-----------------------------------------------------------------------------
void CPropTerminal::InputToggle( inputdata_t &inputData )
{
    // Toggle our active state
    if ( !m_bActive )
    {
        m_bActive = true;
    }
    else
    {
        m_bActive = false;
    }
}

//-----------------------------------------------------------------------------
// Purpose:
// Input  : *pActivator -
//            *pCaller -
//            useType -
//            value -
//-----------------------------------------------------------------------------
void CPropTerminal::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
    CBasePlayer *pPlayer = ToBasePlayer( pActivator );
    if ( pPlayer )
    {
        /*
        if ( HasSpawnFlags( SF_PHYSPROP_ENABLE_PICKUP_OUTPUT ) )
        {
            m_OnPlayerUse.FireOutput( this, this );
        }

        pPlayer->PickupObject( this );
        */
        pPlayer->GiveNamedItem( "weapon_ar2" );
    }
}
Das Problem besteht nun darin, dass wenn ich das Ding im Spiel versuche es keinen Effekt gibt - z.Z. erfüllt es sozusagen den selben Zweck wie ein prop_static. Es gibt auch keine Fehler oder Warnungen beim Kompilieren.

Was kann ich hier falsch gemacht haben?

--

zum Seitenanfang zum Seitenende Profil || Suche
001
04.04.2005, 19:13
Quak



Schreib mal in deine Use() Function sowas wie DevMsg("Custom Use() called\n") damit du sicher sein kannst, dass dein Code ausgeführt wird. Wenn du die Message siehst muss der Fehler in der Use() Function sein. Ansonsten sieht der Code sauber aus, allerdings versteh ich nicht was die InputToggle() Function bezwecken soll.

--

Coder @ Heat

zum Seitenanfang zum Seitenende Profil || Suche
002
04.04.2005, 19:27
GcDesign



*juhu-endlich-ne-antwort*

Ich werd das gleich mal testen !
Is eigentlich sonst noch was zu beachten damit Use() ausgeführt wird?

Aja und InputToggle() ist mehr ein Relikt aus dem my_first_model_entity Beispiel - ich habs aber trotzdem drinnen gelassen

--

zum Seitenanfang zum Seitenende Profil || Suche
003
04.04.2005, 20:36
GcDesign



Hmmm - ging scheinbar nicht - ich bekomm auch keine DevMsg wenn ich es teste

Wo kann der Fehler hier noch liegen?

--

zum Seitenanfang zum Seitenende Profil || Suche
004
04.04.2005, 21:40
Quak



Eventuell stimmt was mit der BBox nicht...kommentier mal das UTIL_SetSize aus.

Und ersetzte das SetSolid( SOLID_VPHYSICS ) mal mit SetSolid( SOLID_BBOX ).

--

Coder @ Heat


Dieser Beitrag wurde am 04.04.2005 um 21:43 von Quak bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
005
05.04.2005, 15:49
GcDesign



Hmm...
Funktioniert nicht - ich bekomm keine Devleoper Messages :(

Also damit ich soche bekomm muss ich doch DevMsg("..."); einfügen und im spiel dann developer 1 eingeben oder ?

EDIT: Moment - ich hab was übersehen - ich werd noch versuchen UTIL_SetSize auszukommentieren.

--


Dieser Beitrag wurde am 05.04.2005 um 15:56 von GcDesign bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
006
05.04.2005, 20:20
Quak



starte die mod über die .bat datei, nicht über steam dann müsstest du sie auf jedenfall sehen

--

Coder @ Heat

zum Seitenanfang zum Seitenende Profil || Suche
007
06.04.2005, 14:08
GcDesign



Ok - also ich hab eine komische Erfahrung gemacht:

Es funktioniert zwar noch immer nicht, aber wenn ich über die console "ent_fire ent_terminal" eingebe scheint es den gleichen Zweck wie "Use" zu erfüllen!
D.h. ich bekom msogar die Waffe und auch die Dev Message wird angezeigt.

-> Mit der Funktion "Use" selbst scheint alles in Ordnung - nur "der Auslöser" dazu funktioniert noch nicht

--

zum Seitenanfang zum Seitenende Profil || Suche
008
06.04.2005, 15:48
feigling



Blöde Frage aber wo rufst du denn die Use Funktion überhaupt im Code auf ?

Müsste die nicht irgendwo in der

"void CPropTerminal::InputToggle( inputdata_t &inputData )"

Funktion aufgerufen werden ? Kann auch sein, dass ich total falsch liege und die automatisch aufgerufen wird (hab seit Wochen nichts mit dem HL2 Code gemacht). Wenn das der Fall ist, poste mal den *.fgd Eintrag von dem Entity.

--

zum Seitenanfang zum Seitenende Profil || Suche
009
06.04.2005, 19:51
Quak



Normalerweise sollte Use automatisch gerufen werden, aber probiers mal mit dem code in deiner InputToggle funktion:
Use( inputdata.pActivator, inputdata.pCaller, (USE_TYPE)inputdata.nOutputID, 0 );

--

Coder @ Heat

zum Seitenanfang zum Seitenende Profil || Suche
010
06.04.2005, 21:07
m0ep



Schreib mal:

BEGIN_DATADESC( CPropTerminal )
....
DEFINE_USEFUNC(Use)
...
END_DATADESC()

vieleicht gehts dann :|

--

zum Seitenanfang zum Seitenende Profil || Suche
011
06.04.2005, 21:14
feigling



Jo, das müsste es sein.

Ist auch so an anderen Stellen im Code:

BEGIN_DATADESC( CNPCSimpleTalker )
DEFINE_USEFUNC( FollowerUse ),
END_DATADESC()

void CNPCSimpleTalker::FollowerUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )..

src\dlls\npc_talker.cpp als Beispiel.

--

zum Seitenanfang zum Seitenende Profil || Suche
012
06.04.2005, 21:53
GcDesign



Beides von beidem zeigt keine Wirkung bzw. macht Fehler.
Also wenn ich meine Zeile mit der von dir ersetze Quak, dann gibt's nur Fehler...

DEFINE_USEFUNC zeigt keine Wirkung

--

aja hier is ja gerade noch was neues von feigling dazugekommen - das muss ich erst genauer testen ^^

thx auf jeden fall schon mal!

EDIT:
Das funktioniert einfach nicht :/
kA wieso, warum - aber es geht nicht - ich hab jetzt übrigens mal VPHYSICS aktiviert und auch VPHYSICScreate reingegeben - theoretisch sollte ja alles gehen aber es wird einfach nicht ausgelöst durch "E" drücken...
kA wieso

vl. muss ich das ganze wirklich komplett buttons.cpp nachahmen :(

--


Dieser Beitrag wurde am 06.04.2005 um 22:26 von GcDesign bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
013
06.04.2005, 22:47
Quak



Noch eine Möglichkeit wäre eine Touch() Funktion zu benutzen und bei Berührung zu testen ob der Spieler IN_USE gedrückt hat/hält und dann die Waffe zu geben.

--

Coder @ Heat

zum Seitenanfang zum Seitenende Profil || Suche
014
07.04.2005, 14:34
Quak



Hab gerade das hier auf valve-erc.com/srcsdk gefunden ;)

Zitat:
DEFINE_USEFUNC

Entities using a Use() function must declare that function via this macro declaration.

Use functions must be of the type:

typedef void (*UseFunc)(
CBaseEntity *pActivator,
CBaseEntity *pCaller,
USE_TYPE useType,
float value
);

--

Coder @ Heat

zum Seitenanfang zum Seitenende Profil || Suche
015
07.04.2005, 18:23
GcDesign



danke für das ganez aber soweit bin ich beim verc auch schon gekommen - und adbei hab ich schon alle unterschiedlichen variationen mit SetUse() und den defines_ - etc. probirt

Trotzdem - wie würdest du das mit define_usefunc dann anstellen?

Aja und ich habs jetzt wirklich einfach mal probiert eine Touch() Methode zu implenmtieren - und siehe da - es funktioniert auf Anhieb - d.h. bei der Variante bräuchte ich nur mehr herausfinden wie man auswerten kann ob spezielle Tasten (hiere eben die "Use" Taste) gedrückt sind!

--

zum Seitenanfang zum Seitenende Profil || Suche
016
07.04.2005, 19:49
Killing Me Softly



Irgendwie sehe ich in dem oberen Code nicht, das du die Funktion ObjectCaps() überschrieben hast. Die Funktion gibt ein Integer zurück. Nur falls die Flags FCAP_IMPULSE_USE, FCAP_CONTINUOUS_USE oder FCAP_ONOFF_USE bei dem Rückgabewert gesetzt sind, kann der Spieler das Entity "benutzen".

--

Der Horizont vieler Menschen ist ein Kreis mit Radius Null - und das nennen sie ihren Standpunkt.

zum Seitenanfang zum Seitenende Profil || Suche
017
07.04.2005, 20:10
Quak



Caste den pActivator zu nem CBasePlayer und teste

Quellcode:if ( pPlayer->m_nButtons & IN_USE )
{
      ....
}
Alternativ kanst du auch m_afButtonPressed oder m_afButtonReleased testen.

--

Coder @ Heat

zum Seitenanfang zum Seitenende Profil || Suche
018
07.04.2005, 21:45
GcDesign



Heureka ^^
Ich hab's (nein mehr ihr habt's und besonders Quak) gefunden!

Mit dem Code von Quak geht's - ich musste nur noch die in_buttons.h includen (ein großer Erfolg für einen Newbie wie mich ;) )
Also, jetzt funktionierts auf diese Weise!

Mich würde nur auch noch interessieren was genau, du - Killing Me Softly - gemeint hast.
(BTW: deine Signatur find ich sehr gut)

Aja und eins noch - Quak - wenn du mal im ICQ bsit wär's toll wenn du mich authorisieren würdest =)

thx @ all

--

zum Seitenanfang zum Seitenende Profil || Suche
019
07.04.2005, 22:52
Killing Me Softly



Zitat:
GcDesign postete
Mich würde nur auch noch interessieren was genau, du - Killing Me Softly - gemeint hast.
Was passiert, wenn der Spieler die Use-Taste drückt?
In der Memberfunktion void CBasePlayer::PlayerUse ( void ) wird das Entity ermittelt, welches "benutzt" werden soll. Hierzu wird u.a. die Funktion CBaseEntity *CBasePlayer::FindUseEntity() aufgerufen, welches mehr oder weniger einfach alle umliegenden Entities überprüft, ob sie "benutzbar" sind und das sympatischste Entity wird zurückgegeben. Um zu ermitteln, ob ein Entity "benutzbar" ist oder nicht, wird die Funktion bool CBasePlayer::IsUseableEntity() für jedes Entity aufgerufen (kann mir noch jemand folgen :D)
Quellcode:bool CBasePlayer::IsUseableEntity( CBaseEntity *pEntity, unsigned int requiredCaps )
{
    if ( pEntity )
    {
        int caps = pEntity->ObjectCaps();
        if ( caps & (FCAP_IMPULSE_USE|FCAP_CONTINUOUS_USE|FCAP_ONOFF_USE|FCAP_DIRECTIONAL_USE) )
        {
            if ( (caps & requiredCaps) == requiredCaps )
                return true;
        }
    }

    return false;
}
Bei dem Wert, den pEntity->ObjectCaps() zurückliefert, muss also eines der im ersten Post genannten Flags gesetzt sein, damit das Entity als "benutzbar" angesehen wird. Bei einem Button sieht das z.B. folgendermaßen aus.
Quellcode:int CBaseButton::ObjectCaps(void)
{
    return((BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) |
            (HasSpawnFlags(SF_BUTTON_USE_ACTIVATES) ? (FCAP_IMPULSE_USE | FCAP_USE_IN_RADIUS) : 0));
}
Damit das normale Use bei dir funktioniert, müsstest du besagte Funktion überschreiben. Das könnte z.B. so aussehen:
Quellcode:int CPropTerminal::ObjectCaps(void)
{
    return (BaseClass::ObjectCaps() | FCAP_IMPULSE_USE);
}

--

Der Horizont vieler Menschen ist ein Kreis mit Radius Null - und das nennen sie ihren Standpunkt.


Dieser Beitrag wurde am 07.04.2005 um 22:53 von Killing Me Softly bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
020
07.04.2005, 23:15
GcDesign



Sehr interessant - wahrscheinlich das, nachdem ich die ganze Zeit mehr oder weniger auch gesucht hab :)

ICh werd mal schaun wie ich damit zurechtkomm und jetzt überhaupt gleich mal ein paar Seiten über'S VGUI lesen

Also - thx nochmal an alle
(und hoffentlich bis zum nächsten mal ^^)

--

zum Seitenanfang zum Seitenende Profil || Suche
021
10.04.2005, 01:36
m0ep



Ich habs jetzt hinbekommen, mit der Use-Funktion \o/

Nach dem ich ein bissle im BaseEntity code rumgestöbert habe ist mir die Funktion UseSet(...) aufgefallen.

Ok, auprobiert, Code von Killing Me Softly noch eingefügt und schon gings. Ohne den Umweg über Touch(...) :D

Noch mal alles zum mitschreiben:

Quellcode:class CPropTerminal
{
    ...
    void MyUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType,    float value );
    int ObjectCaps(void);
    ...
}

void CPropTerminal::Spawn()
{
    ...
    SetUse(MyUse);
    ...
}

void CPropTerminal::MyUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
    CBasePlayer *pPlayer = ToBasePlayer( pActivator );

    // hier code einfuegen
}

int CPropTerminal::ObjectCaps(void)
{
    return (BaseClass::ObjectCaps() | FCAP_IMPULSE_USE);
}
Viel Spaß =)

--


Dieser Beitrag wurde am 10.04.2005 um 01:38 von m0ep bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
022
10.04.2005, 14:53
GcDesign



Thx!
Funktioniert bei mir auch, übrigens sogar ohne SetUse()!

Aja - eine Frage: weiß jemand über das VGUI bescheid?
Mein nächster Schritt dabei wäre nämlich ein Kauf-Menü ^^

--

zum Seitenanfang zum Seitenende Profil || Suche
023
10.04.2005, 23:43
Quak



Ich hab schon ein wenig mit dem VGUI gearbeitet und müsste demnächst auch ein ähnliches Menü für meine Mod coden, vielleicht können wir das ja zusammen erarbeiten. Melde dich einfach bei mir, hast ja meine ICQ Nummer.

--

Coder @ Heat

zum Seitenanfang zum Seitenende Profil || Suche