XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > StarCraft (только чтение)> Галактическая академия
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

 
yellyex

offline
Опыт: 4,267
Активность:
Отследить номер массива
Здравствуйте!
У меня есть целочисленная переменная Здоровье равная 100 единицам. Я её преобразовываю в действительную и даю значение целочисленной здоровью морпеха. Вобщем, если кратко, то здоровье морпеха делаю равным значению целочисленной. Сделано это для того, чтобы все процессы урона и остальных действий происходили сначала в арифметических действиях, а результат уже давался юниту. То есть переменная Damage и Health. Health (Юнита 1) - Damage (Юнита 2) = Health (Юнита 1) И устанавливаем результат на Юнита 1. С этим разобрались. Так вот в чём проблема:
У нас есть Здоровье и Урон в массиве из 10 со значениями 100 и 10. На карте последовательно появляются юниты и каждому в порядке очереди присваиваются переменные Здоровье и Урон соответственно их номеру. Первому появившемуся юниту Здоровье [1] и Урон [1] и так далее. Далее идёт триггер боя:
Событие: Юнит атакован.
Условие: И:
Атакованный юнит 7 (например)
Атакующий юнит 2 (тоже например:)
Действие: Здоровье[7] (100) минус Урон[2] (10) равно Здоровье[7] (90).
Задать Юниту[7] Здоровье Преобразовать из целочисленной в действительную Здоровье[7].
Сделать вручную все триггеры взаимодействия каждого юнита с каждым я могу. Но представте, что юниты на карте то и дело появляются и их далеко не 10. Соответственно у меня возник вопрос: Как можно отследить момент, когда происходит событие Любой юнит атакован и при этом узнать под каким номером массива Атакующий юнит и под каким номером массива Атакованный юнит, чтобы в дальнейшем произвести арифметическое действие Здоровья с Уроном этих юнитов?
Старый 15.01.2013, 12:00
H
hello world
offline
Опыт: 130,725
Активность:
wtf?
Что ты пытаешься сделать и почему таким странным образом.
Скажи конечную цель, я кажу как это сделать одной функцией и без массивов.
Старый 15.01.2013, 13:00
yellyex

offline
Опыт: 4,267
Активность:
Текущий вариант у меня сделан методом перебора в ручную. Во всех условиях Атакованного и Атакующего юнита перебраны все номера массивов этих юнитов. Если один триггер, то он будет тяжёлым (сильно загруженным и время на его выполнение будет долгим). Ну и второй для каждого юнита свой триггер. Тоже самое как в первом варианте, только триггеров очень много, но они все лёгкие. И самое главное оба варианты не динамические. То есть нелья взять номер массива Если атакованный юнит, то массив n, и Если атакующий юнит, то его массив p. Как взять массивы атакованного и атакующего юнита мне не понятно.
Старый 15.01.2013, 13:01
Doc

offline
Опыт: 63,163
Активность:
Черт возьми прям расписываешь как Пушкин.
native void     UnitSetCustomValue (unit inUnit, int inIndex, fixed inVal);
native fixed    UnitGetCustomValue (unit inUnit, int inIndex);
Старый 15.01.2013, 13:10
yellyex

offline
Опыт: 4,267
Активность:
Doc:
Черт возьми прям расписываешь как Пушкин.
native void     UnitSetCustomValue (unit inUnit, int inIndex, fixed inVal);
native fixed    UnitGetCustomValue (unit inUnit, int inIndex);
А ты как Менделеев. Я вот нифига не понял :) Сейчас карту выложу.
Старый 15.01.2013, 13:11
H
hello world
offline
Опыт: 130,725
Активность:
Я так и не понял что ты хочешь сделать и зачем делать по триггеру на каждого юнита с перебором по массиву.
Старый 15.01.2013, 13:12
yellyex

offline
Опыт: 4,267
Активность:
Чтобы сделать каждого юнита на карте индивидуальными и обращаться к его характеристикам (Здоровье, Урон, Броня и так далее). А если характеристики будут одни на всех, то получится бред. Я отнимаю здоровье у юнита, а у какого не понятно?
Старый 15.01.2013, 13:19
Doc

offline
Опыт: 63,163
Активность:
Кто первый мне скажет, что я "разделом ошибся"?
Старый 15.01.2013, 13:19
Faion
Noblesse Oblige
offline
Опыт: 30,395
Активность:
Берем это и это .
С помощью 1-го присваиваем индекс объекту, во 2-ом храним данные.
Старый 15.01.2013, 13:23
yellyex

