Алгоритмы, Наработки и Способности
Способ реализации:
cJass
Тип:
Наработка
Эта наработка позволяет получить доступ к тени и кругу выделения юнитов/предметов, а также текстуре земли зданий.

Принцип работы

На самом деле image и ubersplat — не handle, а индекс от массива, отсчет в котором ведется с нуля.
Пустому объекту соответствует значение -1, а null(0) ссылается на первый элемент.
Переменные, содержащие ссылки на эти типы, не нуждаются в обнулении.
При создании, выдается первый свободный слот, который, после освобождения, может быть сразу переиспользован.
Следующий код выведет на экран "equal":
раскрыть
image a = CreateImage(...)
DestroyImage(a)
image b = CreateImage(...)

if a == b then
	BJDebugMsg("equal")
else
	BJDebugMsg("not equal")
endif
В результате создания и последующего уничтожения объекта, получается ссылка, которая указывает на следующий, пока не созданный.
Если после обретения подобной ссылки, игра создаст что-либо (круг выделения, например), её владелец получит контроль над новым объектом.
Файл текстуры нельзя менять напрямую, но можно пересоздать объект. Он будет занимать тот же слот, что и раньше, если все предыдущие слоты будут заняты, иначе придется заполнить дыры в таблице временными объектами (что уже делает готовая функция).
Создание предмета со скрытой тенью
image shadow = CreateImage(...)
DestroyImage(shadow)
CreateItem(...)
SetImageColor(shadow, 0, 0, 0, 0)

Код

ImageUtils
library ImageUtils

constant int IMAGE_TYPE_INVALID = -1
constant int IMAGE_TYPE_SHADOW = 0
constant int IMAGE_TYPE_SELECTION = 1
constant int IMAGE_TYPE_INDICATOR = 2
constant int IMAGE_TYPE_OCCLUSION_MASK = 3
constant int IMAGE_TYPE_UBERSPLAT = 4
constant int IMAGE_TYPE_TOPMOST = 5

private constant string dummy_texture = "ReplaceableTextures\\CommandButtons\\BTNWallOfFire.blp"

private image CreateDummyImage()
{
    return CreateImage(dummy_texture, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMAGE_TYPE_SELECTION)
}

// 0 вернет первое свободное изображение, 1 — второе и т.д
image GetFreeImage(int offset)
{
    image images[]
    
    for (int i = 0; i < offset; i++)
    {
        images[i] = CreateDummyImage()
    }
    
    image result = CreateDummyImage()
    DestroyImage(result)
    
    for (int i = 0; i < offset; i++)
    {
        DestroyImage(images[i])
    }
    
    return result
}

void RecreateImage(image img, string file, real sizeX, real sizeY, real sizeZ, real posX, real posY, real posZ, real originX, real originY, real originZ, integer imageType)
{
    DestroyImage(img)
    
    image images[]
    int count = 0
    
    loop
    {
        image i = CreateDummyImage()
        
        if (i == img) {
            DestroyImage(i)
            break
        } else {
            images[count++] = i
        }
    }
    
    CreateImage(file, sizeX, sizeY, sizeZ, posX, posY, posZ, originX, originY, originZ, imageType)
    
    for (int i = 0; i < count; i++)
    {
        DestroyImage(images[i])
    }
}

void RecreateImageCentered(image img, string file, real sizeX, real sizeY, real sizeZ, real posX, real posY, real posZ, integer imageType)
{
    RecreateImage(img, file, sizeX, sizeY, sizeZ, posX, posY, posZ, sizeX/2, sizeY/2, sizeZ/2, imageType)
}

private ubersplat CreateDummyUbersplat()
{
    return CreateUbersplat(0, 0, "NGOL", 0, 0, 0, 0, false, false)
}

// 0 вернет первую свободную текстуру земли, 1 — вторую и т.д
ubersplat GetFreeUbersplat(int offset)
{
    ubersplat splats[]
    
    for (int i = 0; i < offset; i++)
    {
        splats[i] = CreateDummyUbersplat()
    }
    
    ubersplat result = CreateDummyUbersplat()
    DestroyUbersplat(result)
    
    for (int i = 0; i < offset; i++)
    {
        DestroyUbersplat(splats[i])
    }
    
    return result
}

