Registration - or - Enter
ParanoiaParanoia

Лучшая отечественная модификация...

3/12/2007
SprucecapeSprucecape

Мы играем за Джона Спрюскейпа, бывшего профессора философии, алкоголика, который проживает в загородном доме где-то на А...


Добавление ножа из Op4


  • Description
  • Link and installation

Добавление ножа из Op4

Добавление ножа из Op4


Author/s of lesson : DIMaN[BBc]
Views : 1522 ( +1 )
Downloads : 0
Uploaded by : Streit
Created : 04/07/2011 5:33:01 PM
Source : http://www.confession.ucoz.ru/forum
Rating :
 ( 0 ) 
Share :


Available following translations : | russian |

Ну вопервых опредилимся с инструментами:

Возьмем Visual C++ 6.0 и исходники халвы - HL SDK 2.3 (Думаю эта версия подойдет). Теперь нам надо взять все файлы из OP4, нужные для ножа. Это модели, спрайты и звуки. Вот они:

Resource:

models/p_knife.mdl
models/v_knife.mdl
models/w_knife.mdl
sprites/320hudof01.spr
sprites/640hudof03.spr
sprites/640hudof04.spr
sprites/weapon_knife.txt
sound/weapons/knife1.wav
sound/weapons/knife2.wav
sound/weapons/knife3.wav
sound/weapons/knife_hit_flesh1.wav
sound/weapons/knife_hit_flesh2.wav
sound/weapons/knife_hit_wall1.wav
sound/weapons/knife_hit_wall2.wav

