Перейти к контенту

Скриптование


Svoboда

Рекомендуемые сообщения

Shoker,

Кто нибудь может пож-ста словами или готовым кодом написать формулу для нахождения перпендикулярного вектора направленного вбок от искомого и перпендикулярного вектора, направленного вверх от искомого?

 

ок. Пусть вектор dir - это вектор направления. Обязательным условием является его невертикальность.

 

единичный вектор, смотрящий вправо, получаем так:

right = dir x vert / |dir x vert|

 

где vert - вектор вертикали (в системе координат сталкера будет (0,1,0))

x - векторное произведение (в сталкере метод crossproduct)

|dir x vert| - длина вектора (функция magnitude)

 

Или просто взять сначала произведение, получить ненормированный вектор, затем нормировать (в сталкере метод normalize)

 

Затем получаем единичный вектор, перпендикулярный первым двум, т.е. направленный вверх (вверх относительно исходного направления естественно, а не мировой системы координат):

up = right x dir

  • Нравится 2
 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

Shoker,

не учитывает Roll (наклон объекта вбок)

То есть если игрок выглядывает из за угла (наклоняется вправо\влево), то этот наклон не учитывается при расчёте боковых векторов.

Какой такой наклон у объектов? Где ты это видел? А если это ГГ, то зачем тебе эти пляски, если можно не заморачиваясь взять уже готовую камеру?

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

Коли так, то у него наклон получить сложнее будет. Это же не объект, а всего лишь кость худа.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

OFF_ender,

По мере заполнения таблиц получаю либо зависание при сохранении, либо вылет при попытке загрузки (чаще).

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

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

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

АuReN,

 

Пытаюсь определить id машины актёра

local oActorCar = db.actor:get_holder_class()
local oCarId = oActorCar:id() 
Происходит вылет:

эта функция возвращает объект типа CHolderCustom, он же скриптовый класс holder (имя класса на самом деле не имеет значения, поскольку нигде явно не используется). Строго говоря, это клиентский класс, но не game_object, поэтому у него нет поля id.

Кроме того. как ты делаешь делать нельзя. Если актор не в машине или не за станковыйм пулемётом, то get_holder_class() вернёт nil и вылет будет на следующей строке, но уже по другой причине. Кстати, судя по логу именно это и происходит.

 

Что касается определения id машины, то без правок движка это делается достаточно хлопотно: надо перебирать машины и искать ту, в которой сидит актор, сравнением положения актора и машины. По крайней мере я других способов не знаю. С правками это можно сделать проще.

Изменено пользователем malandrinus
 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

АuReN,

что тогда с функцией get_current_holder? Работает ли она?

О, кстати я ошибся в предыдущем посте. Функция get_holder_class() возвращает этот же объект, но сконвертированный в тип holder.Т.е. её надо вызывать для машины, и она вернёт машину же, но в виде класса holder. А вот get_current_holder() как раз вызывается для актора и возвращает машину/пулемёт, в которой он сидит, или nil.

 

Вот жаль, что нельзя править посты. Как всё неудобно стало.

 

Кстати, в качестве идеи. Можно попробовать сравнить сами объекты холдеров, тот, что получен у актора и тот, который получен из машины. Я сейчас попробовать не могу, но есть некая вероятность, что это может сработать. Если сработает, то тогда всё равно надо перебирать машины, но не придётся мудрить с расстоянием до актора.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

@Alex535, а кто сказал, что это скрипт? Все эффекты контролёра внутри движка.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

Alex535,

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

 

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

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

mumie,

Может существует альтернатива?

Можно попытаться вывести нужный тебе элемент не на самом окне инвентаря, а поверх отдельным окном. Визуально разницы не будет.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

Shadows,
у лампочек нет ни смерти ни здоровья, поскольку они не живые объекты. "Смерть" лампочки наступает от первого хита, что реализуется движком. Вроде как и колбек на хит работает, хотя сейчас точно не вспомню. Правда это всё в оригинале криво работает. После перезагрузки включается опять и т.д.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

