Регистрация - или - Войти

Восстановить пароль
×

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

Логин или почта :

Dead SectorDead Sector

На одном острове возле Британии распространился вирус зомби, превратив всех живущих на нем в ходячих мертвецов....

12/12/2004
Статистика ( общая по моделям ), шт.

Подбираемый фонарик v 2.5


  • Описание
  • КАК УСТАНОВИТЬ

Подбираемый фонарик v 2.5

Подбираемый фонарик v 2.5


Автор / ы урока : Дядя Миша
Просмотров : 2180 ( +2 )
Прислал / (а) : Streit
Дата создания : 07.04.2011 21:00:34
Источник : http://www.half-life.ru/forum
Рейтинг :
 ( 5 ) 
Поделиться :


Имеются следующие переводы : | русский |

Ниже представлен код подбираемого фонарика, код разработан BUzer, дополнения и поправки - мои (G-Cont).

Для начала сделаем саму подбираемую ентитю. Для этого откроем items.cpp и внесем туда код нового предмета - item_flashlight (можно в конец файла).

Code:

class CItemFlashlight : public CItem
{
   void Spawn( void )
   {
     Precache( );
     SET_MODEL(ENT(pev), "models/w_flashlight.mdl");
     CItem::Spawn( );
   }

   void Precache( void )
   {
     PRECACHE_MODEL ("models/w_flashlight.mdl");
     PRECACHE_SOUND( "items/gunpickup2.wav" );
   }

   BOOL MyTouch( CBasePlayer *pPlayer )
   {
     if ( pPlayer->pev->weapons & (1<<WEAPON_FLASHLIGHT) )
       return FALSE;

     pPlayer->pev->weapons |= (1<<WEAPON_FLASHLIGHT);

     MESSAGE_BEGIN( MSG_ONE, gmsgItemPickup, NULL, pPlayer->pev );
     WRITE_STRING( STRING(pev->classname) );
     MESSAGE_END();

     EMIT_SOUND_SUIT( pPlayer->edict(), "items/gunpickup2.wav" );

     return TRUE;
   }
};

LINK_ENTITY_TO_CLASS(item_flashlight, CItemFlashlight);

Теперь нам нужно задекларировать переменную weapon_flashlight в системе

Для этого откройте weapons.h и cdll_dll.h и добавьте в каждый следующую строку

Code:

#define WEAPON_FLASHLIGHT 30

добавлять переменную в cdll_dll.h нужно для того, что бы она была задекларирована и в client.dll - что нужно для отключения прорисовки фонарика. Добавлять строку нужно (в обоих файлах) перед строкой

Code:

#define WEAPON_SUIT 31

Эта строка встречается в каждом файле по одному разу.

Теперь нам нужно прекэшировать фонарик, как предмет, если мы например захотим получить его из консоли, набрав команду give item_flashlight Если этого не сделать - игра вывалиться с ошибкой прекэшинга. Итак откроем weapons.cpp и найдем функцию W_Precache добавим туда строку

Code:

UTIL_PrecacheOther( "item_flashlight" );

Добавлять строку нужно после строки

Code:

UTIL_PrecacheOther( "item_longjump" );

Ну и давайте тогда уж сделаем, чтобы фонарик можно было получить по стандартной "читерской" команде impulse 101

Для этого откройте player.cpp и найдите в нем строку

Code:

case 101

и добавьте ниже строку

Code:

GiveNamedItem( "item_flashlight" );

после строки

Code:

GiveNamedItem( "item_suit" );

Итак, фонарик как предмет у нас уже есть и мы даже можем его подбирать Однако толку от него пока мало, так если вы скомпилируете вышеприведенный код, то с удивлением обнаружите, что, хотя фонарик и можно подбирать, но от него ничего не зависит и функция прорисовки фонарика и его отключение по прежнему зависят от наличия костюма, но не фонарика Давайте исправим данный баг. Откройте снова player.cpp, а если вы его не закрывали, то это еще лучше и найдите там строку FlashlightTurnOn немного ниже вы найдете строку