Напомню все это хранится в папке gearbox. И скопируйте все это в соответсвующие директории вашего мода. Примечание редактора: если у вас нет Opposing Force то эти файлы вы можете скачать здесь. Сначало откроем серверную часть. Это файл hl.dsp в папке dlls, которая хранится в SDK. Также все файлы с расширением *.cpp и *.h редактировать с помощью обычного блакнота. Напишем код для нашего ножа. Это будет файл knife.cpp. Создайте обычный текстовый документ, затем переменуйте и измените расширение. Затем скопируйте в него следующее (исходники ножа из OP4 взяты с http://zzero.fatal.ru/SDKopfor.html. Большое спасибо.):

Code:

//=========================================================
// Opposing Forces Weapon knife (standart knife)
//
// Made by Demiurge
//
//FGD weapon_knife
//
//Примечания DIMaN[BBc]
//=========================================================

#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "monsters.h"
#include "weapons.h"
#include "nodes.h"
#include "player.h"
#include "gamerules.h"

#define KNIFE_BODYHIT_VOLUME 128
#define KNIFE_WALLHIT_VOLUME 512
#define KNIFE_FLOOR 0
#define KNIFE_INFLOOR 1
#define KNIFE_INWALL 2

LINK_ENTITY_TO_CLASS( weapon_knife, CKnife ); //Создаем энтитю

enum gauss_e //Загружаем анимации
{
   KNIFE_IDLE = 0,
   KNIFE_DRAW,
   KNIFE_HOLSTER,
   KNIFE_ATTACK1HIT,
   KNIFE_ATTACK1MISS,
   KNIFE_ATTACK2MISS,
   KNIFE_ATTACK2HIT,
   KNIFE_ATTACK3MISS,
   KNIFE_ATTACK3HIT
};

void CKnife::Spawn( )
{
   Precache( );
   m_iId = WEAPON_KNIFE; //Имя энтити, которое внесем в fgd файл
   SET_MODEL(ENT(pev), "models/w_knife.mdl");//Модель нашего ножа на карте
   m_iClip = -1;

   pev->movetype = MOVETYPE_FLY;
   pev->solid = SOLID_TRIGGER;

   UTIL_SetOrigin( pev, pev->origin );
   UTIL_SetSize(pev, Vector( -16, -16, 0), Vector(16, 16, 32) );//pointsize until it lands on the ground.

   SetTouch( DefaultTouch );
   SetThink( FallThink );

   pev->nextthink = gpGlobals->time + 0.1;

   // pev->body
   // FallInit();// get ready to fall down.
}

void CKnife::Precache( void )
{
   //Загружаем модели и звуки
   PRECACHE_MODEL("models/v_knife.mdl");//Модель у нас в руках
   PRECACHE_MODEL("models/w_knife.mdl");//Модель на карте
   PRECACHE_MODEL("models/p_knife.mdl");//Модель в руках у игрока и мобов
   PRECACHE_SOUND("weapons/knife_hit_wall1.wav");
   PRECACHE_SOUND("weapons/knife_hit_wall2.wav");
   PRECACHE_SOUND("weapons/knife_hit_flesh1.wav");
   PRECACHE_SOUND("weapons/knife_hit_flesh2.wav");
   PRECACHE_SOUND("weapons/knife1.wav");
   PRECACHE_SOUND("weapons/knife2.wav");
   PRECACHE_SOUND("weapons/knife3.wav");

   m_usKnife = PRECACHE_EVENT ( 1, "events/knife.sc" );
}

int CKnife::GetItemInfo(ItemInfo *p)
{
   p->pszName = STRING(pev->classname);
   p->pszAmmo1 = NULL;
   p->iMaxAmmo1 = -1;
   p->pszAmmo2 = NULL;
   p->iMaxAmmo2 = -1;
   p->iMaxClip = WEAPON_NOCLIP;
   p->iSlot = 0;//Слот в худе, начиная с 0. В данном случае 1
   p->iPosition = 1; //Позиция в слоте худа, начиная с 0. В данном случае 2
   p->iId = WEAPON_KNIFE;
   p->iWeight = CROWBAR_WEIGHT;
   return 1;
}

//Остальное можно понять только со знанием языка С++

BOOL CKnife::Deploy( )
{
   return DefaultDeploy( "models/v_knife.mdl", "models/p_knife.mdl", KNIFE_DRAW, "knife" );
}

void CKnife::Holster( int skiplocal /* = 0 */ )
{
   m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
   SendWeaponAnim( KNIFE_HOLSTER );
}

void FindHullIntersectionKnife( const Vector &vecSrc, TraceResult &tr, float *mins, float *maxs, edict_t *pEntity )
{
   int i, j, k;
   float distance;
   float *minmaxs[2] = {mins, maxs};
   TraceResult tmpTrace;
   Vector vecHullEnd = tr.vecEndPos;
   Vector vecEnd;

   distance = 1e6f;

   vecHullEnd = vecSrc + ((vecHullEnd - vecSrc)*2);
   UTIL_TraceLine( vecSrc, vecHullEnd, dont_ignore_monsters, pEntity, &tmpTrace );
   if ( tmpTrace.flFraction < 1.0 )
   {
      tr = tmpTrace;
      return;
   }

   for ( i = 0; i < 2; i++ )
   {
     for ( j = 0; j < 2; j++ )
     {
       for ( k = 0; k < 2; k++ )
       {
         vecEnd.x = vecHullEnd.x + minmaxs[i][0];
         vecEnd.y = vecHullEnd.y + minmaxs[j][1];
         vecEnd.z = vecHullEnd.z + minmaxs[k][2];

         UTIL_TraceLine( vecSrc, vecEnd, dont_ignore_monsters, pEntity, &tmpTrace );
         if ( tmpTrace.flFraction < 1.0 )
         {
           float thisDistance = (tmpTrace.vecEndPos - vecSrc).Length();
           if ( thisDistance < distance )
           {
             tr = tmpTrace;
             distance = thisDistance;
           }
         }
       }
     }
   }
}

void CKnife::PrimaryAttack()
{
   if (! Swing( 1 ))
   {
     SetThink( SwingAgain );
     pev->nextthink = gpGlobals->time + 0.1;
   }
}

void CKnife::Smack( )
{
   DecalGunshot( &m_trHit, BULLET_PLAYER_CROWBAR );
}

void CKnife::SwingAgain( void )
{
   Swing( 0 );
}

int CKnife::Swing( int fFirst )
{
   int fDidHit = FALSE;

   TraceResult tr;

   UTIL_MakeVectors (m_pPlayer->pev->v_angle);
   Vector vecSrc = m_pPlayer->GetGunPosition( );
   Vector vecEnd = vecSrc + gpGlobals->v_forward * 32;

   UTIL_TraceLine( vecSrc, vecEnd, dont_ignore_monsters, ENT( m_pPlayer->pev ), &tr );

   #ifndef CLIENT_DLL
     if ( tr.flFraction >= 1.0 )
     {
       UTIL_TraceHull( vecSrc, vecEnd, dont_ignore_monsters, head_hull, ENT( m_pPlayer->pev ), &tr );
       if ( tr.flFraction < 1.0 )
       {
         // Calculate the point of intersection of the line (or hull) and the object we hit
         // This is and approximation of the "best" intersection
         CBaseEntity *pHit = CBaseEntity::Instance( tr.pHit );
         if ( !pHit || pHit->IsBSPModel() )
           FindHullIntersectionKnife( vecSrc, tr, VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX, m_pPlayer->edict() );
         vecEnd = tr.vecEndPos; // This is the point on the actual surface (the hull could have hit space)
       }
     }
   #endif

   if ( tr.flFraction >= 1.0 )
   {
     if (fFirst)
     {
       switch((m_iSwing++) % 3 )
       {
         case 0:
             SendWeaponAnim( KNIFE_ATTACK1MISS ); break;
           case 1:
             SendWeaponAnim( KNIFE_ATTACK2MISS ); break;
           case 2:
             SendWeaponAnim( KNIFE_ATTACK3MISS ); break;
       }
     // miss
     m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;

     switch( RANDOM_LONG(0,2) )
     {
       case 0:
         EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/knife1.wav", 1, ATTN_NORM);
         break;
       case 1:
         EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/knife2.wav", 1, ATTN_NORM);
         break;
       default:
         EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/knife3.wav", 1, ATTN_NORM);
         break;
     }
        // player "shoot" animation
       m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
     }
   }
   else
   {
     switch( ((m_iSwing++) % 2) + 1 )
     {
       case 0:
         SendWeaponAnim( KNIFE_ATTACK1HIT ); break;
       case 1:
         SendWeaponAnim( KNIFE_ATTACK2HIT ); break;
       case 2:
         SendWeaponAnim( KNIFE_ATTACK3HIT ); break;
     }

     // player "shoot" animation
     m_pPlayer->SetAnimation( PLAYER_ATTACK1 );

     #ifndef CLIENT_DLL

       // hit
       fDidHit = TRUE;
       CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit);

       ClearMultiDamage( );

       if ( (m_flNextPrimaryAttack + 1 < UTIL_WeaponTimeBase() ) || g_pGameRules->IsMultiplayer() )
       {
         // first swing does full damage
         pEntity->TraceAttack(m_pPlayer->pev, gSkillData.plrDmgCrowbar, gpGlobals->v_forward, &tr, DMG_CLUB );
       }
       else
       {
         // subsequent swings do half
         pEntity->TraceAttack(m_pPlayer->pev, gSkillData.plrDmgCrowbar / 2, gpGlobals->v_forward, &tr, DMG_CLUB );
       }
       ApplyMultiDamage( m_pPlayer->pev, m_pPlayer->pev );

       // play thwack, smack, or dong sound
       float flVol = 1.0;
       int fHitWorld = TRUE;

       if (pEntity)
       {
         if ( pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE )
         {
            // play thwack or smack sound
           switch( RANDOM_LONG(0,1) )
           {
             case 0:
               EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/knife_hit_flesh1.wav", 1, ATTN_NORM); break;
             case 1:
               EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/knife_hit_flesh2.wav", 1, ATTN_NORM); break;
           }
           m_pPlayer->m_iWeaponVolume = KNIFE_BODYHIT_VOLUME;
           if ( !pEntity->IsAlive() )
             return TRUE;
           else
             flVol = 0.1;

           fHitWorld = FALSE;
         }
       }

       // play texture hit sound
       // UNDONE: Calculate the correct point of intersection when we hit with the hull instead of the line

       if (fHitWorld)
       {
         float fvolbar = TEXTURETYPE_PlaySound(&tr, vecSrc, vecSrc + (vecEnd-vecSrc)*2, BULLET_PLAYER_CROWBAR);

         if ( g_pGameRules->IsMultiplayer() )
         {
           // override the volume here, cause we don't play texture sounds in multiplayer,
           // and fvolbar is going to be 0 from the above call.

           fvolbar = 1;
         }

         // also play knife strike
         switch( RANDOM_LONG(0,1) )
         {
           case 0:
             EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/knife_hit_wall1.wav", fvolbar, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3));
             break;
           case 1:
             EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/knife_hit_wall2.wav", fvolbar, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3));
             break;
         }

         // delay the decal a bit
         m_trHit = tr;
       }

       m_pPlayer->m_iWeaponVolume = flVol * KNIFE_WALLHIT_VOLUME;
     #endif
     m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.25;

     SetThink( Smack );
     pev->nextthink = UTIL_WeaponTimeBase() + 0.2;
   }
   return fDidHit;
}

