HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- Флуд (https://hlfx.ru/forum/forumdisplay.php?forumid=11)
-- Выражения в качестве значений полей в энтитях (https://hlfx.ru/forum/showthread.php?threadid=3858)
Отправлено XaeroX 24-03-2013 в 12:36:
Цитата:
FiEctro писал:
Ты всерьёз веришь что кто то бросится изучать кастомную ВМ?
Верю. Там очень похоже на обычный хл. 
Только проще.
Отправлено Ku2zoff 24-03-2013 в 13:02:
Цитата:
XaeroX писал:
Только проще.
Если не затруднит, приведи пример FireBulletsPlayer из ВМ. Мне интересно, насколько это проще, потому что мапперы в большинстве своём хотят нечто вроде "Press "E" to make custom entity". А я уверен, что кодинг в ВМ будет не настолько элементарным.
Отправлено XaeroX 24-03-2013 в 14:11:
Цитата:
Ku2zoff писал:
Если не затруднит, приведи пример FireBulletsPlayer из ВМ.
Этого пока нет, но могу привести в пример код env_spark.
Проще тут то, что а) нет поганых классов, б) не надо думать о сейвресторе (у svEntity_t есть массив persistant, который сохраняется, и local, который не сохраняется), в) можно гибко настраивать любые функции по указателям (хотя в сейв, как и в халфе, пишутся только Think, Touch, Blocked и Use).
C++ Source Code:
1 | #define m_flDelay pers.fValue1 |
3 | EXPORT void CMiscSparks_SparkThink( svEntity_t *self ); |
4 | EXPORT void CMiscSparks_SparkStop( svEntity_t *self, svEntity_t *pActivator, svEntity_t *pCaller, USE_TYPE useType, float value ); |
5 | EXPORT void CMiscSparks_SparkStart( svEntity_t *self, svEntity_t *pActivator, svEntity_t *pCaller, USE_TYPE useType, float value ); |
7 | void CMiscSparks_DoSpark( svEntity_t *self ) |
11 | MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, self->pev->origin, NULL ); |
12 | WRITE_BYTE( TE_SPARKS ); |
13 | WRITE_COORD( self->pev->origin[0] ); |
14 | WRITE_COORD( self->pev->origin[1] ); |
15 | WRITE_COORD( self->pev->origin[2] ); |
18 | flVolume = RANDOM_FLOAT( 0.1f, 0.3f ); /* random volume range */ |
19 | switch ( RANDOM_LONG( 0, 5 ) ) { |
20 | case 0: EMIT_SOUND( self, CHAN_VOICE, "buttons/spark1.wav", flVolume, ATTN_NORM ); break; |
21 | case 1: EMIT_SOUND( self, CHAN_VOICE, "buttons/spark2.wav", flVolume, ATTN_NORM ); break; |
22 | case 2: EMIT_SOUND( self, CHAN_VOICE, "buttons/spark3.wav", flVolume, ATTN_NORM ); break; |
23 | case 3: EMIT_SOUND( self, CHAN_VOICE, "buttons/spark4.wav", flVolume, ATTN_NORM ); break; |
24 | case 4: EMIT_SOUND( self, CHAN_VOICE, "buttons/spark5.wav", flVolume, ATTN_NORM ); break; |
25 | case 5: EMIT_SOUND( self, CHAN_VOICE, "buttons/spark6.wav", flVolume, ATTN_NORM ); break; |
28 | self->pev->nextthink = gpGlobals->time + 0.1f + RANDOM_FLOAT( 0, self->m_flDelay ); |
31 | void CMiscSparks_SparkThink( svEntity_t *self ) |
33 | self->pev->nextthink = gpGlobals->time + 0.1f + RANDOM_FLOAT( 0, self->m_flDelay ); |
34 | CMiscSparks_DoSpark( self ); |
37 | void CMiscSparks_SparkStop( svEntity_t *self, svEntity_t *pActivator, svEntity_t *pCaller, USE_TYPE useType, float value ) |
39 | SetUse( self, CMiscSparks_SparkStart ); |
40 | SetThink( self, NULL ); |
43 | void CMiscSparks_SparkStart( svEntity_t *self, svEntity_t *pActivator, svEntity_t *pCaller, USE_TYPE useType, float value ) |
45 | SetUse( self, CMiscSparks_SparkStop ); |
46 | SetThink( self, CMiscSparks_SparkThink ); |
47 | self->pev->nextthink = gpGlobals->time + 0.1f + RANDOM_FLOAT( 0, self->m_flDelay ); |
50 | static void CMiscSparks_Spawn( svEntity_t *self ) |
52 | self->caps &= ~FCAP_ACROSS_TRANSITION; |
53 | self->pev->nextthink = gpGlobals->time + ( 0.1f + RANDOM_FLOAT( 0, 1.5f ) ); |
55 | if ( FBitSet( self->pev->spawnflags, 32 ) ) /* Use for on/off */ |
57 | if ( FBitSet( self->pev->spawnflags, 64 ) ) /* Start on */ |
59 | SetThink( self, CMiscSparks_SparkThink ); /* start sparking */ |
60 | SetUse( self, CMiscSparks_SparkStop ); /* set up +USE to stop sparking */ |
63 | SetUse( self, CMiscSparks_SparkStart ); |
66 | SetThink( self, CMiscSparks_SparkThink ); |
69 | if ( self->m_flDelay <= 0 ) |
70 | self->m_flDelay = 1.5f; |
73 | static void CMiscSparks_Precache( svEntity_t *self ) |
75 | PRECACHE_SOUND( "buttons/spark1.wav" ); |
76 | PRECACHE_SOUND( "buttons/spark2.wav" ); |
77 | PRECACHE_SOUND( "buttons/spark3.wav" ); |
78 | PRECACHE_SOUND( "buttons/spark4.wav" ); |
79 | PRECACHE_SOUND( "buttons/spark5.wav" ); |
80 | PRECACHE_SOUND( "buttons/spark6.wav" ); |
83 | static void CMiscSparks_KeyValue( svEntity_t *self, KeyValueData *pkvd ) |
85 | if ( FStrEq( pkvd->szKeyName, "MaxDelay" ) ) { |
86 | self->m_flDelay = atof(pkvd->szValue); |
87 | pkvd->fHandled = TRUE; |
91 | void misc_sparks( svEntity_t *self ) |
93 | self->type = ETYPE_BASEENTITY; |
94 | self->vtbl.Spawn = (func_t)CMiscSparks_Spawn; |
95 | self->vtbl.Precache = (func_t)CMiscSparks_Precache; |
96 | self->vtbl.KeyValue = (func_t)CMiscSparks_KeyValue; |
Добавлено 24-03-2013 в 21:08:
Эта энтитя, misc_sparks, как раз и написана мной в качестве демонстрации.
Потом будут ещё демо-монстр и демо-оружие.
А дальнейшее расширение возможностей виртуальной машинки (там много куда расшириться можно) отложим до HLFX 0.8 beta.
Добавлено 24-03-2013 в 21:11:
Цитата:
Ku2zoff писал:
потому что мапперы в большинстве своём хотят нечто вроде "Press "E" to make custom entity"
Для работы с выражениями достаточно освоить простенький триггер: на входе энтитя1 и энтитя2, на выходе суперпозиция каких-либо их параметров.
В принципе, заготовку такой энтити я тоже могу сделать в качестве демонстрации.
Отправлено Ku2zoff 24-03-2013 в 14:29:
Цитата:
XaeroX писал:
а) нет поганых классов
Будет немного непривычно, хотя если кто-то кодил под вторую и третью кваку освоятся быстрее. Насчёт удобности не знаю, насчёт сложности - да, это проще.
Цитата:
XaeroX писал:
б) не надо думать о сейвресторе
Хм, ну это тоже полезно. Мне интересно, почему валвэ в дллках сделали именно выборочное сохранение каких-либо переменных и параметров в сейв. Чтобы сэкономить память и уменьшить время загрузки/сохранения?
Цитата:
XaeroX писал:
в) можно гибко настраивать любые функции по указателям
С этим у меня туговато
т.к. не очень силён в C как таковом, но примерно представляю. В коде дллок бывает иногда довольно проблематично "выцепить" какую-либо функцию для своих нужд. Бесит работа с CBasePlayerItem вместо CBasePlayerWeapon, например.
Отправлено XaeroX 24-03-2013 в 14:42:
Цитата:
Ku2zoff писал:
Мне интересно, почему валвэ в дллках сделали именно выборочное сохранение каких-либо переменных и параметров в сейв. Чтобы сэкономить память и уменьшить время загрузки/сохранения?
Экономия памяти, да.
Массив одного размера на все энтити - это удобно, но многие энтити не юзают все поля, и размер сейва вырастает. В этом примере с искрами юзается один-единственный флоат из всего persistant. Возможно, позже я предусмотрю в ВМ возможность выборочной записи персистантов в сейв, но пока пишется массив целиком.
Цитата:
Ku2zoff писал:
В коде дллок бывает иногда довольно проблематично "выцепить" какую-либо функцию для своих нужд.
В этом и заключается главный минус классов - ходьба по иерархии, пока не поймёшь, какая именно виртуальная функция вызывается. А здесь - ты заполняешь vtbl вручную и имеешь чёткое понимание, что, когда и как. Ну и наследование в каком-то виде можно через этот vtbl реализовать.
Добавлено 24-03-2013 в 21:42:
Цитата:
Ku2zoff писал:
Будет немного непривычно
Да ты присмотрись...
В халфе ты писал:
C++ Source Code:
void CMiscSparks::SparkThink( void ) |
а тут будешь писать:
C++ Source Code:
void CMiscSparks_SparkThink( svEntity_t *self ) |
Разве большое отличие?
Ну и self-> надо везде писать, но и в халфе можно писать this->, просто там это опционально, а тут - обязательно.
Есть ещё кое-какие отличия в движковых функциях, в основном связанные с тем, что ВМ безопасна (в частности, не имеет доступа ни к каким указателям за пределами своего внутреннего адресного пространства), но это тонкости, которые коснутся далеко не всех.
Отправлено Ku2zoff 24-03-2013 в 14:44:
А не слишком ли это, не утруждать товарищей заботой о сейв-ресторе? Ну в самом деле, вдруг у них потом возникнет необходимость кодить по-обычному, и начнутся проблемы типа "с моего пистолета пропадает глушитель" или "а почему после загрузки у игрока стамина 100%"?
Добавлено 24-03-2013 в 21:44:
Цитата:
XaeroX писал:
ВМ безопасна (в частности, не имеет доступа ни к каким указателям за пределами своего внутреннего адресного пространства)
Ну хоть крэшиться ничего не будет
Отправлено XaeroX 24-03-2013 в 14:45:
Цитата:
Ku2zoff писал:
А не слишком ли это, не утруждать товарищей заботой о сейв-ресторе? Ну в самом деле, вдруг у них потом возникнет необходимость кодить по-обычному, и начнутся проблемы типа "с моего пистолета пропадает глушитель" или "а почему после загрузки у игрока стамина 100%"?
Зачем человеку, который однажды перешёл на HLFX в целом и его ВМ в частности, начинать кодить "по-обычному"? HLFX - его надёжный товарищ, который берёт на себя большую часть забот. Конечно, возможности ВМ не безграничны и, вероятно, кому-то их не хватит - но этот кто-то, вероятно, и сам хлфх свой написать сможет, логично?
Отправлено Ku2zoff 24-03-2013 в 14:49:
Цитата:
XaeroX писал:
и, вероятно, кому-то их не хватит - но этот кто-то, вероятно, и сам хлфх свой написать сможет, логично?
Встречаются особые индивидуумы, которые эта, попробуют что-то, а потом хотят упереть код из этого чего-то в что-то другое или наоборот. Как быть с такими?
Отправлено XaeroX 24-03-2013 в 14:50:
Цитата:
Ku2zoff писал:
Ну хоть крэшиться ничего не будет
Ну почему же не будет? Внутри адресного пространства можно натворить всякого.
Но это особенность языка Си, иначе никак. Хотите арифметику указателей и все связанные с ней бонусы - получайте и потенциальную возможность креша.
А вот взломать OpenGL из-под DirectX с помощью GDI в ВМ действительно будет невозможно. Или, скажем, написать эксплоит с переполнением какого-нибудь движкового буфера.
Добавлено 24-03-2013 в 21:50:
Цитата:
Ku2zoff писал:
а потом хотят упереть код из этого чего-то в что-то другое или наоборот. Как быть с такими?
Им всё равно придётся думать о сейве. В частности, решать, где хранить переменную - в персистанте или в локале. Эдакое концептуальное решение. А при переводе кода на халфу просто надо будет записать в сейв всё, что хранил в персистанте в ВМ. Не так уж сложно.
Отправлено FiEctro 24-03-2013 в 14:52:
XaeroX
Примеры это очень хорошо. Такие вещи как позиция элементов худа, отключение старых пушек и монстров (для мода с полностью кастомными пушками и монстрами) - машинка может прожевать?
__________________
У котёнка мокрый нос и гладенькая шерсть, у него забавный хвост и быстрых лапок шесть. Две задних, две средних и две передних лапы, такая многоножка получилася у папы.
Он ученый — папа мой — зверушек изучает, гуляет по помойкам, ловит крыс и чаек. Две крысы белокрылые и чайки две унылые покрытые пупырчатою кожей лягушат без пёрышек тоскуют и ускакать спешат.
А ещё есть муравей большой размером с гуся он пугает всех зверей, и я его боюся, когда он ковыляет на лапках на своих.
И в двери ударяет, и начинает стих: Я — муравей, воды налей! Не меньше ведра, напиться мне пора!
Отправлено Ku2zoff 24-03-2013 в 15:01:
Цитата:
FiEctro писал:
отключение старых пушек
Так-то это не нужно, главное не давать игроку эти пушки. Разве что для экономии памяти. Цитата:
FiEctro писал:
Такие вещи как позиция элементов худа
Худ же целиком весь будет в машинке, какие примеры? Меняй не хочу. Другое дело, если автор мода захочет прикрутить что-нибудь особое, например ВГУИ-менюшки для каких-л. нужд.
Добавлено 24-03-2013 в 22:01:
XaeroX а как насчёт модельрендерера? Я понимаю, что целиком его вытаскивать в ВМ - занятие неблагодарное, но будет ли возможность аттачить произвольные модели к игроку/монстрам и прочему посредством StudioMergeBones? И возможность выбора 2-way\9-way блендинга для особо упоротых, желающих сделать клон КаЭс?
Отправлено FiEctro 24-03-2013 в 15:02:
>> Так-то это не нужно, главное не давать игроку эти пушки.
Хотя бы из импульс 101 вычеркнуть.
__________________
У котёнка мокрый нос и гладенькая шерсть, у него забавный хвост и быстрых лапок шесть. Две задних, две средних и две передних лапы, такая многоножка получилася у папы.
Он ученый — папа мой — зверушек изучает, гуляет по помойкам, ловит крыс и чаек. Две крысы белокрылые и чайки две унылые покрытые пупырчатою кожей лягушат без пёрышек тоскуют и ускакать спешат.
А ещё есть муравей большой размером с гуся он пугает всех зверей, и я его боюся, когда он ковыляет на лапках на своих.
И в двери ударяет, и начинает стих: Я — муравей, воды налей! Не меньше ведра, напиться мне пора!
Отправлено Ku2zoff 24-03-2013 в 15:06:
Цитата:
FiEctro писал:
Хотя бы из импульс 101 вычеркнуть.
Это ж читерская команда, если хотят играть нормально - не используют её. Вон, в опфоре все халфовские стволы на месте, ничего не вырезано. ЕМНИП, не все из них можно получить в игре.
Отправлено XaeroX 24-03-2013 в 15:25:
Цитата:
FiEctro писал:
Такие вещи как позиция элементов худа
Я собираюсь весь худ вынести в клиентскую ВМ.
Цитата:
FiEctro писал:
отключение старых пушек и монстров
Зачем отключать, если можно просто не ставить эти энтити на карту, как правильно написал Ku2zoff?
Цитата:
Ku2zoff писал:
например ВГУИ-менюшки
С вгуи я ещё не придумал и в версии 0.7 вряд ли буду заморачиваться, но вообще - можно и поддержку вгуи в машинке сделать подобно серверным псевдоклассам.
Цитата:
Ku2zoff писал:
а как насчёт модельрендерера?
У хлфх свой как бы.
Цитата:
Ku2zoff писал:
И возможность выбора 2-way\9-way блендинга для особо упоротых, желающих сделать клон КаЭс?
Проще добавить этот 9-вей в хлфх. Да хотя бы из волатилы скопипастить.
Цитата:
FiEctro писал:
Хотя бы из импульс 101 вычеркнуть.
Импульс 101 можно в ВМ перенести, это не проблема.
Отправлено Government-Man 24-03-2013 в 21:20:
Цитата:
XaeroX писал:
А вот взломать OpenGL из-под DirectX с помощью GDI в ВМ действительно будет невозможно. Или, скажем, написать эксплоит с переполнением какого-нибудь движкового буфера.
Много ли существует зловредных модов, переполняющих движковые буферы и взламывающих графические АПИ?