Неопределенность

Темы, связанные с проектированием и программированием roguelike-игр

Модераторы: Sanja, Максим Кич

Ответить
EditorRUS
Сообщения: 141
Зарегистрирован: 05 янв 2012, 05:16
Откуда: Нижний Тагил

Неопределенность

Сообщение EditorRUS » 16 авг 2012, 12:00

Не совсем относится к рогалико-писанине, но суть такая же.
Итак, есть некоторый код на языке DM:

Код: Выделить всё

obj/item/flasher/Pulse()
	if(charge >= 100)
		flick("FlashPulse",src)
		for(var/mob/creature/victim in viewers(3,src))
			if(haseye(victim) && !isblind(victim))
				victim.flash(src)
Тут есть некий объект "Флешер", который при вызове метода Pulse() получает всех мобов типа creature с зоны 3*3 от места src.
Так вот, аналог на дельфях(примерно, пишу в блокноте):

Код: Выделить всё

type
	flasher = class(item)
	public
		procedure Pulse();
		begin
		if(charge >= 100) then
			begin
				flick("pulse", self)
				var victim:creature;
				foreach(victim in viewers(3,self))
					if((haseye(victim)) and (not isblind(victim))) then victim.flash(self);
			end;
		end;
	end;

Код: Выделить всё

foreach(victim in viewers(3,self))
Вот эта строчка проблемная. Дело в том, что функция viewers(radius, source) возвращает все объекты, который "видят" source. Ключевое слово - все. В коде по языку DM возвратятся именно все объекты типа creature, а в коде по дельфи возникнет ошибка несовместимости типов. Так вот, каким образом узнать, что нужно возвращать?

Аватара пользователя
kipar
Сообщения: 2120
Зарегистрирован: 10 мар 2010, 13:16
Откуда: Москва

Re: Неопределенность

Сообщение kipar » 16 авг 2012, 13:21

Как-то так

Код: Выделить всё

for Obj in Viewers(3, src) do
  if Obj.InheritsFrom(TCreature) then
  begin
    Victim := TCreature(Obj); 
    Victim.flash;
  end;
Правда чтобы работал for..in Viewers должна возвращать массив или IEnumerable. А, ну и Дельфи должен быть не младше 2007 (или когда там for..in появился).
Если без этого, то надо переделать viewers чтобы на входе принимал функцию-коллбек, но идея останется та же - сначала проверить объект на соответствие типу, потом привести его к этому типу.

---
Ну и можно функцию Viewers доработать, чтобы на входе принимала нужный тип, тогда эту проверку можно внутрь функции убрать. Правда чтобы убрать не только проверку, но и приведение к типу придется использовать generics из Delphi XE и выше.

EditorRUS
Сообщения: 141
Зарегистрирован: 05 янв 2012, 05:16
Откуда: Нижний Тагил

Re: Неопределенность

Сообщение EditorRUS » 16 авг 2012, 15:05

В целом я уже придумал решение этой проблемы, я внезапно вспомнил, что в коде DM ещё используются такие конструкции:

Код: Выделить всё

for(var/atom/A in viewers(3,src))
	if(istype(A,/mob/creature))
		var/mob/creature/T = A
		if(haseye(T) && !isblind(T))
			T.flash(src)
Но т.к. пишут на DM в другом стиле, я привык использовать как уже в примере выше.

Накалякал в своем паскале.нет сию конструкцию:

Код: Выделить всё

type
  Atom = class
  end;
  Obj = class(Atom)
  end;
  Item = class(Obj)
  end;

begin
  var A := new Atom;
  var O := new Obj;
  var I := new Item;
  writeln(I is Atom);
end.
Выдалось true, значит is таки работает с подклассами.

Итого фикс теперь таков:

Код: Выделить всё

//Begin
begin
	var F:Atom;
	foreach(F in viewers(3,self))
	begin
		if (F is Creature) then
			if((haseye(F)) and (not hasblind(F))) then
			begin
				F.flash();
			end;
	end;
end;
//End
Надо избавляться от привычки писать сначала на форум, а потом легко узнавать решение... впринципе тему можно закрыть.

Ответить

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 38 гостей