Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Teleport and phase door

2 views
Skip to first unread message

Phil

unread,
Apr 28, 2004, 11:17:59 AM4/28/04
to
I know that phase door moves you a small amount in a random direction
and teleport the same but further.
How does Angband decide where you are going to end up? Are you more
likely to end up in a big open space than in a dead end corridor? Is
there a built in bias to dump you in the middle of a pack of Dark
Hounds?
Hopefully this'll shed some light on the problem that if you teleport
twice, you often end up back in the mess you just left.

On an almost related note, what is the probability of being paralysed
and/or losing CON when casting a spell without enough mana?

Thanks

Phil.

Dr. Andrew White

unread,
Apr 28, 2004, 11:42:38 AM4/28/04
to

"Phil" <ph...@ideastakingshape.co.uk> wrote in message
news:5fd988b0.04042...@posting.google.com...

Well, here is the code:

Looks to me like the game will search for the first grid which is free of a
monster, object, and not in a vault. There does not seem to be a bias for a
the only free grid in the middle of an orc pit.

The health damage code is below also. Basically 50% chance to damage your
health.


/*
* Teleport the player to a location up to "dis" grids away.
*
* If no such spaces are readily available, the distance may increase.
* Try very hard to move the player at least a quarter that distance.
*/
void teleport_player(int dis)
{
int py = p_ptr->py;
int px = p_ptr->px;

int d, i, min, y, x;

bool look = TRUE;


/* Initialize */
y = py;
x = px;

/* Minimum distance */
min = dis / 2;

/* Look until done */
while (look)
{
/* Verify max distance */
if (dis > 200) dis = 200;

/* Try several locations */
for (i = 0; i < 500; i++)
{
/* Pick a (possibly illegal) location */
while (1)
{
y = rand_spread(py, dis);
x = rand_spread(px, dis);
d = distance(py, px, y, x);
if ((d >= min) && (d <= dis)) break;
}

/* Ignore illegal locations */
if (!in_bounds_fully(y, x)) continue;

/* Require "naked" floor space */
if (!cave_naked_bold(y, x)) continue;

/* No teleporting into vaults and such */
if (cave_info[y][x] & (CAVE_ICKY)) continue;

/* This grid looks good */
look = FALSE;

/* Stop looking */
break;
}

/* Increase the maximum distance */
dis = dis * 2;

/* Decrease the minimum distance */
min = min / 2;
}

/* Sound */
sound(MSG_TELEPORT);

/* Move player */
monster_swap(py, px, y, x);

/* Handle stuff XXX XXX XXX */
handle_stuff();
}


/* Over-exert the player */
else
{
int oops = s_ptr->smana - p_ptr->csp;

/* No mana left */
p_ptr->csp = 0;
p_ptr->csp_frac = 0;

/* Message */
msg_print("You faint from the effort!");

/* Hack -- Bypass free action */
(void)set_paralyzed(p_ptr->paralyzed + randint(5 * oops + 1));

/* Damage CON (possibly permanently) */
if (rand_int(100) < 50)
{
bool perm = (rand_int(100) < 25);

/* Message */
msg_print("You have damaged your health!");

/* Reduce constitution */
(void)dec_stat(A_CON, 15 + randint(10), perm);
}
}


David Grenier

unread,
Apr 28, 2004, 2:25:19 PM4/28/04
to
Dr. Andrew White wrote:
> "Phil" <ph...@ideastakingshape.co.uk> wrote in message
> news:5fd988b0.04042...@posting.google.com...
>> I know that phase door moves you a small amount in a random direction
>> and teleport the same but further.
>> How does Angband decide where you are going to end up? Are you more
>> likely to end up in a big open space than in a dead end corridor? Is
>> there a built in bias to dump you in the middle of a pack of Dark
>> Hounds?
>> Hopefully this'll shed some light on the problem that if you teleport
>> twice, you often end up back in the mess you just left.

<snip>

> Well, here is the code:

Hm, It's rare to see actual code posted...

> /*
> * Teleport the player to a location up to "dis" grids away.
> *
> * If no such spaces are readily available, the distance may increase.
> * Try very hard to move the player at least a quarter that distance.
> */
> void teleport_player(int dis)
> {

<snip location find>

> /* This grid looks good */
> look = FALSE;
>
> /* Stop looking */
> break;
> }
>
> /* Increase the maximum distance */
> dis = dis * 2;
>
> /* Decrease the minimum distance */
> min = min / 2;
> }

What's the point of the above two statements? If I read the code correctly,
they aren't reached unless a good grid has already heen found, and the they
are not used before the player is moved...

> /* Sound */
> sound(MSG_TELEPORT);
>
> /* Move player */
> monster_swap(py, px, y, x);

