Forum

QuakeC puzzles

Discuss programming in the QuakeC language.

Moderator: InsideQC Admins

QuakeC puzzles

Postby OneManClan » Fri Nov 18, 2011 12:38 pm

[EDIT: I originally used 'dremove()' below, which I forgot is specific to CustomTF. I've changed the 'dremove()' to 'remove()' which is essentially the same thing. Sorry for any confusion ('dremove' is just 'remove()' with extra code to check that the entity hasn't already been removed, and isn't a player etc)]

QuakeC Puzzle 1: 'self' issues
Code: Select all
void () Func_1 =
{
   local entity foo;
   foo = spawn();

   foo.think = Func_2;
   foo.nextthink = time + 1;
};

void () Func_2 =
{
remove(self);
   Func_3();
};

void () Func_3 =
{
// Q: who is self?
      
};

=========================================
QuakeC Puzzle 2: 'find'
Code: Select all
void () Func_1 =
{
   local entity foo;
      foo = spawn();
      foo.classname = "puzzle";
      .
      .

};

void () Func_2 =
{
local entity e;
e = find(world, classname, "puzzle");
remove(e); // Q: did we just delete foo?

};
Last edited by OneManClan on Fri Nov 18, 2011 4:44 pm, edited 4 times in total.
OneManClan
 
Posts: 243
Joined: Sat Feb 28, 2009 2:38 pm

Re: Quake puzzles

Postby ceriux » Fri Nov 18, 2011 1:47 pm

puzzle 1 is either no one or foo right? lol cause foo was removed.
User avatar
ceriux
 
Posts: 2223
Joined: Sat Sep 06, 2008 3:30 pm
Location: Indiana, USA

Re: QuakeC puzzles

Postby Spike » Fri Nov 18, 2011 3:03 pm

1:
I don't know what's special about dremove, so I can't answer that one fully.
self refers to the entity spawned in Func_1, but either it has been removed, or its think function has been set to cause it to be removed. Either way, you can still assign to its fields... but you really shouldn't do so.

2:
the dremove call removes (I assume, I've not seen the dremove function itself) an entity which was probably spawned inside Func_1. If Func_1 was called multiple times then it'll remove just one of those entities (per time Func_2 is called). If Func_2 is called more than Func_1 was called, the whole thing will break.
I'm careful to not say that "it removes 'foo'" because, technically, it doesn't. Once Func_1 returns, foo leaves scope, and nothing is known as that particuar 'foo' any more.
So no, it doesn't 'remove foo' because 'foo' no longer exists anyway, but the entity that foo refered to does still exist, and its that entity which is removed, rather than simply 'foo'.
Many times you'll see someone refer to it as though Func_2 does remove Func_1, quite simply they're being lazy, and are technically incorrect. However that distinction is not a major one, and is usually not actually relevent as any experienced programmer will know what was actually meant even if what is said is a lie, so its quite common to say it, or even think that way. Just remember that its not actually true when you do have multiple instances of 'foo' entities at the same.
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Re: QuakeC puzzles

Postby WickedShell » Fri Nov 18, 2011 7:46 pm

This seems like a good chance to clarify. I've been operating on the assumption that spawn() is essentially malloc(sizeof(struct_entity)), and that remove() is essentially free(). Is there anything fundamentally wrong with looking at it this way?
WickedShell
 
Posts: 24
Joined: Mon Feb 14, 2011 5:16 am

Re: QuakeC puzzles

Postby Spike » Sat Nov 19, 2011 2:24 am

aye, spawn as malloc and remove as free is basically how it is. with the 'entity' type being just a pointer to it.

an entity can get reused by spawn() 2 seconds after being remove()d, and it is considered valid to be able to read or even write the fields of an entity that was freed, if only because the engine is to lazy to block it and too much code already does such that the engine couldn't block it and still be used. Memory reuse is a problem in C, too, but one that is more likely to result in page faults, so yeah, there's no real difference.
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Re: QuakeC puzzles

Postby Qrv » Sat Nov 19, 2011 3:10 am

Puzzle 1 :

I'd be inclined here to say self = world, as theres no entity.

Puzzle 2 :

It'l remove the entity spawned earlier. Although not known as foo by that point, that entity should be removed.


Although both functions say "local entity", from my own experience, that means nothing in regards to programming terms. I posted code in another thread that uses "local entity" to spawn bubbles to help Nahuel with something, although spawned locally, they seem to exist globally.
I'm looking for a Mapper, Modeller/Animator and a Sound effect/Music person, to work on an exciting project. PM Me here, or catch me on IRC for further info.
Qrv
 
Posts: 45
Joined: Thu Oct 20, 2011 7:43 am
Location: Stuck in a Slipgate.

Re: QuakeC puzzles

Postby frag.machine » Sun Nov 20, 2011 10:37 pm

Qrv wrote:Puzzle 1 :

I'd be inclined here to say self = world, as theres no entity.

Puzzle 2 :

It'l remove the entity spawned earlier. Although not known as foo by that point, that entity should be removed.


Although both functions say "local entity", from my own experience, that means nothing in regards to programming terms. I posted code in another thread that uses "local entity" to spawn bubbles to help Nahuel with something, although spawned locally, they seem to exist globally.


That's correct. The local entity means that once outside the function, the entity reference is lost, but not the entity itself.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
User avatar
frag.machine
 
Posts: 2090
Joined: Sat Nov 25, 2006 1:49 pm

Re: QuakeC puzzles

Postby necros » Mon Nov 21, 2011 2:43 am

1. self is foo
remember, a removed entity's pointer is still locked to the entity for ~2 seconds, afterwhich the entity pointer is freed for use with another entity. if you spawned another entity 3 seconds later, it would probably take this edict slot, and self (if it was called later on) would be this new entity.
also, not all entity fields are cleaned out at remove() time, only obvious ones like .model, .solid, maybe a few others. if you use an engine that displays bboxes, you can watch discarded entities who have bboxes accumulate at the origin (0,0,0).
spawn() is the only point where all fields are cleared.
this is important because if you had something like:
self.owner = someEntity;

and then you removed someEntity and then later did a check:
if (!self.owner)

it would return true.

2. yes
this one is straightforward.
necros
 
Posts: 77
Joined: Thu Dec 16, 2004 10:32 pm


Return to QuakeC Programming

Who is online

Users browsing this forum: No registered users and 1 guest