Новости/News | | Туториалы/Tutorials | | Форум/Forum | | ЧаВо/FAQ | | Файлы/Downloads | | Ссылки/Links | | Авторы/About |

Mutator Class

Класс Mutator расширяет (extends) класс Info. Ниже следует список всех переменных (а также их назначения, которые мне удалось выяснить) и функций с подробным их описанием.

Переменные

var Mutator NextMutator Указатель на следующий мутатор (mutator object) из текущего списка мутаторов;
var Mutator NextDamageMutator Указатель на следующий мутатор повреждений (damage mutator object) из текущего списка мутаторов повреждений;
var Mutator NextHUDMutator Указатель на следующий HUD мутатор (HUD mutator object) из текущего списка HUD мутаторов;
var bool bHUDMutator Логическая переменная-флаг, указывающая, является ли данный мутатор HUD мутатором;
var class<Weapon> DefaultWeapon Не уверен для чего это предназначено, но, судя по всему, эта переменная перегружает (override) ранее установленное оружие по умолчанию (default weapon) для level/game (с помощью функций MutatedDefaultWeapon() и MyDefaultWeapon(), с которыми я не имел дело);

Функции

event PreBeginPlay() Вызов этой функции происходит непосредственно перед игрой;
simulated event PostRender(canvas Canvas) Вызывается каждый тик (tick) игры "на машине, которая стартовала мутатор", т.е. эта функция не может похвастаться своими сетевыми возможностями. Более подробно см. ниже в информации о HUD мутаторах;
function ModifyPlayer(Pawn Other) Вызывается, когда игрок вступает (подключается) в игру. Other ссылается на объект (player's pawn) этого игрока;
function ScoreKill(Pawn Killer, Pawn Other) Если в течение игры кого-то завалили, то вызывается эта функция, передавая ссылку на Killer (того, кто ответственен за убийство), а также на Other (жертва, павшая от руки Killer-а). Следует отметить, что вызов этой функции происходит в том же тике, в котором и произошло убийство, до того как начнут работать любые процессы, даже перед rendering-ом;
function Class<Weapon> MutatedDefaultWeapon() Возвращает установленное по умолчанию оружие, учитывая все мутаторы из списка;
function Class<Weapon> MyDefaultWeapon() Вызывается функцией MutatedDefaultWeapon(). Возвращает оружие по умолчанию для данного мутатора;
function AddMutator(Mutator M) Добавляет мутатор M в текущий список мутаторов. Вызов этой функции не обязателен;
function bool ReplaceWith(Actor Other, string aClassName) Заменяет один актер (Actor Class object) на другой с именем aClassName. Эта функция не вызывается автоматически мутатором;
function bool AlwaysKeep(Actor Other) Вызывается, когда актер вот-вот должен быть уничтожен. Если эта функция вернет значение true, то актер останется невредим. По умолчанию возвращается false;
function bool IsRelevant(Actor Other, out byte bSuperRelevant) Проверяет, разрешено ли мутатору изменять/заменять объект (актер) или нет. Назначение переменной bSuperRelevant осталось для меня загадкой;
function bool CheckReplacement(Actor Other, out byte bSuperRelevant) Вызывается функцией IsRelevant() чтобы узнать будет ли заменен актер Other или нет. Назначение переменной bSuperRelevant осталось для меня загадкой;
function Mutate(string MutateString, PlayerPawn Sender) Вызывается, когда игрок вводит одноименную консольную команду. Позволяет мутатору добавлять свои команды;
function MutatorTakeDamage(out int ActualDamage, Pawn Victim, Pawn InstigatedBy, out Vector HitLocation, out Vector Momentum, name DamageType) Вызов этой функции происходит при повреждении актера. Следует заметить, что функция отрабатывает до того, как реальные повреждения вступят в силу, позволяя тем самым мутатору самому обрабатывать повреждения и точки попадания (hit location);
simulated function RegisterHUDMutator() Регистрирует данный мутатор в качестве HUD мутатора, вследствие чего, он начинает получать вызовы функции PostRender();

Как Вы заметили, в классе Mutator всего лишь 5 переменных и 14 функций. Тем не менее, в силу наследования класса Info (который, в свою очередь, наследует класс Actor), Вам становятся доступны многие другие переменные и функции. Наиболее важной из них является функция PostBeginPlay(). Давайте рассмотрим мутатор Spectre в качестве примера:

// Spectre
// Модифицированная версия мутатора GhostBoy
class Spectre extends Mutator; 

var bool Initialized; 

function PostBeginPlay() {

  if (Initialized) return; 

  Initialized = True; 

  Level.Game.RegisterDamageMutator(Self);
} 

function ScoreKill(Pawn Killer, Pawn Other) {

  // если у нас появился победитель, увеличим его glowing
  // у жертвы сбросим glowing на исходное значение
  if ((Killer != Other) && (Other != None) && (Killer != None)) {

    Killer.ScaleGlow += 0.2;
    Other.ScaleGlow = 1.5;
  } 

  // при суициде установим игроку то, что он заслужил :)
  if ((Other != None) && ((Killer == None) || (Killer == Other))) Other.ScaleGlow = 1.5; 

  // установим значение видимости (visibility) для того, чтобы боты нормально ее воспринимали
  Other.Visibility = Other.Default.Visibility * Other.ScaleGlow;
  Killer.Visibility = Killer.Default.Visibility * Killer.ScaleGlow; 

  // вызовем родительский ScoreKill для последующей обычной обработки убийцы и трупа
  Super.ScoreKill(Killer, Other);
} 

function bool CheckReplacement( actor Other, out byte bSuperRelevant) {

  // игроки, боты и каркасы (carcasses) (включая джибсы) должны также быть невидимыми
  if ( Other.IsA('Pawn') || Other.IsA('Carcass')) Other.Style = STY_Translucent; 

  // пикапы, дающие невидимость несколько неуместны
  // поэтому просто избавимся от них...
  if (Other.IsA('Invisibility')) return false; 

  return true;
} 

function MutatorTakeDamage(out int ActualDamage, Pawn Victim, Pawn InstigatedBy,
 out Vector HitLocation, out Vector Momentum, name DamageType) {

  local float dglow; 

  // уменьшаем glowing жертвы
  dglow = float(ActualDamage) / 70.0;
  if (dglow <= 0.1) dglow = 0.1;
  Victim.ScaleGlow -= dglow;
  if (Victim.ScaleGlow <= 0.1) Victim.ScaleGlow = 0.1; 

  // увеличиваем glowing атакующего
  if (InstigatedBy != Victim) InstigatedBy.ScaleGlow += dglow; 

  // установим значение видимости (visibility) для того, чтобы боты нормально ее воспринимали
  Victim.Visibility = Victim.Default.Visibility * Victim.ScaleGlow;
  InstigatedBy.Visibility = InstigatedBy.Default.Visibility * InstigatedBy.ScaleGlow;
  Super.MutatorTakeDamage(ActualDamage, Victim, InstigatedBy, HitLocation, Momentum, DamageType);
}

Пояснение

Начнем с самого начала. Первое, что мы делаем - объявляем класс. Честно говоря, мы просто наследуем/расширяем (extending) класс Mutator. Затем следует объявление переменных. Все переменные, объявленные вне пределов функций являются глобальными и статичными относительно этого объекта (класса) с момента его создания. Ниже следует функция PostBeginPlay(). PostBeginPlay() вызывается после того, как игра полностью подготовлена для запуска (т.е. все объекты проинициализированы, созданы, отслежены) и игра начнется после того, как мутатор вернется из этой функции (точнее, после того как все классы вернутся из этой функции). По некоторым причинам класс Mutator вызывает эту функцию дважды. Для того, чтобы избежать повторной инициализации, используется глобальная логическая переменная-флаг, показывающая вызывалась ли уже эта функция или нет. Единственная инициализация, которая происходит в этой функции, регистрирует данный мутатор в качестве мутатора повреждений, в результате чего, при нанесении кому-либо повреждения, движок будет вызывать функцию MutatorTakeDamage(). Обычно все глобальные переменные инициализируются именно в PostBeginPlay(). Не смотря на то, что движок игры инициализирует все объекты значениями по умолчанию, лучше застраховаться и произвести их инициализацию исходными значениями (надежнее сделать параноидальные проверки переменным, гарантирующие защиту от потенциальных ошибок).

Далее следует функция ScoreKill(). Эта функция вызывается любым типом мутаторов, поэтому это лучшее место, где можно сделать что-то особенное двум актерам: убийце (Killer) и жертве (Other). Объекты/свойства игрока не удаляются, когда он умирает, а просто "сбрасываются" (reset) на исходные значения. Тем не менее, движок берет на себя ответственность только за некоторые свойства, которые он и восстанавливает при респавне (respawn). Вот здесь Вы и можете произвести сброс/модификацию/настройку любых свойств игрока/актера. Следующая функция: CheckReplacement(). Вызов этой функции происходит для каждого актера при добавлении его в уровень. Если Вам не по душе присутствие какого либо актера/объекта на карте, то эта функция все уладит. Возвращая значение false, Вы тем самым говорите движку избавиться от этого актера.

И, наконец, сердце этого мутатора - функция MutatorTakeDamage(). Вследствие того, что этот мутатор был зарегистрирован в качестве мутатора повреждений в PostBeginPlay(), каждый раз, когда игроку/боту "вот-вот будет нанесен урон" вызывается эта функция. Это позволяет мутатору самому обработать переданные этой функции переменные: т.е. величину урона, место, куда попал снаряд (hit location) или вызвать другие процессы, основываясь на информации, полученной этой функцией, например, поменять значение невидимости, в зависимости от количества полученного повреждения, что и делает вышеописанный мутатор.

Автор

Pfhoenix
Источник: www.unrealscript.com
Перевод сделан 32_Pistoleta

Хостинг от uCoz