Code:

if ( (pev->weapons & (1<<WEAPON_SUIT)) )

замените в ней WEAPON_SUIT на WEAPON_FLASHLIGHT

Теперь фонарик будет невозможно включить если у вас его нету Однако его спрайт в правом верхнем углу экрана все равно будет рисоваться как при наличии фонарика так и при отсутствии оного, что не есть хорошо, будем фиксить и этот баг. Откройте папку cl_dll и найдите там файл flashlight.cpp. откройте этот файл и найдите в нем строку

Code:

CHudFlashlight::Draw

затем найдите, чуть ниже строку

Code:

if (!(gHUD.m_iWeaponBits & (1<<(WEAPON_SUIT)) ))

ее нужно заменить на

Code:

if (!(gHUD.m_iWeaponBits & (1<<(WEAPON_SUIT)) && (gHUD.m_iWeaponBits & (1<<(WEAPON_FLASHLIGHT)) )))

Теперь спрайт фонарика будет отрисовываться при соблюдении двух условий - при наличии собственно фонарика и при наличии костюма.

Чтобы фонарик отрисовывался при его поднятии нужно нарисовать его картинку и запихнуть в спрайт с названием 640hud2. Фонарик для разрешения 320 рисовать необязательно, поскольку при таком разрешении практически никто не играет. Однако если вы всеже надумаете это сделать, то его удобно будет запихнуть в спрайт 320hud2. В hud.txt нам будет нужно добавить две строки - для разрешения 320 х 200 и 640 х 480 соответственно.

Code:

item_flashlight 320 320hud2 68 72 20 20
item_flashlight 640 640hud2 176 144 44 44

куда их дописывать - я думаю сообразите в начале файла hud.txt будет прописано некое число, после добавления двух вышеприведенных строк это число нужно будет увеличить на 2, т.е. если было прописано 125 вам нужно будет прописать 127. Для самых ленивых моделька и спрайты выложены в архиве внизу. Что бы добавить фонарик на карту создайте точечную ентитю item_flashlight.

Дополнение 1:

Можно сделать так, чтобы фонарик автоматически появлялся у игрока при старте карты для этого допишем следующий код: в cbase.h добавим булевскую переменную

Code:

extern BOOL g_startFlashlight;

откроем файл gamerules.cpp, найдем строку GetPlayerSpawnSpot и перед строкой

Code:

return pentSpawnSpot;

добавим новую функцию

Code:

if (pentSpawnSpot->v.spawnflags & 2) //Спаунфлаг равен 2 для совместимости со спиритом
{
   g_startFlashlight = TRUE;//если вы подобные извращения производите в нем
}

Теперь откроем файл singleplay_gamerules.cpp и найдем в нем строку PlayerSpawn и после строки

Code:

CBaseEntity *pWeaponEntity = NULL;

добавим код, который присваивает переменной WEAPON_FLASHLIGHT значение TRUE по умолчанию.

Code:

if (g_startFlashlight)
   pPlayer->pev->weapons |= (1<<WEAPON_FLASHLIGHT);

в world.cpp перед функциями worldspawn (там где перечислены спаунфлаги) нужно будет добавить

Code:

BOOL g_startFlashlight;

Ну вот собственно и все, проставьте у info_player_start параметр spawnflags 2 и вы увидите, что фонарик появляется у вас при загрузке карты (даже если костюма на вас нету).

Дополнение 2: [new]

Фонарик заряжаемый от батарей. Согласитесь, что самозаряжающийся фонарик - это несколько неестественно Давайте сделаем так, чтобы фонарик зраяжался от батарей, подобно костюму, (тут возможны два варианта: либо фонарик заряжается от основных батарей, либо от своих, особых батарей, я подробно рассмотрю оба варианта).

