Наше комьюнити:   OpenGL Shader Lab  •  Half-Life FX  •  Форум  
HLFX.Ru Forum
профиль •  правила •  регистрация •  календарь •  народ •  FAQ •  поиск •  новое •  сутки •  главная •  выход  
HLFX.Ru Forum HLFX.Ru Forum > Теория и практика > Half-Life SDK > Проблема c grapple.
Добавил определение текстур xeno_grapple. Все работает, но есть одно но...
  Предыдущая тема   Следующая тема
Автор
Тема Новая тема    Ответить
Lost_Gamer_
NULL
Девойс

Дата регистрации: Jan 2017
Проживает: Лида
Сообщений: 17

Рейтинг



Half-Life Проблема c grapple.

http://youtu.be/e_X38m6QAg0 здесь показан баг у grapple.
Вот весь код:

C++ Source Code:
/***
*
*   Copyright © 1996-2001, Valve LLC. All rights reserved.
*
*   This product contains software technology licensed from Id
*   Software, Inc. ("Id Technology").  Id Technology © 1996 Id Software, Inc.
*   All Rights Reserved.
*
*   Use, distribution, and modification of this source code and/or resulting
*   object code is restricted to non-commercial enhancements to products from
*   Valve LLC.  All other use, distribution, or modification is prohibited
*   without written permission from Valve LLC.
*
****/


#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "monsters.h"
#include "weapons.h"
#include "nodes.h"
#include "player.h"
#include "gamerules.h"
#include "customentity.h"
#include "grapple_tonguetip.h"
#include <string.h>

#ifndef CLIENT_DLL
LINK_ENTITY_TO_CLASS(grapple_tonguetip, CGrappleTonguetip);

TYPEDESCRIPTION    CGrappleTonguetip::m_SaveData[] =
{
    DEFINE_FIELD(CGrappleTonguetip, m_pMyGrappler, FIELD_CLASSPTR),
};

IMPLEMENT_SAVERESTORE(CGrappleTonguetip, CBaseEntity);

//=========================================================
// Purpose: Spawn
//=========================================================
void CGrappleTonguetip::Spawn(void)
{
    pev->movetype = MOVETYPE_TOSS;
    pev->classname = MAKE_STRING("grapple_tonguetip");
    CheckTarget = 0;
    pev->solid = SOLID_BBOX;
    pev->rendermode = kRenderTransTexture;
    pev->renderamt = 0;
    pev->gravity = 0.01;
    
    SET_MODEL(ENT(pev), "models/v_bgrap_tonguetip.mdl");
    
    UTIL_SetSize(pev, Vector(0, 0, 0), Vector(0, 0, 0));
    
    SetTouch(&CGrappleTonguetip::TipTouch);
}


//=========================================================
// Purpose: CreateTip
//=========================================================
CGrappleTonguetip* CGrappleTonguetip::CreateTip(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity)
{
    CGrappleTonguetip* pTonguetip = GetClassPtr((CGrappleTonguetip *)NULL);
    pTonguetip->Spawn();
    
    UTIL_SetOrigin(pTonguetip->pev, vecStart);
    pTonguetip->pev->velocity = vecVelocity;
    pTonguetip->pev->owner = ENT(pevOwner);
    pTonguetip->m_pMyGrappler = GetClassPtr((CGrapple*)pevOwner);
    pTonguetip->SetThink(&CGrappleTonguetip::FlyThink);
    pTonguetip->pev->nextthink = gpGlobals->time + 0.1;
    
    return pTonguetip;
}

//=========================================================
// Purpose: FlyThink
//=========================================================
void CGrappleTonguetip::FlyThink(void)
{
    //ALERT(at_console, "FlyThink\n");
    
    pev->nextthink = gpGlobals->time + 0.1f;
}

//=========================================================
// Purpose: HitThink
//=========================================================
void CGrappleTonguetip::HitThink(void)
{
    //ALERT(at_console, "HitThink\n");
    
    pev->nextthink = gpGlobals->time + 0.1f;
}

