Сделал мод (скачать можно здесь) с рандомным спауном червей для одной карты. Увы, универсальный скрипт написать не могу, т.к. "ориентиры" (reference points, далее могу звать просто точками), подходящие для размещения червей (находятся на земле, свободны от зданий), приходится выискивать вручную. Хотелось бы получать их массив (хотя бы всех) средствами игры. Использовать ориентир "Random", который в некоторых скриптах юзается для указания места для мины/бочки, не получается - все черви размещаются в одном месте.
Часть точек рандомно заполняется телепортами, остальные используются как их точки назначения. После использования телепорт исчезает, также его можно разрушить и червь попадет на его место. За ход можно использовать сколь угодно телепортов.
Код
-- Random Spawn & Teleports mod -- by 4erver aka poxyxol96 -- http://wormsforts.ucoz.ru
function InitialiseLevel() LoadLevel("landscapes/MP/ScriptPack/M4.xom",true) FreeBuildPos = {"001", "003", "005", "006", "007", "008", "009", --7 --массив номеров buildHere для свободных мест --после удаления всех зданий (кроме маяков и крепостей) "0010", "0011", "0012", "0015", "0016", "0017", "0018", "0019", --7+8=15 "0020", "0021", "0022", "0024", "0025", "0026", "0027", "0028", --15+8=23 "0039", "0040", "0042", "0043", "0044", "0045", "0114", --23+7=30 --ниже указаны адреса башен: --"0030", "0034", "0035", "0037", "0056", "0120", "0067", "0070", "0071", "0072", "0108", "0109" } --30+12=36 --считаю число элементов массива --т.к. функции #, table.maxn и table.getn не работают :[ OtherWfRef = { "000", "001", "002", "000Outro" } --прочие wfRef (кроме CrateDrop, *Grail*), 4 шт. hasObject = {} --массив, хранящий инфу о наличии объекта на точке numPoints = 58 --число всех точек end
function PointByN(N, markObject, AddCrateId) --дать название точки по номеру (1-58) if markObject ~= nil then hasObject [N]= markObject end --как пометить наличие объекта if AddCrateId then crate.CrateId = N end --дать ящику номер if N <= 18 then return "wfRefCrateDrop"..N elseif (N > 18) and (N <= 54) then return "buildHere"..FreeBuildPos[N-18] elseif N > 54 then return "wfRef"..OtherWfRef[N-54] end end
function RandomPoint(markObject, AddCrateId) --дать название случайной точки local R = RandomRange(numPoints, true) while hasObject [r]do R = RandomRange(numPoints, true) end --чтоб не было неск объектов на 1 месте return PointByN(R, markObject, AddCrateId) end
function HideWormsNow() ObjData = GetDetailObjectData("holygrail") --скрыл измененный detail ObjData.IsVisible = false ObjData.IsCollidable = false RemoveBuilding( "buildHere0030" ) --убрал мешающие башни RemoveBuilding( "buildHere0034" ) RemoveBuilding( "buildHere0035" ) RemoveBuilding( "buildHere0037" ) RemoveBuilding( "buildHere0056" ) RemoveBuilding( "buildHere0120" ) RemoveBuilding( "buildHere0067" ) RemoveBuilding( "buildHere0070" ) RemoveBuilding( "buildHere0071" ) RemoveBuilding( "buildHere0072" ) RemoveBuilding( "buildHere0108" ) RemoveBuilding( "buildHere0109" ) if GetCurrentSchemeData().HotSeatTime == 500 then GetCurrentSchemeData().NumRandomMines = 0 end --откл мины при подготовке 5с if (GetCurrentSchemeData().Wins == 1) or (GetCurrentSchemeData().Wins == 3) then --при 1/3 раундах вкл тп local tpIndex = 1 --создание и размещение тп while tpIndex <= (numPoints - 16) do --используется число всех точек минус макс число червей if RandomRange(5, true) == 1 then --тп ставятся рандомно с опред шансом crate = CreateCrate() --создается триггер-ящик в виде мишени --при подборе которого происходит тп crate.Contents = kWF_TRIGGER_CRATE crate.NumContents = 1 -- amount in the crate use kWF_INFINITE_AMOUNT for infite crate.TeamDestructible = -1 -- -1 for all teams, otherwise the index of the team crate.WormCollectable = -1 -- -1 for all worms otherwise the index of the worm crate.TeamCollectable = -1 -- -1 for all teams, otherwise the index of the team crate.GroundSnap = true -- set to true for crate to be placed on the ground below spawn point. crate.FixedPosition = true -- set to true, crate will not move i.e. stays at spanw point crate.UXB = false -- whether crate is booby trapped crate.Destructible = true -- whether crate can be destroyed. crate.Pushable = false -- whether crate can be moved by weapons. crate.CollectableByPayload = false -- whether crate can be collected by roaming rounds e.g. rhino crate.Collectable = true -- whether crate can be collected) crate.Model = "Crate.Target" --модель - мишень crate.SpinBaby = true --мишень будет вращаться SpawnCrate( crate.Index, RandomPoint(true, true) ) --спавн end tpIndex = tpIndex + 1 end end if (GetCurrentSchemeData().Wins == 1) or (GetCurrentSchemeData().Wins == 2) then --при 1/2 раундах рандом спавн local hasObjectBackup = hasObject --бэкап массива доступности объектов т.к. можно будет тп на место спавна червя local playerIndex = 0 --размещение червей local wormIndex = 0 local player = GetPlayerData(playerIndex) while player.PlayerIndex ~= -1 do lastwormIndex = (wormIndex - 1) + player.NumberOfWorms while wormIndex <= lastwormIndex do MoveWorm( wormIndex, RandomPoint(true), false ) wormIndex = wormIndex + 1 end if playerIndex == 3 then break end playerIndex = playerIndex + 1 player = GetPlayerData(playerIndex) end hasObject = hasObjectBackup end end
function CrateCollected(CrateIndex,WormIndex) crate = GetCrateData(CrateIndex) if crate.Contents == kWF_TRIGGER_CRATE then --проверка на ящик-триггер MoveWorm( WormIndex, RandomPoint(), true ) hasObject[crate.CrateId] = false end collectgarbage() end
function CrateDestroyed(CrateIndex,WormIndex) --если уничтожить тп, червь переместится на его место crate = GetCrateData(CrateIndex) if crate.Contents == kWF_TRIGGER_CRATE then --проверка на ящик-триггер MoveWorm( WormIndex, PointByN(crate.CrateId, false), false ) end collectgarbage() end
Добавлено (25.03.2015, 03:10) --------------------------------------------- Игра со скриптом иногда вылетает (ну хотя бы сразу после загрузки карты, а не во время игры), причину пока что не знаю. Также червя может заспаунить рядом с миной. Хотя это не совсем так - спаунятся черви как обычно, на своих крепостях, а потом скрипт рандомно перемещает их на один из указанных ориентиров.
Возможно какой-то из ориентиров "глючный", тестил пока только массив OtherWfRef - там проблем нет. Однако до его добавления вроде как не вылетало (либо запускал слишком мало раз)
Вскоре кину новую версию, которая позволит ещё сильнее приблизить классический геймплей Worms - победить противника можно будет только убив всех его червей. Для этого надо будет убрать из инвентаря схемы башни.убрал, все равно это есть в фортпоте Вот код, ставится после строчки с возвращением крепостей:
Код
if GetCurrentSchemeData().Tower.Ammo == 0 then --для желающих получить классический геймплей Worms можно отключить урон крепостям --убрав из инвентаря схемы башни SetBuildingIndestructible("buildHere"..StrongholdPos[playerIndex+1], true) end
Добавлено (26.03.2015, 03:28) --------------------------------------------- Готово. Кстати, потестил все точки - "глючных" не нашёл, значит проблема в другом (возможно вообще в коде игры).
Добавлено (27.03.2015, 18:35) --------------------------------------------- Снял на видео тест мода в сингле.
4erveR, а что ты хочешь сделать с Worms Forts ? По-моему, если ты убираешь замки, то стоит переделать некоторые орудия, потому что они заточены для уничтожения крепости врага, а не стрельбы по червям, лазерная установка в видео. Ею по червю будет сложно попасть, а убить и подавно. I've heard of unisex but never had it
Joker, хочу сделать подобие классического геймплея Worms. Про твики оружия - особого желания нет, да и хз, получится ли тот же лазер изменить. Имхо лучше уж схему создать, где будет только более-менее пригодное для убийства червей оружие. Ещё там можно сделать задержку (или доступность только через ящики) слишком опасному червям оружию вроде носорога. Ну и прочие мелочи настроить в стиле обычного Worms (полностью здания убрать, например).
Сообщение отредактировал 4erveR - СБ, 28.03.2015, 07:07:18
Смог сделать универсальный код для всех чисел игроков. Неразрушаемые здания при отсутствии башен убрал, т.к. это можно сделать в вормпоте.
Код
playerIndex = 0 player = GetPlayerData(playerIndex) while player.PlayerIndex ~= -1 do CreateBuilding( kWF_BUILDING_STRONGHOLD, playerIndex, "buildHere"..StrongholdPos[playerIndex+1] ) --возвращение крепостей wormIndex = 0 while wormIndex < player.NumberOfWorms do R = RandomRange(3, true) if R == 1 then --спавн либо на некоторые wfRef либо на свободные buildHere --всё ищется и указывается вручную (открываем карту в хомвью, смотрим в Forts Exported Data) MoveWorm( playerIndex * 4 + wormIndex, "wfRefCrateDrop"..RandomRange(18, true) ) --повезло что много нумерованных wfRef --в частности wfRefCrateDrop1 - wfRefCrateDrop18 elseif R == 2 then MoveWorm( playerIndex * 4 + wormIndex, "buildHere"..FreeBuildPos[RandomRange(42, true)] ) --42 - число элементов FreeBuildPos elseif R == 3 then MoveWorm( playerIndex * 4 + wormIndex, "wfRef"..OtherWfRef[RandomRange(5, true)] ) --5 - число элементов OtherWfRef end wormIndex = wormIndex + 1 end if playerIndex == 3 then break end playerIndex = playerIndex + 1 player = GetPlayerData(playerIndex) end
Добавлено (27.11.2015, 15:06) --------------------------------------------- Немного улучшил скрипт - теперь несколько червей не могут спауниться в одной точке. Мб добавлю возможность отключения мин и добавления телепортов и тогда выложу.
Добавлено (27.11.2015, 20:35) --------------------------------------------- Объединил в итоге со скриптом телепортов (каждая опция отключаема: 1 раунд - вкл обе, 2 раунда - только рандом, 3 раунда - только тп), мины сделал отключаемыми (когда время на подготовку 5с, т.е. по умолчанию).
Добавлено (27.11.2015, 21:41) --------------------------------------------- [v11] Пофиксил вылеты, когда червей в команде меньше 4
Сообщение отредактировал 4erveR - ПТ, 27.11.2015, 21:10:10