offline
Опыт: 4,267
Активность:
Вот карта. Юнит 1 атакует Юнита 2. Doc, ты не ошибся. Тут вопрос не по разделу, а вообще по программированию.
Старый 15.01.2013, 13:24
Faion
Noblesse Oblige
offline
Опыт: 30,395
Активность:
Тьфу блин, это ск2.
Старый 15.01.2013, 13:26
yellyex

offline
Опыт: 4,267
Активность:
Спасибо парни! Сейчас почитаю статьи, посмотрю что да как.
yellyex добавил:
Вот то, что у меня сейчас.
Старый 15.01.2013, 13:44
Doc

offline
Опыт: 63,163
Активность:
Мы все итак уже поняли.
Перечитай еще раз мои посты.
Тебе нужно хранить "внутри юнита" его номер и при атаке доставать его.
Старый 15.01.2013, 13:59
ScorpioT1000
Работаем
offline
Опыт: отключен
native void     UnitSetCustomValue (unit inUnit, int inIndex, fixed inVal);
native fixed    UnitGetCustomValue (unit inUnit, int inIndex);
Старый 15.01.2013, 14:44
yellyex

offline
Опыт: 4,267
Активность:
Doc:
Черт возьми прям расписываешь как Пушкин.
native void     UnitSetCustomValue (unit inUnit, int inIndex, fixed inVal);
native fixed    UnitGetCustomValue (unit inUnit, int inIndex);
А когда у меня юнит появляется, я записываю в переменную типа юнита с индексом его номер. То есть 1,2,3,4 и 5. То есть номера уже есть. Я не понял, как брать номер юнита, когда происходит событие атаки? (Статьи ещё не читал)
Старый 15.01.2013, 17:42
yellyex

offline
Опыт: 4,267
Активность:
Объясняю всю картину целиком. На карте будут появляться много премного разных юнитов. Каждый юнит будет содержать две целочисленные переменные Здоровье и Урон. Когда эти юниты будут атаковать друг друга, все действия будут просиходить в триггерах, а не в данных. То есть, как я уже писал выше. Спавнится юнит, я ему даю переменную Здоровье и Урон с его номером спавна, например 95 юнит. Соответственно и Здоровье и Урон у него тоже должны быть его номером 95, чтобы при взятии их в арифметические действия Здоровье минус Урон, они различались.
Старый 15.01.2013, 18:02
ScorpioT1000
Работаем
offline
Опыт: отключен
смотри я тебе показываю, есть какаято база начальных значений, допустим 3 массива (это как аналог базы РО)
int MyCustomHealth[];
int MyCustomDamage[];
int MyCustomHealRate[];
// тут может быть еще много
массив потому что может быть разные типы юнита, предположим типа "mariner" это номер 666
заполняем базу данных для типов юнитов, представь в ро есть разные равкоды (типы юнитов) 666, 667, мы каждому задаем поля
// маринер
MyCustomHealth[666] = 100500;
MyCustomDamage[666] = 123;
MyCustomHealRate[666] = 0; // не умеет лечить
// лекарь
MyCustomHealth[667] = 100500;
MyCustomDamage[667] = 10;
MyCustomHealRate[667] = 50; // лечит 50/сек

дальше база данных тип юнита из нашей базы - тип юнита в ск2
string MytypeToSctype[];
int MytypeToSctype_MAX = 668; // максимум

// заполняем бд мойтип - типск2, вызвать при инициализации карты
void MytypeToSctype_Init() {
	MytypeToSctype[666] = "Marine";
	MytypeToSctype[667] = "blablabla";
}

// функция Mytype to Sctype
string MytypeToSctype(int mytype) {
	return MytypeToSctype[mytype];
}

// функция Sctype to Mytype
int SctypeToMytype(string sctype) {
	int i = 0;
	while(i < MytypeToSctype_MAX) {
		if( MytypeToSctype[i] == sctype ) { return i; }
		i = i + 1;
	}
	return 0;
}