//=========================================================
// Purpose: TipTouch
//=========================================================
void CGrappleTonguetip::TipTouch(CBaseEntity *pOther)
{
    // Do not collide with the owner.
    if (ENT(pOther->pev) == pev->owner || (ENT(pOther->pev) == VARS(pev->owner)->owner))
        return;
    
    TraceResult tr;
    float rgfl1[3];
    float rgfl2[3];
    const char *pTextureName;
    Vector vecSrc = pev->origin;
    Vector vecEnd = pev->origin + pev->velocity * 10;
    
    UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, ENT(pev), &tr);
    
    CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit);
    vecSrc.CopyToArray(rgfl1);
    vecEnd.CopyToArray(rgfl2);
    
    if (pEntity)
        pTextureName = TRACE_TEXTURE(ENT(pEntity->pev), rgfl1, rgfl2);
    else
        pTextureName = TRACE_TEXTURE(ENT(0), rgfl1, rgfl2);
    
    
    int content = UTIL_PointContents(tr.vecEndPos);
    int hitFlags = pOther->pev->flags;
    
    m_pMyGrappler->m_iHitFlags    = hitFlags;
    //float m_IsPull;
    if(FClassnameIs( pOther->pev, "monster_barnacle"))
    {
        pev->velocity = Vector(0, 0, 0);
        pev->movetype = MOVETYPE_NONE;
        pev->gravity = 0.0f;
        m_pMyGrappler->m_fTipHit    = FALSE;
        hitFlags = 0;
        m_pMyGrappler->OnTongueTipHitSurface(tr.vecEndPos);
        CheckTarget = 1;
    }
    
    if ((hitFlags & (FL_CLIENT | FL_MONSTER)) || (FClassnameIs( pOther->pev, "ammo_spore")) || (hitFlags && pTextureName && m_pMyGrappler && (strnicmp (pTextureName, "xeno_grapple", 15) == 0)))
    {
        // Set player attached flag.
        if (pOther->IsPlayer())
            ((CBasePlayer*)pOther)->m_afPhysicsFlags |= PFLAG_ATTACHED;
        
        pev->origin = pOther->Center();
        
        pev->movetype = MOVETYPE_FOLLOW;
        pev->aiment = ENT(pOther->pev);
        
        pev->velocity = pev->velocity.Normalize();
        
        m_pMyGrappler->OnTongueTipHitEntity(pOther);
        m_pMyGrappler->m_fTipHit    = TRUE;
        CheckTarget = 0;
    }
    else
    {
        pev->velocity = Vector(0, 0, 0);
        pev->movetype = MOVETYPE_NONE;
        pev->gravity = 0.0f;
        m_pMyGrappler->m_fTipHit    = FALSE;
        hitFlags = 0;
        m_pMyGrappler->OnTongueTipHitSurface(tr.vecEndPos);
        CheckTarget = 1;
    }
    
    EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "weapons/bgrapple_impact.wav", 1, ATTN_NORM, 0, 100);
    
    SetTouch( NULL );
    SetThink(&CGrappleTonguetip::HitThink);
    pev->nextthink = gpGlobals->time + 0.1f;
}

void CGrappleTonguetip::PreRemoval(void)
{
    if (pev->aiment != NULL)
    {
        CBaseEntity* pEnt = GetClassPtr((CBaseEntity*)VARS(pev->aiment));
        if (pEnt && pEnt->IsPlayer())
        {
            // Remove attached flag of the target entity.
            ((CBasePlayer*)pEnt)->m_afPhysicsFlags &= ~PFLAG_ATTACHED;
        }
    }
    CBaseEntity::PreRemoval();
}
#endif

LINK_ENTITY_TO_CLASS(weapon_grapple, CGrapple);

enum bgrap_e {
    BGRAP_BREATHE = 0,
    BGRAP_LONGIDLE,
    BGRAP_SHORTIDLE,
    BGRAP_COUGH,
    BGRAP_DOWN,
    BGRAP_UP,
    BGRAP_FIRE,
    BGRAP_FIREWAITING,
    BGRAP_FIREREACHED,
    BGRAP_FIRETRAVEL,
    BGRAP_FIRERELEASE,
};

