Суббота, 23.11.2024, 15:33

Беспроводной датчик протечки воды цена.
logo

Пользовательский поиск

Меню сайта
Категории раздела
Разное [15]
Tutorials
Создание карт [13]
Создание моделей [2]
Кодинг [14]
Создание карт CS [197]
Учебник cs-mapper
Свойства entity HL-CS [117]
Форма входа
Наш сервер CS 1.6
Поиск
Наш опрос
Оцените мой сайт
Всего ответов: 167
Друзья сайта


Главная » Статьи » HL Development » Кодинг


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

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

Никогда не задумывались , почему в хев костюме идет сразу же фонарик ? Ну кончено же - это специальный навороченный костюм со всеми прибамбасами и тд. А если ,положем, нет фонарика в комплекте ? Может сделать так, чтобы его нужно было отдельно подбирать , чтобы затем было легче в различных вентиляциях и тд? Чтож ,задумка вполне неплохая и вот ее реализация:

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

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

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 и добавьте в каждый следующую строку

#define WEAPON_FLASHLIGHT 30

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

#define WEAPON_SUIT 31

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

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

UTIL_PrecacheOther( "item_flashlight" );

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

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

case 101

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

GiveNamedItem( "item_flashlight" );

после строки GiveNamedItem( "item_suit" );

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

Откройте снова player.cpp, а если вы его не закрывали, то это еще лучше и найдите там строку FlashlightTurnOn немного ниже вы найдете строку:

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

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

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

CHudFlashlight::Draw

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

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

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

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

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

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

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 добавим булевскую переменную:

extern BOOL g_startFlashlight;

откроем файл gamerules.cpp, найдем строку GetPlayerSpawnSpot и перед строкой return pentSpawnSpot; добавим новую функцию:

if (pentSpawnSpot->v.spawnflags & 2)
{
g_startFlashlight = TRUE;//
}

Cпаунфлаг равен 2 для совместимости со спиритом.Теперь откроем файл single_playgamerules.cpp и найдем в нем строку PlayerSpawn и после строки

CBaseEntity *pWeaponEntity = NULL;

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

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

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

BOOL g_startFlashlight;

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

Дополнение 2

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

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

// Update Flashlight

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

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

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

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 и ищем строку:

#define FLASH_DRAIN_TIME 1.2

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

Теперь создадим собсно, саму батарейку, для чего откроем items.cpp в самом верху файла, рядом с extern int gmsgItemPickup; добавим еще одну строку extern int gmsgFlashBattery; это нам нужно, для обновления иконки заряда фонарика (для передачи данных в клиент). Теперь у нас - два пути - либо сделать так, чтобы обычная батарейка заряжала фонарь совместно с костюмом, либо сделать отдельную батарейку для фонаря, первый способ проще, но в игровом плане дает меньше гибкости, хотя тогда его можно применять и в обычном ХЛ. Итак способ 1 - общая батарейка. Найдите комментарий

// Suit reports new power level

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

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;
}
}
else
return FALSE;

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

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

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

// ================================================== ======
// 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 и добавьте куда-нибудь к остальным строкам GiveNamedItem( "item_flashlight_battery" ); Теперь займемся прекэшингом - откроем weapons.cpp и найдем функцию W_Precache добавим туда строку

UTIL_PrecacheOther( "item_flashlight_battery" );

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

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

... и так далее, в самом низу добавьте

"item_flashlight"//22
"item_flashlight_battery" //23
Соответственно, вызвать предметы можно будет поставив в поле spawnobject
22 - для фонаря, 23 - для его батарейки.
На этом все, код fgd, для вашего любимого хаммера напишете сами, ибо кварк умеет такие вещи делать автоматически :)(g-cont ничего кроме кварка не признает :) прим. Mitoh)
Отсюда можно скачать зип файл с моделью фонарика , спрайтом и тд.

Категория: Кодинг | Добавил: SuperStart (18.10.2010)
Просмотров: 3023 | Рейтинг: 1.0/1 |



Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

Copyright www.akksimo.net © 2024