2001-01-25 10:37:55 +01:00
/* vi: set ts=2:
2004-05-25 01:09:10 +02:00
*
*
* Eressea PB ( E ) M host Copyright ( C ) 1998 - 2003
* Christian Schlittchen ( corwin @ amber . kn - bremen . de )
* Katja Zedel ( katze @ felidae . kn - bremen . de )
* Henning Peters ( faroul @ beyond . kn - bremen . de )
* Enno Rehling ( enno @ eressea - pbem . de )
* Ingo Wilken ( Ingo . Wilken @ informatik . uni - oldenburg . de )
*
* based on :
*
* Atlantis v1 .0 13 September 1993 Copyright 1993 by Russell Wallace
* Atlantis v1 .7 Copyright 1996 by Alex Schr <EFBFBD> der
*
* This program may not be used , modified or distributed without
* prior permission by the authors of Eressea .
* This program may not be sold or used commercially without prior written
* permission from the authors .
*/
2001-01-25 10:37:55 +01:00
# include <config.h>
# include "eressea.h"
# include "teleport.h"
2001-12-10 01:13:39 +01:00
/* kernel includes */
2001-01-25 10:37:55 +01:00
# include "unit.h"
# include "region.h"
2001-12-10 01:13:39 +01:00
# include "race.h"
2002-02-10 14:23:30 +01:00
# include "skill.h"
2001-01-25 10:37:55 +01:00
# include "faction.h"
# include "plane.h"
2004-05-25 10:53:59 +02:00
/* util includes */
# include <log.h>
2001-12-10 01:13:39 +01:00
/* libc includes */
2001-01-25 10:37:55 +01:00
# include <assert.h>
# include <stdlib.h>
2004-05-25 01:09:10 +02:00
# define TE_CENTER_X 1000
# define TE_CENTER_Y 1000
2004-06-04 00:28:39 +02:00
# define TP_RADIUS 2
2004-05-25 19:54:47 +02:00
# define TP_DISTANCE 4
2004-05-25 01:09:10 +02:00
2005-06-10 00:10:35 +02:00
static short
real2tp ( short rk ) {
2004-05-25 01:09:10 +02:00
/* in C:
* - 4 / 5 = 0 ;
* + 4 / 5 = 0 ;
* ! ! ! ! ! ! ! ! ! ! ;
*/
2004-05-25 19:54:47 +02:00
return ( rk + ( TP_DISTANCE * 5000 ) ) / TP_DISTANCE - 5000 ;
2001-01-25 10:37:55 +01:00
}
static region *
2001-09-05 21:40:40 +02:00
tpregion ( const region * r ) {
2005-01-01 16:16:41 +01:00
region * rt = findregion ( TE_CENTER_X + real2tp ( r - > x ) , TE_CENTER_Y + real2tp ( r - > y ) ) ;
if ( rplane ( rt ) ! = get_astralplane ( ) ) return NULL ;
return rt ;
2004-05-25 01:09:10 +02:00
}
region_list *
astralregions ( const region * r , boolean ( * valid ) ( const region * ) )
{
region_list * rlist = NULL ;
2005-06-10 00:10:35 +02:00
short x , y ;
2004-05-25 01:09:10 +02:00
2004-05-25 10:53:59 +02:00
assert ( rplane ( r ) = = get_astralplane ( ) ) ;
if ( rplane ( r ) ! = get_astralplane ( ) ) {
log_error ( ( " astralregions was called with a non-astral region. \n " ) ) ;
return NULL ;
}
2004-05-25 01:09:10 +02:00
r = r_astral_to_standard ( r ) ;
2004-05-25 10:53:59 +02:00
if ( r = = NULL ) return NULL ;
2004-05-25 01:09:10 +02:00
2004-05-25 11:33:44 +02:00
for ( x = - TP_RADIUS ; x < = + TP_RADIUS ; + + x ) {
for ( y = - TP_RADIUS ; y < = + TP_RADIUS ; + + y ) {
2004-05-25 01:09:10 +02:00
region * rn ;
2004-05-25 11:33:44 +02:00
int dist = koor_distance ( 0 , 0 , x , y ) ;
2004-05-25 01:09:10 +02:00
if ( dist > TP_RADIUS ) continue ;
2004-05-25 11:33:44 +02:00
rn = findregion ( r - > x + x , r - > y + y ) ;
2004-05-25 01:09:10 +02:00
if ( rn ! = NULL & & ( valid = = NULL | | valid ( rn ) ) ) add_regionlist ( & rlist , rn ) ;
}
}
return rlist ;
2001-01-25 10:37:55 +01:00
}
region *
2001-09-05 21:40:40 +02:00
r_standard_to_astral ( const region * r )
2001-01-25 10:37:55 +01:00
{
2004-05-25 01:09:10 +02:00
region * r2 ;
2001-01-25 10:37:55 +01:00
2004-05-25 19:54:47 +02:00
if ( rplane ( r ) ! = get_normalplane ( ) ) return NULL ;
2004-05-25 11:30:39 +02:00
r2 = tpregion ( r ) ;
2005-01-01 16:16:41 +01:00
if ( rterrain ( r2 ) ! = T_ASTRAL ) return NULL ;
2001-01-25 10:37:55 +01:00
2004-05-25 01:09:10 +02:00
return r2 ;
2001-01-25 10:37:55 +01:00
}
region *
2001-09-05 21:40:40 +02:00
r_astral_to_standard ( const region * r )
2001-01-25 10:37:55 +01:00
{
2005-06-10 00:10:35 +02:00
short x , y ;
2004-05-25 01:09:10 +02:00
region * r2 ;
2001-01-25 10:37:55 +01:00
2004-05-25 01:09:10 +02:00
assert ( rplane ( r ) = = get_astralplane ( ) ) ;
2004-05-25 19:54:47 +02:00
x = ( r - > x - TE_CENTER_X ) * TP_DISTANCE ;
y = ( r - > y - TE_CENTER_Y ) * TP_DISTANCE ;
2001-01-25 10:37:55 +01:00
2004-05-25 01:09:10 +02:00
r2 = findregion ( x , y ) ;
2004-05-25 11:30:39 +02:00
if ( rplane ( r2 ) ! = get_normalplane ( ) ) return NULL ;
2001-01-25 10:37:55 +01:00
2004-05-25 01:09:10 +02:00
return r2 ;
2001-01-25 10:37:55 +01:00
}
2004-02-21 13:18:29 +01:00
region_list *
2005-06-10 00:10:35 +02:00
all_in_range ( const region * r , short n , boolean ( * valid ) ( const region * ) )
2001-01-25 10:37:55 +01:00
{
2005-06-10 00:10:35 +02:00
short x , y ;
2004-05-25 01:09:10 +02:00
region_list * rlist = NULL ;
if ( r = = NULL ) return NULL ;
for ( x = r - > x - n ; x < = r - > x + n ; x + + ) {
for ( y = r - > y - n ; y < = r - > y + n ; y + + ) {
if ( koor_distance ( r - > x , r - > y , x , y ) < = n ) {
2005-06-10 00:10:35 +02:00
region * r2 = findregion ( x , y ) ;
2004-05-25 01:09:10 +02:00
if ( r2 ! = NULL & & ( valid = = NULL | | valid ( r2 ) ) ) add_regionlist ( & rlist , r2 ) ;
}
}
}
return rlist ;
2001-01-25 10:37:55 +01:00
}
void
random_in_teleport_plane ( void )
{
2004-05-25 01:09:10 +02:00
region * r ;
faction * f0 = findfaction ( MONSTER_FACTION ) ;
int next = rand ( ) % 100 ;
if ( f0 = = NULL ) return ;
for ( r = regions ; r ; r = r - > next ) {
if ( rplane ( r ) ! = get_astralplane ( ) | | rterrain ( r ) ! = T_ASTRAL ) continue ;
/* Neues Monster ? */
if ( next - - = = 0 ) {
unit * u = createunit ( r , f0 , 1 + rand ( ) % 10 + rand ( ) % 10 , new_race [ RC_HIRNTOETER ] ) ;
set_string ( & u - > name , " Hirnt<EFBFBD> ter " ) ;
set_string ( & u - > display , " Wabernde gr<67> ne Schwaden treiben durch den Nebel und verdichten sich zu einer unheimlichen Kreatur, die nur aus einem langen Ruderschwanz und einem riesigen runden Maul zu bestehen scheint. " ) ;
set_level ( u , SK_STEALTH , 1 ) ;
set_level ( u , SK_OBSERVATION , 1 ) ;
next = rand ( ) % 100 ;
}
}
2001-01-25 10:37:55 +01:00
}
2004-05-25 11:30:39 +02:00
plane *
get_normalplane ( void )
{
return NULL ;
}
2004-05-25 01:09:10 +02:00
plane *
get_astralplane ( void )
{
static plane * astral_plane = NULL ;
if ( astral_plane = = NULL ) {
astral_plane = getplanebyid ( 1 ) ;
}
if ( astral_plane = = NULL ) {
astral_plane = create_new_plane ( 1 , " Astralraum " ,
TE_CENTER_X - 500 , TE_CENTER_X + 500 ,
TE_CENTER_Y - 500 , TE_CENTER_Y + 500 , 0 ) ;
}
return astral_plane ;
}
2001-01-25 10:37:55 +01:00
void
create_teleport_plane ( void )
{
2004-05-25 01:09:10 +02:00
region * r ;
int i ;
plane * aplane = get_astralplane ( ) ;
/* Regionsbereich aufbauen. */
/* wichtig: das mu<6D> auch f<> r neue regionen gemacht werden.
* Evtl . bringt man es besser in new_region ( ) unter , und
* <EFBFBD> bergibt an new_region die plane mit , in der die
* Region gemacht wird .
*/
2005-01-01 16:16:41 +01:00
for ( r = regions ; r ; r = r - > next ) if ( r - > planep = = NULL ) {
2004-05-25 01:09:10 +02:00
region * ra = tpregion ( r ) ;
if ( ra = = NULL ) {
2005-06-10 00:10:35 +02:00
short x = TE_CENTER_X + real2tp ( r - > x ) ;
short y = TE_CENTER_Y + real2tp ( r - > y ) ;
2005-01-01 18:14:51 +01:00
plane * pl = findplane ( x , y ) ;
if ( pl = = aplane ) {
ra = new_region ( x , y ) ;
rsetterrain ( ra , T_ASTRAL ) ;
ra - > planep = aplane ;
if ( terrain [ rterrain ( r ) ] . flags & FORBIDDEN_LAND ) {
rsetterrain ( ra , T_ASTRALB ) ;
}
}
2004-05-25 01:09:10 +02:00
}
}
for ( i = 0 ; i < 4 ; i + + ) {
random_in_teleport_plane ( ) ;
}
2001-01-25 10:37:55 +01:00
}
2004-05-25 01:09:10 +02:00
boolean
inhabitable ( const region * r )
2001-01-25 10:37:55 +01:00
{
2004-05-25 01:09:10 +02:00
return landregion ( rterrain ( r ) ) ;
2001-01-25 10:37:55 +01:00
}