Viнt@rь,

 

проверял и кастом статиками и созданием окна

Вероятно активное окно всегда перекрывает другое top-level окно. Ну значит штатными средствами никак, только с расширениями.

 

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

@dukekan, для ограниченного объёма данных можно использовать трюк с хранением данных в имени файла с использованием класса FS. Этот класс не позволяет записывать данные в файл, но позволяет копировать файлы, менять их имена, читать содержимое каталога. Нужно завести таким образом специальные пустые файлы, придумать формат для имён и хранить данные в именах. Это вполне работает, хотя конечно и пахнет трюкачеством за милю.

С другой стороны можно рассмотреть использование расширений Lua. Есть проект от RvP, где добавлялись недостающие библиотеки работы с файлами.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

Dennis_Chikin,
Разница есть, обусловлена разной природой биндера и серверного объекта. Скриптовый серверный объект является обёрткой для истинного движкового объекта, т.е. когда вызываем его метод в скриптах - тем самым явно вызываем соответствующий метод движка. Одно из следствий этого - когда переопределяем метод в скриптах - он полностью заменяет внутренний движковый метод. Если внутренний метод при этом использовал сервис базового класса в виде явного вызова метода базового класса, то это надо/можно повторить и в скриптах. Самый типичный пример - методы сохранения/чтения, где сам скриптовый метод сохраняет только "своё добро", а надо ещё и явно вызвать метод базового класса для сохранения/загрузки его состояния. Или метод проверки выхода в онлайн, где я могу определить свою логику для этого действия, но при этом могу использовать в качестве одной из веток алгоритма дефолтовое значение. А могу и не использовать. В последнем случае метод базового класса вызывать не надо. При этом всё-таки надо отчётливо понимать, что я сознательно выбрасываю определённый движковый функционал.

С другой стороны биндер работает совсем иначе. Есть онлайновый класс, у него есть базовый класс CScriptBinder, который входит в состав CGameObject (и значит в состав абсолютно всех классов). Класс CScriptBinder как раз и отвечает за функционал биндера. Там есть указатель на объект биндера, а биндер в свою очередь - это отдельный класс CScriptBinderObject, которому как раз и соответствует скриптовый биндер (является его обёрткой). Объект биндера может быть или не быть, мы сами создаём его в скриптах и цепляем к онлайновому объекту методом клиентского класса bind_object.
Если он есть, то это исключительно инициатива клиентского объекта-хозяина вызывать методы биндера и посылать сигналы колбеков. Отсюда идёт важный вывод. Нет никакой необходимости вызывать методы базового класса биндера, поскольку они ничего не делают. Т.е. всё движковое действие происходит в методе клиентского объекта, который сработает вне зависимости от того, вызвался метод биндера или нет, а биндер просто вызывается "до кучи". Я это проверял. Удалял вызовы базового класса биндера, и ничего ровным счётом не менялось.

  • Нравится 1
 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

Dennis_Chikin,


Эти приведенные куски кода - они там зачем ? Если эти методы НЕ переопределяются - они ведь по дефолту как-то работают ?

ок. Первый фрагмент - метод биндера.

function generic_object_binder:reinit()
    object_binder.reinit( self )
end

Вызов object_binder.reinit( self ) здесь не делает ничего, поскольку класс биндера не делает ничего, поскольку его единственное назначение - вызывать скриптовый код. Строку можно убрать, ничего не изменится.

Второй фрагмент. Переопределён метод класса se_artefact, заменен на скриптовый.

function se_artefact:can_switch_offline()
    return cse_alife_item_artefact.can_switch_offline( self )
end

