The New Future :: FOnline, Half-life 2 :: Roleplay It!  

Вернуться   The New Future :: FOnline, Half-life 2 :: Roleplay It! > Прочее > FOmod > TNF

TNF сервер и частично документация

Ответ
 
Опции темы Опции просмотра
Старый 10.02.2015, 15:11   #1
PowerMagic
Lost Overseer
 
Аватар для PowerMagic
 
Специализация: ест детей.
Регистрация: 29.01.2010
Сообщений: 1,000
Вес репутации: 571
PowerMagic has a reputation beyond reputePowerMagic has a reputation beyond reputePowerMagic has a reputation beyond reputePowerMagic has a reputation beyond reputePowerMagic has a reputation beyond reputePowerMagic has a reputation beyond reputePowerMagic has a reputation beyond reputePowerMagic has a reputation beyond reputePowerMagic has a reputation beyond reputePowerMagic has a reputation beyond reputePowerMagic has a reputation beyond repute
По умолчанию [doc] Интерактивные обьекты


-----------------------
Лирической отступление
------------------------------------

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

-----------
Вступление
------------------


Весь код содержится в фаиле interactive_obj.fos (_interactive_groups.fos) и мало зависим от тнф-плюшек. Вполне подлежит портированию на другую версию сервера.

Для этого требуется :
- вызовы GEM(Global Event Manager) заменить на TimeEvent :
code 

- удалить вызовы следующих функций :
Код:
import void DropBleed( Critter& cr ) from "critter_status";
import void DropToxic( Critter& cr ) from "critter_status";

import void Prolonged_Doc ( Critter& targetCr, uint16 doctime, uint16 damage ) from "heal";
import void Prolonged_heal ( Critter& targetCr, uint16 sk ) from "heal";
Если кто-то возьмется за это - не поленитесь, выложите в этой ветке.


-------------------------------------------
Далее непосредственно про сами обьекты
----------------------------------------------------------


На данный момент существуют обьекты :

Код:
PID_OBJECT_WATERPUMP	водяная помпа
PID_OBJECT_WATTS	генератор
PID_OBJECT_AIRLOCK	воздухоочиститель
PID_OBJECT_DOC		автодок
PID_OBJECT_LIGHT	свет
PID_OBJECT_WINDMILL	ветряк
PID_OBJECT_SWITCHER	переключатель
PID_OBJECT_SAWMILL	лесопилка
PID_OBJECT_FOUNDRY	кузня
PID_OBJECT_WELL		колодец
Интерактивные обьекты представляют из себя обычные Item , с биндами функций-перехватчиков событий (ITEM_EVENT_USE_ON_ME, ITEM_EVENT_SKILL).
Данные хранятся в ANY_DATA и единожды парсятся из обьектов карты. Для этого требуется выполнить команду :
Код:
%interactive_obj cumoa_parse scriptSet
где scriptSet = 0\1 в зависимости от необходимости жестко задавать итемам имена Init-функций.

сами имена описанны в функции :
Код:
string GetScriptName(uint16 pid){
  string sScript = "interactive_obj@";

            switch(pid){
                case PID_OBJECT_AIRLOCK     : sScript+="AirLockInit"; break;
                case PID_OBJECT_WATTS       : sScript+="WattsInit"; break;
                case PID_OBJECT_WATERPUMP   : sScript+="WaterPumpInit"; break;
                case PID_OBJECT_DOC         : sScript+="DocInit"; break;
                case PID_OBJECT_LIGHT       : sScript+="LightInit"; break;
		case PID_OBJECT_SWITCHER    : sScript+="SwitcherInit"; break;
		case PID_OBJECT_WELL        : sScript+="WellInit"; break;
		case PID_OBJECT_SAWMILL     : sScript+="SawmillInit"; break;
		case PID_OBJECT_FOUNDRY     : sScript+="FoundaryInit"; break;
		case PID_OBJECT_WINDMILL    : sScript+="WindmillInit"; break;
                default                     : break;
            }
            
            return sScript;
}
собственно здесь видно что по прототипу идет сравнение. Это нужно для ситуаций, когда через маппер был установлен итем. При этом записи из его прототипа не проставлялись в обьект на карте. Сейчас вероятно, это уже исправили.