Для начала давайте сделаем, чтобы фонарик не самоподзаряжался. Для этого откройте Player.CPP, найдите UpdateClientData и в этой функции найдите Code:

// Update Flashlight

удалите (или просто закомментируйте) вот эту часть кода

Code:

if (m_iFlashBattery < 100)
{
   m_flFlashLightTime = FLASH_CHARGE_TIME + gpGlobals->time;
   ALERT( at_console, "battery is charged\n" );
   m_iFlashBattery++;
}
else

Теперь давайте сделаем, чтобы фонарик невозможно было включить, если он полностью разряжен (вы будете удивлены, но если отключить подзарядку, то фонарик продолжает преспокойно гореть, даже когда весь заряд вышел). Для этого найдем функцию (выше UpdateClientData)

Code:

void CBasePlayer :: FlashlightTurnOn

и добавим в ней, в самом верху следующий код

Code:

if (m_iFlashBattery == 0)//g-cont
{
   EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, SOUND_FLASHLIGHT_ON, 1.0, ATTN_NORM, 0, PITCH_NORM );//Clik, clik, a tolky = 0
  return;
}

строка EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON… нужна для большей реалистичности - так как кликать можно и разряженным фонариком. Теперь мы увеличим время разрядки фонарика (в стандартном режиме он разряжается за 3 минуты), согласитесь, было бы нечестно, если бы фонарик, без подзарядки разряжался за те же три минуты в жизни, а впереди - километры вентиляций со злобными хедкрабами Сделать это очень легко - переходим в самый верх player.cpp и ищем строку

Code:

#define FLASH_DRAIN_TIME 1.2

и замените в ней 1.2 на большее значение, например на 15 - это даст примерно полчаса работы фонаря без подзарядки, что довольно реалистично, и заставляет игрока экономить ставший драгоценным теперь свет .

Теперь создадим собсно, саму батарейку, для чего откроем items.cpp в самом верху файла, рядом с

Code:

extern int gmsgItemPickup;

добавим еще одну строку

Code:

extern int gmsgFlashBattery;

это нам нужно, для обновления иконки заряда фонарика (для передачи данных в клиент). Теперь у нас - два пути - либо сделать так, чтобы обычная батарейка заряжала фонарь совместно с костюмом, либо сделать отдельную батарейку для фонаря, первый способ проще, но в игровом плане дает меньше гибкости, хотя тогда его можно применять и в обычном ХЛ.

Итак способ 1 - общая батарейка. Найдите комментарий

Code:

// Suit reports new power level

и перед ним добавьте следующий код.

Code:

if (pPlayer->m_iFlashBattery < 100)
{
   pPlayer->m_iFlashBattery = pPlayer->m_iFlashBattery + 20;
   // ALERT( at_console, "flashlight is charged\n");

   if (pPlayer->m_iFlashBattery > 100)
   {
     pPlayer->m_iFlashBattery = 100;
   }

}

MESSAGE_BEGIN( MSG_ONE, gmsgFlashBattery, NULL, pPlayer->pev );
WRITE_BYTE(pPlayer->m_iFlashBattery);
MESSAGE_END();

Все, теперь обычная батарейка будет подзаряжать и заодно и фонарик.

Способ 2 - отдельная батарейка для фонаря (разумеется оба способа можно использовать вместе). Опустимся в конец файла items.cpp и добавим следующий код.

Code:

//========================================================
// Battery for charger flashlight
// Copyright 2004 Shambler Team
// All Rights Reserved
//========================================================

class CItemFlashBattery : public CItem
{
   void Spawn( void )
   {
     Precache( );
     SET_MODEL(ENT(pev), "models/w_battery.mdl");
     CItem::Spawn( );
   }

   void Precache( void )
   {
     PRECACHE_MODEL ("models/w_battery.mdl");
     PRECACHE_SOUND( "items/gunpickup2.wav" );
   }