//=========================================================
// Purpose:
//=========================================================
void CGrapple::Spawn()
{
    
    SetThink( NULL );
    Precache();
    m_iId = WEAPON_GRAPPLE;
    SET_MODEL(ENT(pev), "models/w_bgrap.mdl");
    m_iClip = -1;
    
    m_pBeam    = NULL;
    m_pTongueTip    = NULL;
    m_fTipHit    = FALSE;
    m_fPlayPullSound = FALSE;
    
    m_iHitFlags    = 0;
    m_iFirestate    = FIRESTATE_NONE;
    
    m_flNextPullSoundTime = 0.0f;
    
    FallInit();// get ready to fall down.
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::Precache(void)
{
    PRECACHE_MODEL("models/v_bgrap.mdl");
    PRECACHE_MODEL("models/v_bgrap_tonguetip.mdl");
    
    PRECACHE_MODEL("models/w_bgrap.mdl");
    PRECACHE_MODEL("models/p_bgrap.mdl");
    
    PRECACHE_SOUND("weapons/alienweap_draw.wav");
    
    PRECACHE_SOUND("weapons/bgrapple_cough.wav");
    PRECACHE_SOUND("weapons/bgrapple_fire.wav");
    PRECACHE_SOUND("weapons/bgrapple_impact.wav");
    PRECACHE_SOUND("weapons/bgrapple_pull.wav");
    PRECACHE_SOUND("weapons/bgrapple_release.wav");
    PRECACHE_SOUND("weapons/bgrapple_wait.wav");
    
    PRECACHE_MODEL("sprites/tongue.spr");
}

//=========================================================
// Purpose:
//=========================================================
int CGrapple::GetItemInfo(ItemInfo *p)
{
    p->pszName = STRING(pev->classname);
    p->pszAmmo1 = NULL;
    p->iMaxAmmo1 = -1;
    p->pszAmmo2 = NULL;
    p->iMaxAmmo2 = -1;
    p->iMaxClip = WEAPON_GRAPPLE;
    p->iSlot = 0;
    p->iPosition = 3;
    p->iId = WEAPON_GRAPPLE;
    p->iWeight = GRAPPLE_WEIGHT;
    return 1;
}

//=========================================================
// Purpose:
//=========================================================
BOOL CGrapple::Deploy()
{
    m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.9f;
    m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.9f;
    
    return DefaultDeploy("models/v_bgrap.mdl", "models/p_bgrap.mdl", BGRAP_UP, "bgrap");
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::Holster(int skiplocal /* = 0 */)
{
    FireRelease();
    
    m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
    SendWeaponAnim(BGRAP_DOWN);
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::PrimaryAttack(void)
{
    if (m_iFirestate != FIRESTATE_NONE)
        return;
    
    m_iFirestate = FIRESTATE_FIRE;
    
    m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + RANDOM_FLOAT(10, 15);
    m_flTimeWeaponIdle = UTIL_WeaponTimeBase();
}

//=========================================================
// Purpose:``
//=========================================================
void CGrapple::ItemPostFrame(void)
{
    if (!(m_pPlayer->pev->button & IN_ATTACK))
    {
        m_flLastFireTime = 0.0f;
    }
    
    
    if (m_iFirestate != FIRESTATE_NONE)
    {
        if (m_fTipHit)
        {
            Pull();
        }
        
        // Check if fire is still eligible.
        CheckFireEligibility();
        CheckTargets();
        // Check if the current tip is attached to a monster or a wall.
        // If the tongue tip move type is MOVETYPE_FOLLOW, then it
        // implies that we are targetting a monster, so it will kill
        // the monster when close enough.
        CheckTargetProximity();
        
        // Update the tip velocity and position.
        UpdateTongueTip();
        
        // Update the tongue beam.
        UpdateBeam();
        
        // Update the pull sound.
        UpdatePullSound();
    }
    
    if ((m_pPlayer->pev->button & IN_ATTACK) && CanAttack(m_flNextPrimaryAttack, gpGlobals->time, UseDecrement()))
    {
        if ((m_iClip == 0 && pszAmmo1()) || (iMaxClip() == -1 && !m_pPlayer->m_rgAmmo[PrimaryAmmoIndex()]))
        {
            m_fFireOnEmpty = TRUE;
        }
        
#ifndef CLIENT_DLL
        m_pPlayer->TabulateAmmo();
#endif
        PrimaryAttack();
        m_pPlayer->pev->button &= ~IN_ATTACK;
    }
    else if (!(m_pPlayer->pev->button & (IN_ATTACK | IN_ATTACK2)))
    {
        if (m_iFirestate != FIRESTATE_NONE)
        {
            FireRelease();
        }
        
#ifndef CLIENT_DLL
        // no fire buttons down
        
        m_fFireOnEmpty = FALSE;
        
        if (!IsUseable() && m_flNextPrimaryAttack < (UseDecrement() ? 0.0 : gpGlobals->time))
        {
            // weapon isn't useable, switch.
            if (!(iFlags() & ITEM_FLAG_NOAUTOSWITCHEMPTY) && g_pGameRules->GetNextBestWeapon(m_pPlayer, this))
            {
                m_flNextPrimaryAttack = (UseDecrement() ? 0.0 : gpGlobals->time) + 0.3;
                return;
            }
        }
#endif
        
        WeaponIdle();
        return;
    }
    
    // catch all
    if (ShouldWeaponIdle())
    {
        WeaponIdle();
    }
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::WeaponIdle(void)
{
    ResetEmptySound();
    
    if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase())
        return;
    
    if (m_iFirestate != FIRESTATE_NONE)
    {
        switch (m_iFirestate)
        {
            case FIRESTATE_FIRE:
                Fire();
            break;
            
            case FIRESTATE_FIRE2:
                Fire2();
            break;
            
            case FIRESTATE_WAIT:
                FireWait();
            break;
            
            case FIRESTATE_REACH:
                FireReach();
            break;
            
            case FIRESTATE_TRAVEL:
                FireTravel();
            break;
            
            case FIRESTATE_RELEASE:
                FireRelease();
            break;
            
            default:
                break;
        }
        return;
    }
    
    int iAnim;
    float flRand = UTIL_SharedRandomFloat(m_pPlayer->random_seed, 0, 1);
    if (flRand <= 0.8f)
    {
        iAnim = BGRAP_BREATHE;
        m_flTimeWeaponIdle = 2.6f;
    }
    else if (flRand <= 0.7f)
    {
        iAnim = BGRAP_LONGIDLE;
        m_flTimeWeaponIdle = 10.0f;
    }
    else if (flRand <= 0.95)
    {
        iAnim = BGRAP_SHORTIDLE;
        m_flTimeWeaponIdle = 1.3f;
    }
    else
    {
        iAnim = BGRAP_COUGH;
        m_flTimeWeaponIdle = 4.6f;
        
        EMIT_SOUND(ENT(pev), CHAN_BODY, "weapons/bgrapple_cough.wav", 1, ATTN_NORM);
    }
    
    SendWeaponAnim(iAnim, UseDecrement());
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::Fire(void)
{
    EMIT_SOUND(ENT(pev), CHAN_BODY, "weapons/bgrapple_fire.wav", 1, ATTN_NORM);
    
    SendWeaponAnim(BGRAP_FIRE, UseDecrement());
    m_iFirestate = FIRESTATE_FIRE2;
    
    m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + RANDOM_FLOAT(15, 20);
    m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.45f;
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::Fire2(void)
{
    // Create the tongue tip.
    CreateTongueTip();
    
    // Start the pull sound.
    StartPullSound();
    
    m_iFirestate = FIRESTATE_WAIT;
    
    m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + RANDOM_FLOAT(15, 20);
    m_flTimeWeaponIdle = UTIL_WeaponTimeBase();
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::FireWait(void)
{
    SendWeaponAnim(BGRAP_FIREWAITING, UseDecrement());
    
    m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + RANDOM_FLOAT(15, 20);
    m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.5f;
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::FireReach(void)
{
    SendWeaponAnim(BGRAP_FIREREACHED, UseDecrement());
    m_iFirestate = FIRESTATE_TRAVEL;
    
    // Start pulling the owner toward tongue tip.
    StartPull();
    
    m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + RANDOM_FLOAT(15, 20);
    //m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 4.7;
    m_flTimeWeaponIdle = UTIL_WeaponTimeBase();
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::FireTravel(void)
{
    SendWeaponAnim(BGRAP_FIRETRAVEL, UseDecrement());
    
    m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + RANDOM_FLOAT(15, 20);
    m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.6f;
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::FireRelease(void)
{
    // Stop pull sound.
    // STOP_SOUND(ENT(pev), CHAN_VOICE, "weapons/bgrapple_pull.wav");
    
    // Play release sound.
    EMIT_SOUND(ENT(pev), CHAN_BODY, "weapons/bgrapple_release.wav", 1, ATTN_NORM);
    
    SendWeaponAnim(BGRAP_FIRERELEASE, UseDecrement());
    m_iFirestate = FIRESTATE_NONE;
    // Stop the pulling.
    StopPull();
    
    // Reset pull sound.
    ResetPullSound();
    
    // Destroy the tongue tip.
    DestroyTongueTip();
    
    m_fTipHit = FALSE;
    m_iHitFlags = 0;
    
    m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.75f;
    m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.1;
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::OnTongueTipHitSurface(const Vector& vecTarget)
{
#ifndef CLIENT_DLL
    //ALERT(at_console, "Hit surface at: (%f,%f,%f).\n", vecTarget.x, vecTarget.y, vecTarget.z);
#endif
    FireReach();
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::OnTongueTipHitEntity(CBaseEntity* pEntity)
{
#ifndef CLIENT_DLL
    ALERT(at_console, "Hit entity with classname %s.\n", (char*)STRING(pEntity->pev->classname));
#endif
    FireReach();
}
//=========================================================
// Purpose:
//=========================================================
void CGrapple::StartPull(void)
{
#ifndef CLIENT_DLL
    Vector vecOrigin = m_pPlayer->pev->origin;
    
    vecOrigin.z++;
    UTIL_SetOrigin(m_pPlayer->pev, vecOrigin);
    
    m_pPlayer->pev->movetype = MOVETYPE_FLY;
    m_pPlayer->pev->gravity = 0.0f;
    
    m_pPlayer->pev->flags &= ~FL_ONGROUND;
    
    m_pPlayer->m_afPhysicsFlags |= PFLAG_LATCHING;
#endif
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::StopPull(void)
{
#ifndef CLIENT_DLL
    m_pPlayer->pev->movetype = MOVETYPE_WALK;
    m_pPlayer->pev->gravity = 1.0f;
    
    m_pPlayer->m_afPhysicsFlags &= ~PFLAG_LATCHING;
#endif
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::Pull( void )
{
#ifndef CLIENT_DLL
    Vector vecOwnerPos, vecTipPos, vecDirToTip;
    vecOwnerPos = m_pPlayer->pev->origin;
    vecTipPos = m_pTongueTip->pev->origin;
    vecDirToTip = (vecTipPos - vecOwnerPos).Normalize();
    
    m_pPlayer->pev->velocity = vecDirToTip * 450;
    
    m_pPlayer->m_afPhysicsFlags |= PFLAG_LATCHING;
#endif
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::CreateTongueTip( void )
{
#ifndef CLIENT_DLL
    Vector vecSrc, vecAiming, vecVel;
    UTIL_MakeVectors( m_pPlayer->pev->v_angle );
    
    vecSrc = m_pPlayer->GetGunPosition();
    vecSrc = vecSrc + gpGlobals->v_forward * 8;
    vecSrc = vecSrc + gpGlobals->v_right * 3;
    vecSrc = vecSrc + gpGlobals->v_up * -3;
    
    vecVel = gpGlobals->v_forward * 1200;
    
    //GetAttachment(0, vecSrc, vecAiming);
    
    m_pTongueTip = CGrappleTonguetip::CreateTip(pev, vecSrc, vecVel);
    CreateBeam(m_pTongueTip);
    
#endif
    
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::DestroyTongueTip(void)
{
#ifndef CLIENT_DLL
    DestroyBeam();
    CheckTarget = 0;
    if (m_pTongueTip)
    {
        UTIL_Remove(m_pTongueTip);
        m_pTongueTip = NULL;
    }
#endif
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::UpdateTongueTip(void)
{
#ifndef CLIENT_DLL
    if (m_pTongueTip)
    {
        Vector tipVel = m_pTongueTip->pev->velocity;
        Vector ownerVel = VARS(pev->owner)->velocity;
        
        Vector newVel;
        
        newVel.x = tipVel.x + (ownerVel.x * 0.02f);
        newVel.y = tipVel.y + (ownerVel.y * 0.05f);
        newVel.z = tipVel.z + (ownerVel.z * 0.01f);
        
        m_pTongueTip->pev->velocity = newVel;
    }
#endif
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::CreateBeam( CBaseEntity* pTongueTip )
{
#ifndef CLIENT_DLL
    m_pBeam = CBeam::BeamCreate("sprites/tongue.spr", 16);
    
    if (m_pBeam)
    {
        m_pBeam-&gt<img src="images/smilies/pp2.gif" border="0" alt="">ointsInit(pTongueTip->pev->origin, pev->origin);
        m_pBeam->SetFlags( BEAM_FSOLID );
        m_pBeam->SetBrightness( 100.0 );
        
        m_pBeam->SetEndAttachment( 1 );
        m_pBeam->pev->spawnflags |= SF_BEAM_TEMPORARY;
    }
#endif
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::DestroyBeam(void)
{
#ifndef CLIENT_DLL
    if (m_pBeam)
    {
        UTIL_Remove(m_pBeam);
        m_pBeam = NULL;
    }
#endif
}

//=========================================================
// Purpose:
//=========================================================
void CGrapple::UpdateBeam(void)
{
#ifndef CLIENT_DLL
    if (m_pBeam)
    {
        Vector vecSrc;
        UTIL_MakeVectors(m_pPlayer->pev->v_angle);
        
        vecSrc = m_pPlayer->GetGunPosition();
        vecSrc = vecSrc + gpGlobals->v_forward * 16;
        vecSrc = vecSrc + gpGlobals->v_right * 6;
        vecSrc = vecSrc + gpGlobals->v_up * -8;
        m_pBeam->SetStartPos(vecSrc);
        m_pBeam->SetEndPos(m_pTongueTip->pev->origin);
        m_pBeam->RelinkBeam();
    }
#endif
}

//=========================================================
// Purpose:
//=========================================================
BOOL CGrapple::CanAttack(float attack_time, float curtime, BOOL isPredicted)
{
#if defined( CLIENT_WEAPONS )
    if (!isPredicted)
#else
    if (1)
#endif
    {
        return (attack_time <= curtime) ? TRUE : FALSE;
    }
    else
    {
        return (attack_time <= 0.0) ? TRUE : FALSE;
    }
}


void CGrapple::StartPullSound(void)
{
    m_flNextPullSoundTime = UTIL_WeaponTimeBase();
    m_fPlayPullSound = TRUE;
}

void CGrapple::UpdatePullSound(void)
{
    if (!m_fPlayPullSound)
        return;
    
    if (m_flNextPullSoundTime <= UTIL_WeaponTimeBase())
    {
        EMIT_SOUND(ENT(pev), CHAN_BODY, "weapons/bgrapple_pull.wav", 1, ATTN_NORM);
        m_flNextPullSoundTime = UTIL_WeaponTimeBase() + 0.6f;
    }
}

void CGrapple::ResetPullSound(void)
{
    STOP_SOUND(ENT(pev), CHAN_BODY, "weapons/bgrapple_pull.wav");
    m_flNextPullSoundTime = 0.0f;
    m_fPlayPullSound = FALSE;
}

void CGrapple::CheckTargets( void )
{//If the target isn't monster or xeno_grapple
if( CheckTarget == 1)
{
    EMIT_SOUND(ENT(pev), CHAN_BODY, "weapons/bgrapple_release.wav", 1, ATTN_NORM);
    DestroyTongueTip();
    Fire2();
}
}

BOOL CGrapple::IsTongueColliding(const Vector& vecShootOrigin, const Vector& vecTipPos)
{
#ifndef CLIENT_DLL
    TraceResult tr;
    UTIL_TraceLine(vecShootOrigin, vecTipPos, dont_ignore_monsters, ENT(m_pPlayer->pev), &tr);
    
    if (tr.flFraction != 1.0)
    {
        if (m_pTongueTip->pev->movetype == MOVETYPE_FOLLOW)
        {
            if (tr.pHit && m_pTongueTip->pev->aiment && m_pTongueTip->pev->aiment == tr.pHit)
                return FALSE;
        }
        
        return TRUE;
    }
    
    return FALSE;
#else
    return TRUE;
#endif
}

void CGrapple::CheckFireEligibility(void)
{
#ifndef CLIENT_DLL
    // Do not check for this if the tongue is not valid.
    if (!m_pTongueTip)
        return;
    
    // Check if the tongue is through walls or if other things
    // such as entities are between the owner and the tip.
    if (IsTongueColliding(m_pPlayer->GetGunPosition(), m_pTongueTip->pev->origin))
    {
        // Stop firing!
        FireRelease();
    }
#endif
}


BOOL CGrapple::CheckTargetProximity(void)
{
#ifndef CLIENT_DLL
    // Do not check for this if the tongue is not valid.
    if (!m_pTongueTip)
        return FALSE;
    
    if (m_pTongueTip->pev->movetype == MOVETYPE_FOLLOW)
    {
        // Trace a hull around to see if we hit something within 20 units.
        TraceResult tr;
        UTIL_TraceHull(
        pev->origin,
        pev->origin + VARS(pev->owner)->velocity.Normalize() * 20,
        dont_ignore_monsters,
            head_hull,
        edict(),
        &tr);
        
        
        // Check to see if we are close enough to our target.
        // In the case o a monster, attempt to get a pointer to
        // the entity, gib it, release grappler fire.
        edict_t* pHit = ENT(tr.pHit);
        if ( pHit &&
            (VARS(pHit)->flags & FL_MONSTER) &&
        (m_pTongueTip->pev->aiment == tr.pHit))
        {
            // Get a pointer to the entity.
            CBaseEntity* pEnt = GetClassPtr((CBaseEntity*)VARS(tr.pHit));
            if (pEnt)
            {
                Attack();
            }
            else
            {
                //ALERT(at_console, "ERROR: %s attempted to reference an unlisted monster.\n", STRING(m_pTongueTip->pev->classname));
            }
            
            // Release fire.
            FireRelease();
        }
    }
#endif
    return FALSE;
}
void CGrapple::Attack( void )
{
#ifndef CLIENT_DLL
    //ALERT(at_console, "Attack\n");
    
    m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + gpGlobals->time + 0.5f;
    TraceResult tr;
    UTIL_TraceHull(
    pev->origin,
    pev->origin + VARS(pev->owner)->velocity.Normalize() * 20,
    dont_ignore_monsters,
        head_hull,
    edict(),
    &tr);
    UTIL_MakeVectors( m_pPlayer->pev->v_angle );
    float flDamage = gSkillData.plrDmgGrapple;
    
    if(g_pGameRules->IsMultiplayer())
        flDamage *= 2;
    
    ClearMultiDamage();
    CBaseEntity::Instance( tr.pHit )->TraceAttack( m_pPlayer->pev, flDamage, gpGlobals->v_forward, &tr, DMG_CLUB | DMG_ALWAYSGIB );
    ApplyMultiDamage( pev, m_pPlayer->pev );
#endif
}


Сообщить модератору | | IP: Записан
Сообщение: 166670

Старое сообщение 24-05-2017 16:45
- За что?
master07
Житель форума

Дата регистрации: Aug 2013
Проживает: гиде-то
Сообщений: 205
Возраст: 25

Рейтинг



Lost_Gamer_ Он у тебя притягивается к 0 0 0.
Если притяжение написано в Pull то смотри vecTipPos.
Ксено текстура это часть мира, а мир это тож ентитя по этому он к ней и прятигивается.
В итоге: либо это, либо где то указатель неправильный. Если скажешь где совершается передвижение от игрока к текстуре посмотрю(я не знаю, может Pull это то)

Сообщить модератору | | IP: Записан
Сообщение: 166672

Старое сообщение 25-05-2017 01:42
- За что?
Ku2zoff
Юзер (типа моддер)

Дата регистрации: Apr 2007
Проживает: В Деревне дураков
Сообщений: 4100
Возраст: 26

Рейтинг



Я код этого оружия никогда не читал, но примерно представляю, как оно работает. Не надо притягивать игрока к какой-то координате. Нужно сделать трейс от игрока к конечной точке, и если там ксен-текстура, то создавать при "касании" языка в этой точке энтитю tonguetip, и к ней уже притягивать. Судя по всему, у тебя tonguetip создаётся в нулевых координатах.

__________________
Вы всё ещё не пьёте? Тогда мы идём к вам!

Сообщить модератору | | IP: Записан
Сообщение: 166677

Старое сообщение 26-05-2017 02:57
- За что?
Lost_Gamer_
NULL
Девойс

Дата регистрации: Jan 2017
Проживает: Лида
Сообщений: 17

Рейтинг



Цитата:
Ku2zoff писал:
Я код этого оружия никогда не читал, но примерно представляю, как оно работает. Не надо притягивать игрока к какой-то координате. Нужно сделать трейс от игрока к конечной точке, и если там ксен-текстура, то создавать при "касании" языка в этой точке энтитю tonguetip, и к ней уже притягивать. Судя по всему, у тебя tonguetip создаётся в нулевых координатах.

Ну вроде там трейс, и к концу языка прикреплена невидимая модель.
Раньше притягивалось к стаенам правильно, но я не помню как я исправлял, чтоб вообще не притягивалось. Да и я нубоват ещё. Просто надеюсь на помощь.

Сообщить модератору | | IP: Записан
Сообщение: 166681

Старое сообщение 26-05-2017 12:53
- За что?
a1batross
Частый гость

Группа: Неопытный
Дата регистрации: May 2016
Проживает: Москва
Сообщений: 77
Возраст: 19

Рейтинг



> pev->origin = pOther->Center();

pOther в при Touch() будет ссылаться на мир. Ну ты взял Center() от pOther, вот он и летит в нулевой оригин.

Нужно наверное брать tr.vecEndPos, если pOther является миром, и Center(), если это там монстр или ammo_spore.

Сообщить модератору | | IP: Записан
Сообщение: 166698

Старое сообщение 28-05-2017 13:27
- За что?
Lost_Gamer_
NULL
Девойс

Дата регистрации: Jan 2017
Проживает: Лида
Сообщений: 17

Рейтинг



Цитата:
a1batross писал:
> pev->origin = pOther->Center();

pOther в при Touch() будет ссылаться на мир. Ну ты взял Center() от pOther, вот он и летит в нулевой оригин.

Нужно наверное брать tr.vecEndPos, если pOther является миром, и Center(), если это там монстр или ammo_spore.

Я это закомментировал и уже разобрался создав отдельное условие
else if( pTextureName && m_pMyGrappler && (strnicmp (pTextureName, "xeno_grapple", 15) == 0))
{
pev->velocity = Vector(0, 0, 0);
pev->movetype = MOVETYPE_NONE;
pev->gravity = 0.0f;
m_pMyGrappler->m_fTipHit = TRUE;
hitFlags = 0;
m_pMyGrappler->OnTongueTipHitSurface(tr.vecEndPos);
CheckTarget = 0;
}

Сообщить модератору | | IP: Записан
Сообщение: 166699

Старое сообщение 28-05-2017 13:48
- За что?
 Дядя Миша
who said meow?

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 20840
Нанёс повреждений: 355 ед.

Рейтинг



у тебя в слове "xeno_grapple" 12 символов, а ты написал 15. Вот зачем?

__________________
Дядя Миша is not able at all to do that before Пасхальный понедельник

Сообщить модератору | | IP: Записан
Сообщение: 166700

Старое сообщение 28-05-2017 14:13
-
Garux
Частый гость

Дата регистрации: Mar 2015
Проживает: Металлострой
Сообщений: 80

Рейтинг



strlen( "\"xeno_grapple\"," ) == 15
Вроде порядочек

Сообщить модератору | | IP: Записан
Сообщение: 166703

Старое сообщение 29-05-2017 07:11
- За что?
 Дядя Миша
who said meow?

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 20840
Нанёс повреждений: 355 ед.

Рейтинг



__________________
Дядя Миша is not able at all to do that before Пасхальный понедельник

Сообщить модератору | | IP: Записан
Сообщение: 166704

Старое сообщение 29-05-2017 09:25
-
Lost_Gamer_
NULL
Девойс

Дата регистрации: Jan 2017
Проживает: Лида
Сообщений: 17

Рейтинг



BOOL CGrapple::CheckTargetProximity(void)
{
#ifndef CLIENT_DLL
// Do not check for this if the tongue is not valid.
if (!m_pTongueTip)
return FALSE;

if (m_pTongueTip->pev->movetype == MOVETYPE_FOLLOW)
{
// Trace a hull around to see if we hit something within 20 units.
TraceResult tr;
UTIL_TraceHull(
pev->origin,
pev->origin + VARS(pev->owner)->velocity.Normalize() * 20,
dont_ignore_monsters,
head_hull,
edict(),
&tr);


// Check to see if we are close enough to our target.
// In the case o a monster, attempt to get a pointer to
// the entity, gib it, release grappler fire.
edict_t* pHit = ENT(tr.pHit);
if ( pHit/* && (m_pTongueTip->pev->aiment == tr.pHit)*/)
{
// Get a pointer to the entity.
CBaseEntity* pEnt = GetClassPtr((CBaseEntity*)VARS(tr.pHit));
if (pEnt)
{
SetThink( &CGrapple::Attack );
pev->nextthink = gpGlobals->time + 1;
}
else
{
FireRelease();
}
}
}
#endif
return FALSE;
}
void CGrapple::Attack( void )
{
#ifndef CLIENT_DLL
ALERT(at_console, "Attack\n");

TraceResult tr;
UTIL_TraceHull(
pev->origin,
pev->origin + VARS(pev->owner)->velocity.Normalize() * 20,
dont_ignore_monsters,
head_hull,
edict(),
&tr);
UTIL_MakeVectors( m_pPlayer->pev->v_angle );
float flDamage = gSkillData.plrDmgGrapple;

if(g_pGameRules->IsMultiplayer())
flDamage *= 2;

ClearMultiDamage();
CBaseEntity::Instance( tr.pHit )->TraceAttack( m_pPlayer->pev, flDamage, gpGlobals->v_forward, &tr, DMG_CLUB | DMG_ALWAYSGIB );
ApplyMultiDamage( pev, m_pPlayer->pev );
#endif
}

Здесь я пытался выставить таймер для дамага.
Но получилось так, что grapple аттакует только через секунду после того, как я перестану жать пкм.
Почему? Что я не так сделал?

Сообщить модератору | | IP: Записан
Сообщение: 166727

Старое сообщение 30-05-2017 14:54
- За что?
master07
Житель форума

Дата регистрации: Aug 2013
Проживает: гиде-то
Сообщений: 205
Возраст: 25

Рейтинг



Lost_Gamer_ заведи таймер и не нужно использовать setthink. В место этого функцию атаки скинь в условие и возьми в новое условие. К примеру if(timer <= gpGlibals->time) и в нутри этого условие timer = gpGlobals->time + 1.0f

Сообщить модератору | | IP: Записан
Сообщение: 166730

Старое сообщение 30-05-2017 16:09
- За что?
Lost_Gamer_
NULL
Девойс

Дата регистрации: Jan 2017
Проживает: Лида
Сообщений: 17

Рейтинг



master07 Можно по-понятнее? Я нубоват еще.

Сообщить модератору | | IP: Записан
Сообщение: 166731

Старое сообщение 30-05-2017 16:14
- За что?
master07
Житель форума

Дата регистрации: Aug 2013
Проживает: гиде-то
Сообщений: 205
Возраст: 25

Рейтинг



Lost_Gamer_ Жду в ЛС. Чтобы не спамить.

Сообщить модератору | | IP: Записан
Сообщение: 166733

Старое сообщение 30-05-2017 16:26
- За что?
Тема: (Опционально)
Ваш ответ:



Переводчик транслита


[проверить длину сообщения]
Опции: Автоматическое формирование ссылок: автоматически добавлять [url] и [/url] вокруг интернет адресов.
Уведомление по E-Mail: отправить вам уведомление, если кто-то ответил в тему (только для зарегистрированных пользователей).
Отключить смайлики в сообщении: не преобразовывать текстовые смайлики в картинки.
Показать подпись: добавить вашу подпись в конец сообщения (только зарегистрированные пользователи могут иметь подписи).

Временная зона GMT. Текущее время 00:18. Новая тема    Ответить
  Предыдущая тема   Следующая тема
HLFX.Ru Forum HLFX.Ru Forum > Теория и практика > Half-Life SDK > Проблема c grapple.
Добавил определение текстур xeno_grapple. Все работает, но есть одно но...
Версия для печати | Отправить тему по E-Mail | Подписаться на эту тему

Быстрый переход:
Оцените эту тему:

Правила Форума:
Вы not можете создавать новые темы
Вы not можете отвечать в темы
Вы not можете прикреплять вложения
Вы not можете редактировать ваши сообщения
HTML Код ВЫКЛ
vB Код ВКЛ
Смайлики ВКЛ
[IMG] Код ВКЛ
 

< Обратная связь - HLFX.ru >

На основе vBulletin
Авторское право © 2000 - 2002, Jelsoft Enterprises Limited.
Дизайн и программирование: Chain Studios © 2005-2017

Рейтинг@Mail.ru