<s> import math <EOL> from . object import WorldObject <EOL> from . . util import normalize <EOL> FACES = [ <EOL> ( <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:0> ) , <EOL> ( <NUM_LIT:0> , - <NUM_LIT:1> , <NUM_LIT:0> ) , <EOL> ( - <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:0> ) , <EOL> ( <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:0> ) , <EOL> ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:1> ) , <EOL> ( <NUM_LIT:0> , <NUM_LIT:0> , - <NUM_LIT:1> ) , <EOL> ] <EOL> class Character ( WorldObject ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , config ) : <EOL> self . config = config <EOL> self . jump_speed = math . sqrt ( <NUM_LIT:2> * self . config [ '<STR_LIT>' ] * self . config [ '<STR_LIT>' ] ) <EOL> self . flying = False <EOL> self . strafe = [ <NUM_LIT:0> , <NUM_LIT:0> ] <EOL> self . strafe_z = <NUM_LIT:0> <EOL> self . position = ( <NUM_LIT:0> , <NUM_LIT:5> , <NUM_LIT:0> ) <EOL> self . rotation = ( <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> self . dy = <NUM_LIT:0> <EOL> def strafe_forward ( self ) : <EOL> self . strafe [ <NUM_LIT:0> ] -= <NUM_LIT:1> <EOL> def strafe_backward ( self ) : <EOL> self . strafe [ <NUM_LIT:0> ] += <NUM_LIT:1> <EOL> def strafe_right ( self ) : <EOL> self . strafe [ <NUM_LIT:1> ] += <NUM_LIT:1> <EOL> def strafe_left ( self ) : <EOL> self . strafe [ <NUM_LIT:1> ] -= <NUM_LIT:1> <EOL> def strafe_up ( self ) : <EOL> if self . flying : <EOL> self . strafe_z += <NUM_LIT:1> <EOL> def strafe_down ( self ) : <EOL> if self . flying : <EOL> self . strafe_z -= <NUM_LIT:1> <EOL> def jump ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . flying : <EOL> self . strafe_up ( ) <EOL> else : <EOL> if self . dy == <NUM_LIT:0> : <EOL> self . dy = self . jump_speed <EOL> def fly ( self ) : <EOL> """<STR_LIT>""" <EOL> self . flying = not self . flying <EOL> self . strafe_z = <NUM_LIT:0> <EOL> def get_motion_vector ( self ) : <EOL> """<STR_LIT>""" <EOL> if any ( self . strafe ) : <EOL> x , y = self . rotation <EOL> strafe = math . degrees ( math . atan2 ( * self . strafe ) ) <EOL> y_angle = math . radians ( y ) <EOL> x_angle = math . radians ( x + strafe ) <EOL> if self . flying : <EOL> m = math . cos ( y_angle ) <EOL> dy = math . sin ( y_angle ) <EOL> if self . strafe [ <NUM_LIT:1> ] : <EOL> dy = <NUM_LIT:0.0> <EOL> m = <NUM_LIT:1> <EOL> if self . strafe [ <NUM_LIT:0> ] > <NUM_LIT:0> : <EOL> dy *= - <NUM_LIT:1> <EOL> dx = math . cos ( x_angle ) * m <EOL> dz = math . sin ( x_angle ) * m <EOL> else : <EOL> dy = <NUM_LIT:0.0> <EOL> dx = math . cos ( x_angle ) <EOL> dz = math . sin ( x_angle ) <EOL> else : <EOL> dy = <NUM_LIT:0.0> <EOL> dx = <NUM_LIT:0.0> <EOL> dz = <NUM_LIT:0.0> <EOL> dy += self . strafe_z <EOL> return dx , dy , dz <EOL> def update ( self , dt , objects ) : <EOL> """<STR_LIT>""" <EOL> speed = self . config [ '<STR_LIT>' ] if self . flying else self . config [ '<STR_LIT>' ] <EOL> d = dt * speed <EOL> dx , dy , dz = self . get_motion_vector ( ) <EOL> dx , dy , dz = dx * d , dy * d , dz * d <EOL> if not self . flying : <EOL> self . dy -= dt * self . config [ '<STR_LIT>' ] <EOL> self . dy = max ( self . dy , - self . config [ "<STR_LIT>" ] ) <EOL> dy += self . dy * dt <EOL> x , y , z = self . position <EOL> x , y , z = self . collide ( ( x + dx , y + dy , z + dz ) , self . config [ "<STR_LIT>" ] , objects ) <EOL> self . position = ( x , y , z ) <EOL> def collide ( self , position , height , objects ) : <EOL> """<STR_LIT>""" <EOL> pad = <NUM_LIT> <EOL> p = list ( position ) <EOL> np = normalize ( position ) <EOL> for face in FACES : <EOL> for i in range ( <NUM_LIT:3> ) : <EOL> if not face [ i ] : <EOL> continue <EOL> d = ( p [ i ] - np [ i ] ) * face [ i ] <EOL> if d < pad : <EOL> continue <EOL> for dy in range ( height ) : <EOL> op = list ( np ) <EOL> op [ <NUM_LIT:1> ] -= dy <EOL> op [ i ] += face [ i ] <EOL> if tuple ( op ) not in objects : <EOL> continue <EOL> p [ i ] -= ( d - pad ) * face [ i ] <EOL> if face == ( <NUM_LIT:0> , - <NUM_LIT:1> , <NUM_LIT:0> ) or face == ( <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:0> ) : <EOL> self . dy = <NUM_LIT:0> <EOL> break <EOL> return tuple ( p ) </s>