   BOOL MyTouch( CBasePlayer *pPlayer )
   {
     if ( pPlayer->pev->deadflag != DEAD_NO )
     {
       return FALSE;
     }

     if (pPlayer->m_iFlashBattery >= 99)
     {
       return FALSE;
     }

     if ( ( pPlayer->pev->weapons & (1<<WEAPON_FLASHLIGHT) ) )
     {
       if (pPlayer->m_iFlashBattery < 100)
       {
         pPlayer->m_iFlashBattery = pPlayer->m_iFlashBattery + 20;
         // ALERT( at_console, "battery is charged\n");
       }
       else
         return FALSE;

       MESSAGE_BEGIN( MSG_ONE, gmsgFlashBattery, NULL, pPlayer->pev );
       WRITE_BYTE(pPlayer->m_iFlashBattery);
       MESSAGE_END();

       EMIT_SOUND( pPlayer->edict(), CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM );

       MESSAGE_BEGIN( MSG_ONE, gmsgItemPickup, NULL, pPlayer->pev );
       WRITE_STRING( STRING(pev->classname) );
       MESSAGE_END();

       return TRUE;
     }
     return FALSE;
   }
};

LINK_ENTITY_TO_CLASS( item_flashlight_battery, CItemFlashBattery );

Модель - обычная батарейка, но разумеется можно заюзать свою, изменив к ней путь. Если вы вдруг решили заюзать второе дополнение, без вставления кода самого подбираемого фонаря (а это также возможно), то замените WEAPON_FLASHLIGHT на WEAPON_SUIT в выше приведенном коде. Данную батарейку невозможно взять, если у вас нету фонарика, или если его заряд полон. Почти что все, теперь нам нужно сделать, чтобы батарейку для фонаря мы могли получить по стандартной читерской команде, по give и могли проставить ее в спаун разбиваемого ящика. Откроем многострадальный Player.cpp и найдем строку case 101 и добавьте куда-нибудь к остальным строкам

Code:

GiveNamedItem( "item_flashlight_battery" );

Теперь займемся прекэшингом - откроем weapons.cpp и найдем функцию W_Precache добавим туда строку

Code:

UTIL_PrecacheOther( "item_flashlight_battery" );

Остался последний штрих - добавить фонарик с батарейкой в func_pushable и func_breakable Откройте func_break.cpp и в самом верху, где идет перечисление предметов

Code:

const char *CBreakable::pSpawnObjects[] =
{
   NULL, // 0
   "item_battery", // 1
   "item_healthkit", // 2
   "weapon_9mmhandgun",// 3
   "ammo_9mmclip", // 4
   "weapon_9mmAR", // 5
   "ammo_9mmAR", // 6
   "ammo_ARgrenades", // 7
   "weapon_shotgun", // 8
   "ammo_buckshot", // 9
   "weapon_crossbow", // 10
  1. и так далее, в самом низу добавьте

Code:

"item_flashlight" //22
"item_flashlight_battery" //23

Соответственно, вызвать предметы можно будет поставив в поле spawnobject 22 - для фонаря, 23 - для его батарейки. На этом все, код fgd, для вашего любимого хаммера напишете сами, ибо кварк умеет такие вещи делать автоматически



Похожие1. Динамическое освещение - этой статье будет описан способ добавления динамических вспышек света, которые можно использовать для еффекта молнии
2. Мазлфлэш на брашах - Мазлфлэш на брашах
3. Как сделать старый 640 худ из 2560/1280 нового худа - сидел, думал как вернуть старые времена, додумал
nikkyhika 02.11.2024, 11:02:07 пишет :
#1
ладно, это круто
Вы не можете комментировать, т.к. вы не зарегистрированы.
    зимнее дерево
    Half-Lifeзимнее дерево
    [old model] CoF Simon
    Half-Life[old model] CoF Simon
    Плюшевая Рей
    Half-LifeПлюшевая Рей
    зомби без хедкраба №2
    Half-Lifeзомби без хедкраба №2