Для работы с обьектами используется класс CUMO (class Used Map Obj). Он имеет не много свойств, основная его задача хранить данные загруженные из ANY_DATA ( в первый раз данные подгружаются из Item::Val0-9). И хранятся в массиве CUMO::Val
вот их обозначения с комментариями :
Код:
#define CUMO_VAL_GENERATOR	(0)  //номер генератора, группировка и привязка обьектов к генератору с этим номером
#define CUMO_VAL_POWER		(1) //есть ли питание
#define CUMO_VAL_SWITCHER	(2) //вкл\выкл
#define CUMO_VAL_CHARGE		(3) //количество "зарядов", для генератора это батарейки, для помпы-колодца уровень воды и тд.
#define CUMO_VAL_CHARGE_MAX	(4) //максимальное кол-во зарядов. Больше быть не может, как ни крути. Нет, я серьезно.
#define CUMO_VAL_TOOLPID	(5) // требуемый инструмент при поломке
#define CUMO_VAL_REPAIR		(6) // требуемый уровень ремонта при поломке
#define CUMO_VAL_SCIENCE	(7) // требуемый уровень науки, все также, при поломке
#define CUMO_VAL_AUTODOOR	(8) // автоматическая ли дверь
#define CUMO_VAL_BREAK_COMP	(9) // сложность поломки

В свою очередь большую часть функционала на себя берет CUMOA (class Used Map Obj Array) - по-сути контейнер классов CUMO. Загрузка \ Сохранение обьектов, выключение энергии, воздуха и тд описанно именно здесь.


Как было написано выше - каждому итему должы быть присвоены следущие функции-перехватчики событий, а точнее :
Код:
void IntObjInit( Item& item, bool firstTime ) //инициализация
{
    item.SetEvent( ITEM_EVENT_SKILL, "_IntObjSkill" );
    item.SetEvent( ITEM_EVENT_USE_ON_ME, "_IntObjPumpOnMe" );
}

bool _IntObjSkill( Item& item, Critter& cr, int skill )
{
	//получаем интерактивный из CUMOA
	uint thisIndex = used_map_obj.GetIndexByItemId(item.Id), genIndex = 0;
	if(thisIndex == uint(-1)) return false;

        int power = 0,
	    switcher = 0,
	    parts = 0,
	    repair = 0,
	    science = 0;

	//копируем данные из обьекта в локальные переменные
	used_map_obj.GetValue(thisIndex, CUMO_VAL_POWER, power);
	used_map_obj.GetValue(thisIndex, CUMO_VAL_SWITCHER, switcher);
	used_map_obj.GetValue(thisIndex, CUMO_VAL_TOOLPID, parts);
	used_map_obj.GetValue(thisIndex, CUMO_VAL_REPAIR, repair);
	used_map_obj.GetValue(thisIndex, CUMO_VAL_SCIENCE, science);

    if( skill == SKILL_PICK_ON_GROUND )
    {
	//если сломано выходим
	if(IsRepair(cr, science, parts, repair)) return true;

	//если подключено питание, выключаем обьект
        if( power > 0 )
        {
		//сохраняем состояние переключателя (индекс обьекта, куда, что)
            used_map_obj.SetValue(thisIndex, CUMO_VAL_SWITCHER, val);

        }
        else
        {
            //выводим грустное сообщение об отключенном питании
        }

	//что-то еще здесь
    }
    else if( skill == SK_SCIENCE )
    {
	if ( !check_science( used_map_obj.cumos[thisIndex], cr )) return true;

	//ваш код здесь

    }
    else if( skill == SK_REPAIR && repair >0)
    {
		//проверяем, можем ли починить
		if ( !check_repair( used_map_obj.cumos[thisIndex], cr )) return true;
	}
	return true;
}

bool _IntObjOnMe( Item& item, Critter& cr, Item@ usedItem )
{

    if( usedItem is null )
        return false;

    uint thisIndex = used_map_obj.GetIndexByItemId(item.Id), genIndex = 0;
	if(thisIndex == uint(-1)) return false;

    uint pid = usedItem.GetProtoId();

	//проверяем соотвествие деталей
    if ( !check_parts( used_map_obj.cumos[thisIndex], cr, usedItem )) return true;

    return false;
}
Выше описаны вызовы, которые обязательно должны быть в функциях-перехватчиках.

Теперь о поломках. На данный момент они немного не доделаны. Верней, код брошен на переходном периоде, когда для каждого обьекта определяются свои группы-связки предмет-навык-количество.

Для этого создан класс CUMOBREAKGROUP
Код:
uint[] BreakPids;
uint[] BreakCounts;
uint[] BreakScience;
uint[] BreakRepair;
Это и есть одна "поломка". все, что будет записано в члены этого класса, будет требоваться для одного ремонта.

Сами группы определяются в фаиле _interactive_groups.fos.

Существует еще один класс - CUMOBREAK, он отвечает за работу с классами CUMOBREAKGROUP хранящимися в нем. Также здесь определяется частота поломок обьекта и тд.
Этот класс должен быть родительским для конкретного класса обьекта, вот пример :
Код:
class CUMOBREAK_WINDMILL : CUMOBREAK
{
  