Вроде все, УФ. Код готов. Теперь открываем файл weapons.cpp, и добавляем следующее в районе 329 строки, сразу после crowbar:

Code:

// knife
UTIL_PrecacheOtherWeapon( "weapon_knife" );//Прикрепляем нож к игре

Вы не запутаетесь, ибо здесь все сделано по аналогии с другими. Теперь юзаем weapons.h и в районе 80 строки ставим:

Code:

#define WEAPON_KNIFE 16 //Порядковый номер нашего оружия

Размещаем это сразу после снарков. Как видите здесь тоже все по аналогии. Теперь идем в самый конец файла. Пишем:

Code:

class CKnife : public CBasePlayerWeapon
{
   public: //Объявляем все действия, которые нож должен выполнять. Эти действия расположены в файле нашего ножа knife.cpp
   void Spawn( void );
   void Precache( void );
   int iItemSlot( void ) { return 1; }
   void EXPORT SwingAgain( void );
   void EXPORT Smack( void );
   int GetItemInfo(ItemInfo *p);

   void PrimaryAttack( void );
   int Swing( int fFirst );
   BOOL Deploy( void );
   void Holster( int skiplocal = 0 );
   int m_iSwing;
   TraceResult m_trHit;

   virtual BOOL UseDecrement( void )
   {
     #if defined( CLIENT_WEAPONS )
       return TRUE;
     #else
       return FALSE;
     #endif
   }
   private:
   unsigned short m_usKnife;
};