дальше есть набор констант, чтобы не тыкаться со всякими твоими 95 юнит, делают перечисления:
const int MY_CUSTOM_HEALTH = 0;
const int MY_CUSTOM_DAMAGE = 1;
const int MY_CUSTOM_HEAL_RATE = 2;
// тут может быть еще много
они упрощают понимание, где какое поле, иначе запутаешься в цифрах
подготовим функцию создания юнита
unit MyCreateUnit(fixed x, fixed y, int utype)
{
	// вот как utype превратить в строку-тип из РД это надо придумать
	// вызываем стандартную функцию создания юнита, я не помню уже
	unit u = CreateUnit( не помню, MytypeToSctype(utype), x, y, не помню )

	UnitSetCustomValue(u, MY_CUSTOM_HEALTH, MyCustomHealth[utype]);
	UnitSetCustomValue(u, MY_CUSTOM_DAMAGE, MyCustomDamage[utype]);
	UnitSetCustomValue(u, MY_CUSTOM_HEAL_RATE, MyCustomHealRate[utype]);
	// тут может быть еще много
}
дальше при создании юнита u ты делаешь (помним что тип - маринер - 666, как определять какой тип какому номеру это другой вопрос):
любой юнит = MyCreateUnit(0, 0, 666);

подготовим функцию для атаки
меняем здоровье у юнита u
тут можно все сделать еще быстрее, но для наглядности я создал переменные
void MyUnitAttack(unit u, unit w) {
	int uCurrentHealth = UnitGetCustomValue(u, MY_CUSTOM_HEALTH);
	int uAttackerDamage = UnitGetCustomValue(w, MY_CUSTOM_HEALTH);
	// вычесть из жизни u дамаг w
	uCurrentHealth = uCurrentHealth - uAttackerDamage;
	// проверить на ноль
	if (uCurrentHealth <= 0) {
		// убить, закопать
		UnitSetCustomValue(u, MY_CUSTOM_HEALTH, 0);
		KillUnit(u); // не помню как функция называется
	} else {
		// иначе записать "в юнита" результат наших расчетов
		UnitSetCustomValue(u, MY_CUSTOM_HEALTH, uCurrentHealth);
	}
}
дальше при атаке, например случился удар по юниту u (current) - от юнита w (damager)
вызываем нашу функцию
// тут как бы сработало событие итп мы знаем кто и кого
MyUnitAttack(кто атакует, кого атакуют);

вот пример как обратно вылечивать
смотри выше я дописал 3 показатель
теперь путь у нас лекарь будет типом 667
дальше при создании лекаря u ты делаешь, все так же как у маринера, потому что мы все сделали в базе типов юнитов
любой юнит = MyCreateUnit(0, 0, 667);
дальше сделаем нехитрое лечение, пускай просто каждую секунду берутся все лекари на карте, не знаю как, пусть текущий будет uh и берутся все "свои" в какойто области, не важно
дальше для каждого такого "своего" uu c типом UU (666 или 667 или еще как это другой вопрос)
int uuCurrentHealth = UnitGetCustomValue(uu, MY_CUSTOM_HEALTH);
// сверить, не ранен ли, т.е. ТЕКУЩАЯ жизнь не меньше ИСХОДНОЙ
if (  uuCurrentHealth < MyCustomHealth[UU] ) {
	// вылечить на рейт лекаря uh
	uuCurrentHealth = uuCurrentHealth  + UnitGetCustomValue(uh, MY_CUSTOM_HEAL_RATE);

	// тут просто чтобы не зашло за пределы
	if( uuCurrentHealth > MyCustomHealth[UU] ) {
		uuCurrentHealth = MyCustomHealth[UU] ;
	}
}

Отредактировано ScorpioT1000, 15.01.2013 в 19:46.
Старый 15.01.2013, 18:20
Харгард
Epic
offline
Опыт: 7,829
Активность:
Вместо массивов используй пользовательский тип данных.
Их заполнять намного удобней. И полей может быть сколько угодно
Старый 15.01.2013, 22:53
yellyex

offline
Опыт: 4,267
Активность:
Харгард:
Вместо массивов используй пользовательский тип данных.
Их заполнять намного удобней. И полей может быть сколько угодно
Это в дате или где?
Старый 15.01.2013, 23:06
Харгард
Epic
offline
Опыт: 7,829
Активность:
Да в дате.
Сперва создаешь свой тип данных (эдакий аналог структуры из С++ или просто таблица БД)
Затем там же заполняешь. Ссылку на юнита/его тип, имя, иконка, пол, ориентация и прочие параметры.
А уже триггером, при помощи Фор Ич, перебираешь их, сравнивая триггерного юнита с User Data (ТИП, Instance, ПОЛЕ, 1)) пока не найдешь нужный тебе.
Старый 16.01.2013, 00:21

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 23:57.