	CUMOBREAK_WINDMILL(){
		CUMOPid = PID_OBJECT_WINDMILL;
		BreakPeriod = 48;
		
		Init();
	}
	void Init(){
		AddBreakGroup(CUMOBREAKGROUP(alcoPart, alcoCount, alcoScience, alcoRepair));
	}
}
Как видно из кода выше, обьект с пидом == PID_OBJECT_WINDMILL, тоесть ветряная мельница, ветряк, будет ломаться каждые 48 часов. Отремонтировать его можно будет с помощью ... бухла. Ну что поделать, такова сельская жизнь.

По-большому счету на этом все. Теперь Вы сможете создаваться свои интерактивные обьекты и связывать их взаимодействие.


------------------------------------
Инструменты для работы \ дебага
-------------------------------------------------


Код:
void ShowLight( Critter& cr, int x, int, int )
Показывает свет, если x == 0, иначе прячет его. Это достигнуто путем замены картинки с белого пикселя на блокиратор greed wall. Действует на текущей карте.

Код:
void debugOnOff(Critter& cr, int index, int val, int)
Включает \ выключает (val) обьекты с индексом генератора == index

Код:
void spawn_autodoors(Critter& cr, int val, int, int)
кидает триггеры вокруг "автоматизированных" дверей.

Код:
void debugDyspnea(Critter& cr, int val, int, int)
Устанавливает уровень удушья на текущей карте равному значению val

Код:
void intsetval(Critter& cr, int id, int val, int value)
Устанавливает обьекту с Item::Id == id, значение value в массив Val[] c индексом val.

Код:
void intgetval(Critter& cr, int id, int, int)
Выводит массив Val[] для обьекта с Item::Id == id.

Код:
void intturnonobjs(Critter& cr, int generatorValue, int objType, int onoff)
Включает \ выключает (onoff) обьекты с Generator == generatorValue, возможно задать конкретный тип обьекта через ObjType

Код:
void interasedouble(Critter& cr, int, int, int)
Удаляет дубликаты обьектов хранящиеся в памяти. Это может произойти при повторном парсе обьктов с карты. Там нет проверки на уже существующий обьект.
__________________
Jet Rock's

Последний раз редактировалось PowerMagic; 10.02.2015 в 16:46.
PowerMagic вне форума   Ответить с цитированием
4 Пользователей сказали спасибо PowerMagic За этот пост:
ErlKing (12.02.2015), FreePunk (10.03.2016), hi-jack (22.02.2015), qthree (13.02.2015)
Старый 11.02.2015, 13:45   #2
AnDE
Senior Member
 
Аватар для AnDE
 
Регистрация: 17.11.2010
Сообщений: 542
Вес репутации: 385
AnDE has a reputation beyond reputeAnDE has a reputation beyond reputeAnDE has a reputation beyond reputeAnDE has a reputation beyond reputeAnDE has a reputation beyond reputeAnDE has a reputation beyond reputeAnDE has a reputation beyond reputeAnDE has a reputation beyond reputeAnDE has a reputation beyond reputeAnDE has a reputation beyond reputeAnDE has a reputation beyond repute
По умолчанию


Код:
// ���������� � ������� �����������
Использую для оформления дипломной работы, спасибо.
__________________
Уголок ностальгии по 2010:
Райно - Мир, существующий внутри мутанта
Андэ - С ним случился Runker

Последний раз редактировалось AnDE; 11.02.2015 в 13:46.
AnDE вне форума   Ответить с цитированием
Старый 12.02.2015, 03:14   #3
PowerMagic
Lost Overseer
 
Аватар для PowerMagic
 
Специализация: ест детей.
Регистрация: 29.01.2010
Сообщений: 1,000
Вес репутации: 571
PowerMagic has a reputation beyond reputePowerMagic has a reputation beyond reputePowerMagic has a reputation beyond reputePowerMagic has a reputation beyond reputePowerMagic has a reputation beyond reputePowerMagic has a reputation beyond reputePowerMagic has a reputation beyond reputePowerMagic has a reputation beyond reputePowerMagic has a reputation beyond reputePowerMagic has a reputation beyond reputePowerMagic has a reputation beyond repute
По умолчанию

codepage prblm. srry
__________________
Jet Rock's

Последний раз редактировалось PowerMagic; 12.02.2015 в 03:15.
PowerMagic вне форума   Ответить с цитированием
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Часовой пояс GMT +4, время: 00:56.


Powered by vBulletin® Version 3.8.3
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd. Перевод: zCarot
Для внутреннего пользования