1. Друзья, в это тяжёлое и непонятное для всех нас время мы просим вас воздержаться от любых упоминаний политики на форуме, - этим ситуации не поможешь, а только возникнут ненужные ссоры и обиды. Это касается также шуток и юмора на тему конфликта. Пусть войны будут только виртуальными, а политики решают разногласия дипломатическим путём. С уважением, администрация Old-Games.RU.

    Скрыть объявление
  2. Пожалуйста, внимательно прочитайте правила раздела.
  3. Если Вы видите это сообщение, значит, вы ещё не зарегистрировались на нашем форуме.

    Зарегистрируйтесь, если вы хотите принять участие в обсуждениях. Перед регистрацией примите к сведению:
    1. Не регистрируйтесь с никами типа asdfdadhgd, 354621 и тому подобными, не несущими смысловой нагрузки (ник должен быть читаемым!): такие пользователи будут сразу заблокированы!
    2. Не регистрируйте больше одной учётной записи. Если у вас возникли проблемы при регистрации, то вы можете воспользоваться формой обратной связи внизу страницы.
    3. Регистрируйтесь с реально существующими E-mail адресами, иначе вы не сможете завершить регистрацию.
    4. Обязательно ознакомьтесь с правилами поведения на нашем форуме, чтобы избежать дальнейших конфликтов и непонимания.
    С уважением, администрация форума Old-Games.RU
    Скрыть объявление

Поговорим об Unreal

