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.
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);
}
}
<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
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.
>> <snip>
>> <snip location find>
Ah, I see it now... I missed that right brace when I first looked. Thanks.
Dave
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.
> 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