Which happens here. Since 'min' and 'dis' are not passed to
"handle_stuff()" and go out of scope immediately afterwards, I don't see the
point of having those statements there.

> /* Handle stuff XXX XXX XXX */
> handle_stuff();
> }

Dave


Julian Lighton

unread,
Apr 28, 2004, 3:40:00 PM4/28/04
to
In article <c6ot9n$5f4$1...@news.ks.uiuc.edu>,

David Grenier <gre...@elbereth.uiuc.edu> wrote:
>Dr. Andrew White wrote:
>> "Phil" <ph...@ideastakingshape.co.uk> wrote in message
>> news:5fd988b0.04042...@posting.google.com...
>>> How does Angband decide where you are going to end up? Are you more
>>> likely to end up in a big open space than in a dead end corridor? Is
>>> there a built in bias to dump you in the middle of a pack of Dark
>>> Hounds?
>
><snip>
>
>> Well, here is the code:
>
>Hm, It's rare to see actual code posted...
>
><snip location find>
>
>> /* This grid looks good */
>> look = FALSE;
>>
>> /* Stop looking */
>> break;
>> }
>>
>> /* Increase the maximum distance */
>> dis = dis * 2;
>>
>> /* Decrease the minimum distance */
>> min = min / 2;
>> }
>
>What's the point of the above two statements? If I read the code correctly,
>they aren't reached unless a good grid has already heen found, and the they
>are not used before the player is moved...

They're outside of the "Try several locations" loop (it's closed by
that '}'), so they'll be reached whether or not a good grid was found
there.

If it fails to find a good space, it expands the range to search in
and tries again.

David Grenier

unread,
Apr 28, 2004, 8:58:24 PM4/28/04
to

>> <snip>

>> <snip location find>

Ah, I see it now... I missed that right brace when I first looked. Thanks.

Dave


Phil

unread,
Apr 30, 2004, 5:01:37 AM4/30/04
to
Thanks for the info and code snippet.
So if I'm reading it right, you always faint from the effort of
csating a spell with not enough mana, and you have 50% chance to
damage your con.
The probability of successfully casting the spell is shown if you have
a look in your spell book.

Probability question:
Is the fail probability to cast cast teleport different if I have one
mana compared to if I have 5?

Infinate loop question: In the extrememly unlikely situation that the
entire level is full of breeders, or the player has cast create doors
all over the place and there are no free spaces, how will this be
resolved? I suppose that stairs count as free spaces, but for the
sake of this question we can cast destruction to get rid of them all.
I notice that minimum distance is divided by 2 each time the loop
fails to find a place. Is this a 'divide by two and round down' or a
'divide by two and round up'. If the latter, it looks like it will
loop forever. If the former, does the function to check for free
spaces allow the current player square to be classed as free? If so,
you will not move from a teleport, otherwise it looks like an infinate
loop again.
Extremely unlikely situation, I know, but still I find myself curious.

Phil.

David Grenier

unread,
Apr 30, 2004, 5:54:41 AM4/30/04
to
Phil wrote:
<snip stuff handled elsewhere>

> Infinate loop question: In the extrememly unlikely situation that the
> entire level is full of breeders, or the player has cast create doors
> all over the place and there are no free spaces, how will this be
> resolved? I suppose that stairs count as free spaces, but for the
> sake of this question we can cast destruction to get rid of them all.

According to the code snippet, it won't. You'll end up locking the process,
but this is so astronomically unlikely as to not require an iteration check.
(Note: This assumption assumes the player's space is not empty. This is a
reasonable assumption as I have never seen a phase door which deposits you
right back where you started, and this is not all that unlikely.)

> I notice that minimum distance is divided by 2 each time the loop
> fails to find a place. Is this a 'divide by two and round down' or a
> 'divide by two and round up'.

In general, integer division (Angband uses no floating point numbers)
truncates (rounds down) to the nearest integer. Thus, the minimum distance
will eventually reach zero.

> If the latter, it looks like it will
> loop forever. If the former, does the function to check for free
> spaces allow the current player square to be classed as free?

I'm not sure about this, but think it doesn't; see above for reasoning.

> If so,
> you will not move from a teleport, otherwise it looks like an infinate
> loop again.
> Extremely unlikely situation, I know, but still I find myself curious.

If you find yourself this curious, you may wish to learn to source dive.
{smile} It looks like you already have some understanding of how to read
code; all that's left is finding the appropriate functions that the code
references ("grep" works nicely here) so you can put all the pieces of the
puzzle together. After you learn that skill, you can answer any technical
question about any *band you may have.

Dave


0 new messages