Тема в разделе "PC Игры", создана пользователем Teron Lifeslayer, 15 ноя 2004.

  1. Masterkent

    Masterkent

    Регистрация:
    19 июл 2009
    Сообщения:
    316
    Достаточно хотя бы просто обеспечить реакцию на выстрел гранатами - так же, как это делается для ракет.

    У меня такое бывало несколько раз.

    Кстати, в v227h/i монстры совсем хреново стреляют на упреждение. В Unreal Gold (v226b) непрерывные стрейфы действительно не канают, а в v227h/i Skaarj-ы даже вблизи умудряются бессовестно мазать, причём на любых уровнях сложности. Отчасти поэтому v227 я считаю гуаном и предпочитаю старый добрый официальный Unreal Gold.

    В классическом Unreal нет ни одной карты с двумя усилителями.
     
  2. tarasb

    tarasb

    Регистрация:
    14 июл 2007
    Сообщения:
    452
    У меня просто Анрыл (не голд), причём со звуками ранних версий, но движок пропатчен до 226 (играю в не-голд, потому он Ъвее). Видимо поэтому они меня несколько раз неплохо так ловили ракетой.
    Странно, или я что-то не то вспомнил...
     
  3. tarasb

    tarasb

    Регистрация:
    14 июл 2007
    Сообщения:
    452
    В общем, я решил сделать свою версию, для себя чисто. На 4 уровнях сложности, как в 226, чтобы меньше над балансом думать.
    Суть такова: характеристики монстров на всех уровнях сложности одинаковые. Количество делать одинаковым влом - это, я так понял, надо на картах всех монстров обтыкивать и править фильтры.
    Смысл в том, что на разных уровнях сложности будет разное поведение. То есть задержка между выстрелами, меткость. На лёгком уровне чтобы все монстры стояли на месте во время атаки. С ростом уровня сложности чтобы появлялось упреждение, стрельба из ракетницы в ноги, уворот от ракет, уворот от гранат.
    В общем, расскажите мне основные положения иерархии объектов, и какие примерно там функции за что отвечают.
    Если что, опыт программирования есть (см ссылку в подписи), правда не на US, но тут же синтаксис в целом такой же, как в популярных языках, только знания фреймворка у меня нету.
     
  4. Warmaster RUH Squadron Officer

    Warmaster

    Регистрация:
    17 мар 2012
    Сообщения:
    5.005
    Эх народ, до чего сейчас мне жалко, что Unreal и Unreal:RtNP уже пройдены!!! Unreal 2 и вправду что-то не очень, по крайней мере так сильно не цепляет((( Так что, пройду сейчас Prey и начну версию 227 покорять! Сначала просто пройду, а потом без сэйвов.
     
  5. LipSheZ Пахан

    LipSheZ

    Регистрация:
    1 окт 2007
    Сообщения:
    908
    Да ладно! где? только один видел там!!
    Если плавно бегать вокруг врага, то 100% что не попадёт. Упреждение врагов рассчитывается изходя из скорости движения игрока в одном направлении, расстояния до него и скорости полёта снаряда. ещё эффективный способ уворачивания - это ходьба маленькими быстрыми шажками.
    В 227h на дополнительных уровнях сложности на уровнях оставались все итемы, что есть на карте (грубо говоря всё как на первом скилле), но живучесть монстров возрастала на 15% и урон увеличивался в 1,5 раза за каждый следующий скилл. В принципе было с трудом, но всё же играбельно и без сейвов проходимо. Но!! в свежем 227i разрабы охренели: теперь на последнем скилле патронов, итемов и аптечек минимально (аналогично послднему скиллу в официальном 226) при том же двойном уроне от врагов! Патронов жестко не хватает практически всегда. Вопщем невозможно стало играть вапще.
    Пачт 227i включает муматор OldWeapons с теми самыми звуками. По мне они приятней, чем из голда, всегда подключаю.

    И ещё, это только у меня в 227i при переходе с Vortex2 на NyLeve в списке найденных итемов появляется пополняющийся акваланг?:banghead: Надеюсь, они хотфикс выпустят, а то на посл. уровне сложности совсем безмазово играть стало.
     
    Последнее редактирование: 25 ноя 2012
    unreal doom нравится это.
  6. FACH

    FACH

    Регистрация:
    31 окт 2009
    Сообщения:
    663
    :shok:
    Ххе... Нда.. Но если Мастеркент сможет 2-х томник написать я бы тоже почитал. А так документации по скрипту у эпиков было на страниц где-то более 550.
    Я тут по функциям документацию переводил (до сих пор маленький кусок не доперевел...), правда для 3-го движка, там на примере довольно прикольном было не плохо объяснены все важные моменты. Но это лишь малая часть, а получилось 55 страниц...

    Видимо. Поставил я 227 И ничего не появляется при переходе
     
    Последнее редактирование: 26 ноя 2012
  7. LipSheZ Пахан

    LipSheZ

    Регистрация:
    1 окт 2007
    Сообщения:
    908
    Гм. А если на NyLeve помрёшь, и загрузишь уровень с его же аутосейва?

    edit: на последнем уровне сложности в 227ай у тебя на Вортексе есть аптечка +20 справа от лифита на втором ярусе?
     
    Последнее редактирование: 26 ноя 2012
  8. FACH

    FACH

    Регистрация:
    31 окт 2009
    Сообщения:
    663
    Нету
    Это где? Не вижу нигде
     
  9. Masterkent

    Masterkent

    Регистрация:
    19 июл 2009
    Сообщения:
    316
    Да уж, расчёт

    Код:
    FireSpot += FMin(1, 0.7 + 0.6 * FRand()) * (Target.Velocity * VSize(Target.Location - ProjStart)/projSpeed);
    действительно довольно грубый. Я как-то сразу этого не заметил. Если игрок приближается к монстру, то упреждение в половине случаев слишком большое, а если отдаляется от монстра - всегда слишком маленькое. Движение по параболе походу вообще не покрывается.

    Ох, ну наконец-то у них руки дошли до фильтров. Глядишь, в какой-нибудь версии 227z они в конце концов пофиксят очевидные баги, вроде пролёта больших Titan-овских булыжников сквозь игрока.

    А мне наоборот Gold-овские больше нравятся.

    Возможно, это от того, что ты включил мутатор для RtNP.

    Да я не особо-то в этих скриптах разбираюсь. Ну, то есть, по мелочи что-то поменять могу, но вот детального понимания работы AI (в частности, в какие моменты времени управление передаётся определённым состояниям (не считая очевидное использование функции GoToState) и как анимации влияют на передачу управления) у меня нет.

    В принципе, я могу выложить свой Fix к 226b, где монстры получше целятся и поменьше тупят.
     
    Timonza-kun, Alien3674, FACH и ещё 1-му нравится это.
  10. unreal doom

    unreal doom

    Регистрация:
    1 мар 2006
    Сообщения:
    4.932
    Блин, а ведь правда, и только сейчас заметил, ибо наученный 226 версией, круговые стрейфы не использовал, а у любителей это оказывается прокатывает.
    Не скажу, что смертельный косяк, но обидно :(.

    И правда им еще дорабатывать и дорабатывать свое детище.
     
  11. tarasb

    tarasb

    Регистрация:
    14 июл 2007
    Сообщения:
    452
    Они не голдовские. Они уткины.

    ---------- Сообщение добавлено в 19:12 ---------- Предыдущее сообщение размещено в 18:24 ----------


    Попробуйте так (названия функции скалярного произведения не знаю, напишите правильно):
    Код:
    vector Dist = Target.Location - ProjStart;
    // коэффициенты квадратного уравнения
    float a = projSpeed*projSpeed - ScalarMul(Target.Velocity, Target.Velocity);
    float p = - ScalarMul(Dist, Tagret.Velocity); // b/2
    float c = - ScalarMul(Dist, Dist);
    float d = p*p-a*c; // дискриминант 
    if (d>=0.0)
    {
      float t = (-p+sqrt(d))/a; /* это больший корень, 
        меньший не нужен, 
        он отрицательный так как c<0   */
      /* теперь t*TargetVelocity содержит 
      точное упреждение на случай, 
      если цель продолжит двигаться
      равномерно и прямолинейно. 
      Рандомизируем на случай, если цель сменит направление. */
      FireSpot += FMin(1, 0.7 + 0.6 * FRand()) * t * Target.Velocity;
    }
    
     
  12. Masterkent

    Masterkent

    Регистрация:
    19 июл 2009
    Сообщения:
    316
    Не вижу смысла в этом противопоставлении.

    Я уже сделал расчёт через итерации (работает для движения по прямой и по параболе в полёте). Быстродействие вполне приемлемое.

    Код:
    function rotator AdjustAim(float projSpeed, vector projStart, int aimerror, bool leadTarget, bool warnTarget)
    {
    	local rotator FireRotation;
    	local vector FireSpot;
    	local actor HitActor;
    	local vector HitLocation, HitNormal;
    //----------------------------------[-FIX_v1.0-]-begin--------------------------
    	local vector InitialFireSpot, PriorFireSpot, TargetHeight;
    	local float dt, dist, prior_dist;
    	local int iterations;
    //----------------------------------[-FIX-]-end---------------------------------
    
    	if ( Target == None )
    		Target = Enemy;
    	if ( Target == None )
    		return Rotation;
    	if ( !Target.IsA('Pawn') )
    		return rotator(Target.Location - Location);
    					
    	FireSpot = Target.Location;
    
    	aimerror = aimerror * (1 - 10 *  
    		((Normal(Target.Location - Location) 
    			Dot Normal((Target.Location + 0.5 * Target.Velocity) - (Location + 0.5 * Velocity))) - 1)); 
    
    	aimerror = aimerror * (2.4 - 0.5 * (skill + FRand()));	
    
    	if (leadTarget && (projSpeed > 0))
    	{
    		FireSpot += FMin(1, 0.7 + 0.6 * FRand()) * (Target.Velocity * VSize(Target.Location - ProjStart)/projSpeed);
    		HitActor = Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
    		if (HitActor != None)
    			FireSpot = 0.5 * (FireSpot + Target.Location);
    	}
    
    	HitActor = self; //so will fail first check unless shooting at feet  
    	if ( bIsPlayer && (Location.Z + 19 >= Target.Location.Z) && Target.IsA('Pawn') 
    		&& (Weapon != None) && Weapon.bSplashDamage && (0.5 * (skill - 1) > FRand()) )
    	{
    		// Try to aim at feet
     		HitActor = Trace(HitLocation, HitNormal, FireSpot - vect(0,0,80), FireSpot, false);
    		if ( HitActor != None )
    		{
    			FireSpot = HitLocation + vect(0,0,3);
    			HitActor = Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
    		}
    		else
    			HitActor = self;
    	}
    	if ( HitActor != None )
    	{
    		//try middle
    		FireSpot.Z = Target.Location.Z;
     		HitActor = Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
    	}
    	if( HitActor != None ) 
    	{
    		////try head
     		FireSpot.Z = Target.Location.Z + 0.9 * Target.CollisionHeight;
     		HitActor = Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
    	}
    	if ( (HitActor != None) && (Target == Enemy) )
    	{
    		FireSpot = LastSeenPos;
    		if ( Location.Z >= LastSeenPos.Z )
    			FireSpot.Z -= 0.5 * Enemy.CollisionHeight;
    		if ( Weapon != None )
    		{
    	 		HitActor = Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
    			if ( HitActor != None )
    			{
    				bFire = 0;
    				bAltFire = 0;
    				SetTimer(TimeBetweenAttacks, false);
    			}
    		}
    	}
    
    //----------------------------------[-FIX_v1.0-]-begin--------------------------
    	if (Level.Game.Difficulty > 3 && leadTarget && projSpeed > 0)
    	{
    		aimerror *= 0.1;
    
    		dt = 0;
    		iterations = 0;
    		InitialFireSpot = Target.Location + Target.Velocity * dt;
    		dist = Abs(VSize(InitialFireSpot - projStart) - projSpeed * dt);
    		HitActor = None;
    
    		if (Target.Physics == PHYS_Falling)
    		{
    			TargetHeight = vect(0, 0, 0);
    			TargetHeight.Z = Target.CollisionHeight;
    			PriorFireSpot = InitialFireSpot;
    
    			do
    			{
    				prior_dist = dist;
    				dt += 0.01;
    				++iterations;
    				InitialFireSpot = Target.Location + Target.Velocity * dt + Target.Region.Zone.ZoneGravity * dt * dt / 2;
    				dist = Abs(VSize(InitialFireSpot - projStart) - projSpeed * dt);
    				HitActor = Trace(HitLocation, HitNormal, InitialFireSpot - TargetHeight, PriorFireSpot - TargetHeight, false);
    			}
    			until (prior_dist < dist || iterations > 500 || HitActor != None);
    
    			if (HitActor != None)
    			{
    				InitialFireSpot = HitLocation;
    				InitialFireSpot.Z += Target.CollisionHeight;
    			}
    			else if (iterations <= 500)
    			{
    				iterations = 0;
    				do
    				{
    					prior_dist = dist;
    					dt -= 0.001;
    					++iterations;
    					InitialFireSpot = Target.Location + Target.Velocity * dt + Target.Region.Zone.ZoneGravity * dt * dt / 2;
    					dist = Abs(VSize(InitialFireSpot - projStart) - projSpeed * dt);
    				}
    				until (prior_dist < dist || iterations > 20);
    
    				if (prior_dist > 100)
    					iterations = -1;
    			}
    		}
    		else
    		{
    			do
    			{
    				prior_dist = dist;
    				dt += 0.01;
    				++iterations;
    				InitialFireSpot = Target.Location + Target.Velocity * dt;
    				dist = Abs(VSize(InitialFireSpot - projStart) - projSpeed * dt);
    			}
    			until (prior_dist < dist || iterations > 500);
    
    			if (iterations <= 500)
    			{
    				iterations = 0;
    				do
    				{
    					prior_dist = dist;
    					dt -= 0.001;
    					++iterations;
    					InitialFireSpot = Target.Location + Target.Velocity * dt;
    					dist = Abs(VSize(InitialFireSpot - projStart) - projSpeed * dt);
    				}
    				until (prior_dist < dist || iterations > 20);
    
    				InitialFireSpot += (Target.Location - InitialFireSpot) * FMax(0, 1 - 2 * FRand()) *
    					FMin(0.1 + 3 *(VSize(InitialFireSpot - projStart) / projSpeed - 0.3), 1);
    				if (prior_dist > 100)
    					iterations = -1;
    			}
    		}
    
    		if (iterations > 500 && HitActor == None || iterations < 0)
    			InitialFireSpot = Target.Location +
    				FMin(1, 0.7 + 0.6 * FRand()) * Target.Velocity * VSize(Target.Location - projStart)/projSpeed;
    		FireSpot = InitialFireSpot;
    		HitActor = self;
    
    		if (Target.bIsPawn && ((Weapon != None) && Weapon.bSplashDamage
    		    || IsA('Brute') || IsA('Mercenary') || IsA('Warlord')))
    		{
    			// Try to aim at feet
     			HitActor = Trace(HitLocation, HitNormal, FireSpot - vect(0,0,80), FireSpot, false);
    			if ( HitActor != None )
    			{
    				FireSpot = HitLocation + vect(0,0,3);
    				HitActor = Trace(HitLocation, HitNormal, FireSpot, projStart, false);
    			}
    			else
    				HitActor = self;
    		}
    		if (HitActor != None)
    		{
    			// try middle
    			//if (Target.Physics == PHYS_Falling)
    			//	InitialFireSpot.Z = Target.Location.Z;
    			FireSpot = InitialFireSpot;
     			HitActor = Trace(HitLocation, HitNormal, FireSpot, projStart, false);
    		}
    		if (HitActor != Target && HitActor != None) 
    		{
    			// try head
    	 		FireSpot.Z = InitialFireSpot.Z + 0.9 * Target.CollisionHeight;
     			HitActor = Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
    		}
    		if (HitActor != Target && HitActor != None && Target == Enemy)
    		{
    			FireSpot = LastSeenPos;
    			if (Location.Z >= LastSeenPos.Z)
    				FireSpot.Z -= 0.5 * Enemy.CollisionHeight;
    		}
    	}
    	else if (Level.Game.Difficulty > 3)
    		aimerror *= 0.5;
    //----------------------------------[-FIX-]-end---------------------------------
    	
    	FireRotation = Rotator(FireSpot - ProjStart);
    	     
    	FireRotation.Yaw = FireRotation.Yaw + 0.5 * (Rand(2 * aimerror) - aimerror);
    	if (warnTarget && Pawn(Target) != None) 
    		Pawn(Target).WarnTarget(self, projSpeed, vector(FireRotation)); 
    
    	FireRotation.Yaw = FireRotation.Yaw & 65535;
    	if ( (Abs(FireRotation.Yaw - (Rotation.Yaw & 65535)) > 8192)
    		&& (Abs(FireRotation.Yaw - (Rotation.Yaw & 65535)) < 57343) )
    	{
    		if ( (FireRotation.Yaw > Rotation.Yaw + 32768) || 
    			((FireRotation.Yaw < Rotation.Yaw) && (FireRotation.Yaw > Rotation.Yaw - 32768)) )
    			FireRotation.Yaw = Rotation.Yaw - 8192;
    		else
    			FireRotation.Yaw = Rotation.Yaw + 8192;
    	}
    	viewRotation = FireRotation;			
    	return FireRotation;
    }
    Вот так примерно это выглядит в игре:
    http://youtu.be/8mwsVmbZ-F0
     
    Последнее редактирование: 28 ноя 2012
    FACH и unreal doom нравится это.
  13. LipSheZ Пахан

    LipSheZ

    Регистрация:
    1 окт 2007
    Сообщения:
    908
    На цвет и вкус разной длины ус ;)
    Получается, eсли прыгаешь или летишь, увернуться от проджектайла невозможно. даёшь айкконтрол! :D

    ---------- Сообщение добавлено в 01:56 ---------- Предыдущее сообщение размещено в 01:55 ----------

    не возможно, а точно! спасиба)))))
     
  14. tarasb

    tarasb

    Регистрация:
    14 июл 2007
    Сообщения:
    452
    Смотрится шикарно. Можно делать четверной rocketjump на отдаче от взрывов ракет скааржа и быстро проходить уровен/открывать секреты.
    Ещё есть такая техника у отцов при работе со скорострельной пушкой с медленными патронами: дёргать прицел.
    Кстати, почему стрельба из ракетницы по ногам сделана все зоны "фикс"? Она изначально была?

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

    ---------- Сообщение добавлено в 18:44 ---------- Предыдущее сообщение размещено в 18:44 ----------

    А по умолчанию не 35%, или я опять по утке смотрю?
     
    unreal doom нравится это.
  15. Masterkent

    Masterkent

    Регистрация:
    19 июл 2009
    Сообщения:
    316
    В моей реализации дёрганье есть.

    Я не понял вопрос.

    Насколько я понимаю, в оригинальном скрипте стрельба в ноги реализована только для ботов (см. флаг bIsPlayer) и только для случаев, когда цель не находится выше стрелка (Location.Z + 19 >= Target.Location.Z).

    Вооружение некоторых монстров (например, SkaarjWarrior-ов) настолько неэффективное, что их никакой AI не спасёт. Увеличить скорость projectile-ов таких монстров, в принципе, есть резон.

    Почему?
     
    Последнее редактирование: 29 ноя 2012
  16. unreal doom

    unreal doom

    Регистрация:
    1 мар 2006
    Сообщения:
    4.932
    Я в последнее время думаю, что стоило бы посильно вмешаться в ход работ над очередным патчем 227 линейки :rolleyes:.

    Тут и баг со стрельбой на упреждение, описанный
    Masterkent.
    И то, что он сам предлагает и более того реализует лучший, и истинно анриловский способ поднятия сложности. В то время, как в 227 версии авторы пошли по простейшему пути вносящему в игру больше условностей.
    И наконец эти мысли подогревает знакомство с одним из знатоков Анрила и местным форумчанином, прозвавшем себя SkaarjZR. Этот человек также состоит и в OldUnreal-сообществе, и даже имеет доступ к ходу разработки 227 линейки.
     
    Timonza-kun и Alien3674 нравится это.
  17. tarasb

    tarasb

    Регистрация:
    14 июл 2007
    Сообщения:
    452
    Твоё изменение кода находится вне зоны, которую ты пометил как изменённую, вот я и спросил.
    Не, всяко хуже не будет, если он будет лучше уворачиваться и если его два шарика будут предугадывать твою траекторию.
    Бруты и Краллы такого интеллекта недостойны. Наделение их такими возможностями лишает Скааржа его крутизны. Изначально по задумке Скаарж - это самый умный и самый крутой монстр, берущий именно ловкостью. А остальные по сравнению с ним - мясо.
     
  18. Masterkent

    Masterkent

    Регистрация:
    19 июл 2009
    Сообщения:
    316
    Не вижу у себя такого. Вроде, всё там правильно отмечено.

    Надо чтоб он ещё и сам попасть по игроку мог.

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

    Чисто для справки: функция AdjustAim - общая для всех монстров. Tentacle и Warlord для расчёта упреждения используют один и тот же код. В принципе, эту виртуальную функцию можно замещать для отдельных видов монстров, но в оригинале такого замещения не делается.

    Мои изменения трудно назвать существенным усовершенствованием AI. Для существенного усовершенствования надо потратить немало времени, чего я не могу себе позволить.
     
  19. tarasb

    tarasb

    Регистрация:
    14 июл 2007
    Сообщения:
    452
    Вот эта строчка:
    Код:
    if ( bIsPlayer && (Location.Z + 19 >= Target.Location.Z) && Target.IsA('Pawn') 
    		&& (Weapon != None) && Weapon.bSplashDamage && (0.5 * (skill - 1) > FRand()) )
    
    Находится не между тэгами "FIX"
    Чисто для справки: можно использовать RTTI, можно перегрузить функцию в наследнике.
     
  20. Masterkent

    Masterkent

    Регистрация:
    19 июл 2009
    Сообщения:
    316
    Этот код есть в оригинале, я там ничего не менял. FIX-ами отмечены добавленные и исключённые (путём закомменчивания) строчки кода.

    Кастить к производным классам и проверять результат на None, либо заюзать IsA можно, конечно, но, по-моему, это изврат. Если ставить перед собой цель избирать алгоритм в зависимости от уровня интеллекта, то целесообразнее проверять значение свойства Intelligence (у Krall-ов, кстати, уровень интеллекта такой же, как и у Skaarj-ей - BRAINS_Human).

    Не перегрузить (overload), а заместить (override). О возможности замещения я уже упомянул.
     
  1. На этом сайте используются файлы cookie, чтобы персонализировать содержимое, хранить Ваши предпочтения и держать Вас авторизованным в системе, если Вы зарегистрировались.
    Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie.
    Скрыть объявление