Исходный метод cse_alife_item_artefact.can_switch_offline(self) что-то делал, пока мы его этим самым фрагментом не переопределили. Скорее всего возвращал значение серверного флага, хотя прямо сейчас не буду утверждать наверняка. Соответственно в показанном виде мы попросту воспроизвели то, что в движке было изначально. Теперь есть два выбора:
1. Заменить эту логику. Строку удаляем, тем самым игнорируя значение серверного флажка (предположительно). Вместо этого ставим что-то своё, к примеру return false, что будет означать, что объект означенного класса никогда не перейдёт из онлайна в оффлайн (разумеется до тех пор, пока на одном уровне с актором).
2. Дополнить эту логику. Можно поставить некий код, который при каких-то условиях будет переходить в оффлайн по нашему условию, а в других условиях по серверному флажку. Как-то так:

function se_artefact:can_switch_offline()
    if <какое-то скриптовое условия> then
        return false
    end
    return cse_alife_item_artefact.can_switch_offline( self )
end
  • Нравится 1
 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

@Dennis_Chikin, т.е. как пустая функция? Это похоже на заглушку, наверняка результат копипасты. Заглушка наверное не нужна сама по себе. С другой стороны и вреда особенного нет.

 

Насчёт дубликата. Скорее всего баг, возможно результат всё той же копипасты. Срабатывать будет вторая функция. Вот смотри, такой код:



function generic_object_binder:reload(section) 
end

Является синтаксическим сахаром для вот такого:



generic_object_binder.reload = function(self, section) end

т.е. сделав это два раза мы просто переписываем поле reload. Естественно, там будет результат от второй записи.

Изменено пользователем ColR_iT
 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

KD87,

 

 

В оригинальной игре два Кругловых - один на ДТ, другой на Янтаре для симуляции одновременного с игроком перехода на Янтарь

Я думаю, что только для симуляции одновременности так и сделано, поскольку в целом неписи с уровня на уровень ходят. Однако, единственный штатный метод отправить непися на другую локацию через скрипты - это используя смарты. Когда непись прописывается в смарт, то ему выдаётся работа, работа в смарте (это не работа в гулаге) - это просто идти в точку пути, а точка эта может быть и на другом уровне, так что непись туда и топает при необходимости переходя в оффлайн и идя по геймнодам. Инициируется это всё скриптами, движок там только автоматически вызывает скриптовые функции. Однако, сам метод получается ограниченный. Требуется смарт, требуется прописать в него непися, требуется заранее подготовить пути.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

Да, вопрос не до конца понятен.

 

@abramcumner, удаление идёт не по id, а по ссылке на объект. Т.е. alife():release(server_object, true)

  • Нравится 1
 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

@Dennis_Chikin,

Ну если честно запутал вконец. Удаляешь по имени, затем ищешь по id. Откуда имя взялось, откуда id? В приведённом выше фрагменте ничего такого нет. Там присутствуют аж две ссылки на серверный объект: self.se_smart_terrain и server_object. Вторая - это ссылка на базовый, не все методы доступны, потому и получаем объект повторно по id, Для удаления однако годятся обе ссылки. Зачем ещё что-то по имени получать?

 

Вместе с клиентским объектом удалить не получится, по-любому придётся ждать завершения жизненного цикла клиентского объекта. Сразу после удаления клиентский ещё можно будет найти с помощью level.object_by_id(). А вот если сразу после удаления можно найти серверный, то либо удалял не тот объект, либо удаление не сработало.

 

Кстати, а зачем удалять смарт? Не лучше ли отключить?

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

Dennis_Chikin,

 

Через 15 секунд - вылет. db.add_smart_terrain() получил из binder'а nil

Поставь в bind_smart_terrain.script затычку. Если серверного объекта нет, то не биндить. Типа такого

function bind( obj )
	if not alife():object(obj:id()) then return end
	...
 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение

почему не передавать сразу функцию:

Встречный вопрос. Как таймер узнает после загрузки игры, какую функцию ему передали до этого?
 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Поделиться этим сообщением


Ссылка на сообщение
  • Недавно просматривали   0 пользователей

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
×
×
  • Создать...