Размещаем это где угодно, главное не разорвать другие функции. Поидее серверная часть нашего оружия готова. Добавим еще несколько дополнений:

Давайте сделаем так, чтобы нож выдавался по консольной команде implse 101. Для этого открываем файл player.cpp и в районе 3461 (ужас да!) пишем

Code:

GiveNamedItem( "weapon_knife" );

Здесь вы тоже не запутаетесь, тк все по аналогии с другими пушками. Вот и все.

Теперь добавим нож в список респауна в разбиваемых объектах. Помните в хл, коробку разбиваем, а там патроны. :-) Для этого открываем файл func_break.cpp и в районе 60 строки

Code:

"weapon_knife",

Опять же все по аналогии с другими пушками, запутатся очень трудно. И последнее. Теперь добавим файл knife.cpp в файл hl.dsp. Для этого откроем последний в блокноте и в районе 338 добавим

Code:

SOURCE=.\knife.cpp
# End Source File
# Begin Source File

Ну вот серверная часть готова. Открываем файл hl.dsp и нажимаем в меню build > Set Active Configuration > Win32 - Relese > OK, затем клавишу F7. Все dll'ка скомпилина и лежит в папке dlls/relises_hl/hl.dll. Это все в папке с HL SDK.

Теперь откроем серверную часть. Это файл cl_dll.dsp в папке cl_dll, которая хранится в SDK. Сначало откроем файл hl_weapons.cpp и в нем в районе 67 строки после снарков пишем