void RecreateUbersplat(ubersplat splat, real x, real y, string name, integer red, integer green, integer blue, integer alpha, boolean forcePaused, boolean noBirthTime)
{
    DestroyUbersplat(splat)
    
    ubersplat splats[]
    int count = 0
    
    loop
    {
        ubersplat s = CreateDummyUbersplat()
        
        if (s == splat) {
            DestroyUbersplat(s)
            break
        } else {
            splats[count++] = s
        }
    }
    
    CreateUbersplat(x, y, name, red, green, blue, alpha, forcePaused, noBirthTime)
    
    for (int i = 0; i < count; i++)
    {
        DestroyUbersplat(splats[i])
    }

}

endlibrary
ImageStructs
library ImageStructs uses ImageUtils

struct Unit
{
	unit object
	image shadow
	image cyrcle
	
	static thistype create(player owner, int id, float x, float y, float face)
	{
		thistype this = thistype.allocate()
        
		this.shadow = GetFreeImage(0)
		this.object = CreateUnit(owner, id, x, y, face)
		this.cyrcle = GetFreeImage(0)
        
		SelectUnit(this.object, true)
		SelectUnit(this.object, false)
        
        return this
	}
}

struct Building
{
	unit object
    image uimage
	ubersplat usplat
	image cyrcle
	
	static thistype create(player owner, int id, float x, float y, float face)
	{
		thistype this = thistype.allocate()
        
        this.uimage = GetFreeImage(0)
		this.usplat = GetFreeUbersplat(0)
		this.object = CreateUnit(owner, id, x, y, face)
		this.cyrcle = GetFreeImage(0)
        
		SelectUnit(this.object, true)
		SelectUnit(this.object, false)
        
        return this
	}
}

struct Item
{
	item object
	image shadow
	
	static thistype create(int id, float x, float y)
	{
		thistype this = thistype.allocate()
        
		this.shadow = GetFreeImage(0)
		this.object = CreateItem(id, x, y)
        
        return this
	}
}

endlibrary

Использование

Unit u = Unit.create(Player(0), 'hfoo', 0, 0, 0)

// ** Сокрытие круга выделения **
// Смена цвета не поможет, так как игра постоянно его переустанавливает.
SetImageType(u.cyrcle, IMAGE_TYPE_INVALID)

// Изменение текстуры круга выделения
RecreateImageCentered(u.cyrcle, "path\\to\\texture", 80, 80, 80, 0, 0, 0, IMAGE_TYPE_SELECTION)

// Прячем тень
SetImageColor(u.shadow, 0, 0, 0, 0)

// Обращение к самому юниту
SetUnitInvulnerable(u.object, true)

u.destroy()

Скриншот

`
ОЖИДАНИЕ РЕКЛАМЫ...
0
26
7 лет назад
0
Круто! Только как этим пользоваться, я не знаю)
И для чего нужна скрытая тень?
5
14
7 лет назад
5
для чего нужна скрытая тень?
Был вопрос, в котором хотели спрятать тень предмета. Не знаю зачем, но раз спросили, значит нужно. Ответ на тот вопрос, собственно, и сподвиг меня проверить: как это работает и на что оно еще способно.
0
26
7 лет назад
0
IceFog, спасибо за добавление информации о применении! Что в секции Код, надо поставить в код карты?
2
14
7 лет назад
2
Скачай карту и скопируй все триггеры, кроме тех, что находятся в папке demo.
Из ресурса тоже можно взять код, но он здесь для тех, кому лень качать или у кого нет редактора.
0
27
6 лет назад
Отредактирован MpW
0
что-то наработка не хорошая. скачал, открыл карту в редакторе, запустил карту. Загрузилась (интерфейс показался, не было ни войск, одна земля, только значок мыши в центре карты в виде стрелочек, только не зеленого как обычный, а серый), и тут же подвисло все на этом моменте. Лишь музон играл. Никак не мог закрыть. Диспетчер даже не помог. Что-то не так делаю?
0
14
6 лет назад
0
Steal nerves, сомневаюсь, что такое может происходить из-за скрипта.
Другие карты не глючат?
Локальные файлы включены?
Попробуй запустить напрямую через игру. Может быть, твой редактор при сохранении ломает что-то.
0
27
6 лет назад
Отредактирован MpW
0
IceFog, не глючат. Единственное, что хотел сказать у меня постоянно ОС виндовс 10 высылает мини-окно с ошибкой драйвера. Просто драйвера обновил, и что-то ОС не нрав. Смело игнорирую. Может быть из-за этого? Ноутбук просто новый.
Напрямую только что через игру включал, одно и то же. Локальные включены. Другие карты не глючат, идут нормально.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.