Code:

CKnife g_Knife; //Объявляем класс ножа

Все как обычно элементарно и делается по аналогии. Теперь гоу в район 639 строки и так же по аналогии ставим

Code:

HUD_PrepEntity( &g_Knife , &player ); //Прорисовка худа

Опять же после снарков. Теперь в район 761 и после снарков вставляем

Code:

case WEAPON_KNIFE:
   pWeapon = &g_Knife;
   break;

Все как всегда по аналогии. А теперь вперед в ev_hldm.cpp и в районе 71 ставим так же, по аналогии, после снарков

Code:

void EV_KnifeFire( struct event_args_s *args );

ВСЕ!!! В смысле с этим файлом. Еще остались последние штрихи. Теперь в hl_events.cpp и в районе 40 и опсле снарком, по аналогии ставим

Code:

void EV_KnifeFire( struct event_args_s *args );

Теперь добавим файл knife.cpp в файл cl_dll.dsp. Для этого откроем последний в блокноте и врайоне 155 добавим

Code:

SOURCE=..\dlls\knife.cpp
# End Source File
# Begin Source File

Все я перекрестился, ФУ У. Все готово, и в тоже время не все. Ну вот клиент готов. Открываем файл cl_dll.dsp и нажимаем в меню build > Set Active Configuration > Win32 - Relese > OK, затем клавишу F7. Все dll'ка скомпилина и лежит в папке cl_dll/relises/client.dll. Это все в папке с HL SDK. Теперь получившиеся файлы ложим в hl.dll > dlls, client.dll > cl_dlls папки вашего мода. Еще осталось немного. В папке events вашего мода создайте файл knife.sc, тк наш нож во многом похож на монтажку, скопируйте в него содержимое файда crowbar.sc Вот наконец и все. Запускаем игру пишем impulse 101, любуемся ножом.

Если вы хотите создать карты для вашего мода с ножом, то добавьте следующее в ваш fgd файл, можно в самом конце

Code:

@PointClass base(Weapon, Targetx) studio("models/w_knife.mdl") = weapon_knife : "Knife" []

Если руки у вас растут от куда надо, то вы сможете забабахать у себя в моде ножик из OP4. А если еще и ум есть, то вообще любая фича, будьто из OP4, спирита, или даже CS будет у вас в моде. Также как это сделал я. Главное немного терпения и снаровки, а остальное приложится.

Большое спасибо: Сайту zzero.fatal.ru - за исходники OP4 Mitoh - за тутор под названием Создание нового оружия Valve - за игру HL




Similar1. weapon_flamethrower - Играя в Халф-Лайф, вы не задумывались над тем, что в нем чего-то не хватает? Чего-то очень близкого, родного, горячего...
2. Смена моделей персонажей - Смена моделей персонажей прямо в Хамере
3. Quake strafing & DoD bobing styles - Вот от нечего делать я решил немножко изменить стиль игры в оригинальной хл.
Ссылки на объект
Полная ссылка на текущем языке :
Короткая ссылка :
Ссылка на превью-картинку :
Ссылка на картинку в полном размере :
Ссылка для вашего форума или сайта
BB код ссылка:
BB код ссылка с картинкой :
BB код картинки :
HTML код ссылка:
HTML код ссылка с картинкой :
HTML код картинки :
You cannot comment, because you are not registered.
    Рождественский пак By TeMM!)))0
    Sven Co-opРождественский пак By TeMM!)))0
    Motoko Kunasagi (GitS FA SACO)
    Resident Evil 6Motoko Kunasagi (GitS FA SACO)
    Ada Wong Hot Replacement
    Ada Wong Hot Replacement
    Ada Wong Joins The Evening Express (v.2.0)
    Ada Wong Joins The Evening Express (v.2.0)