/* This file was generated by scramble.py. */
#line 1 "src/player.py"
#include "player.h"
#line 40
static int ladder;
int gravity = 1;
#line 43
Player * player_create(int tid) {
    Player * self;
#line 44
    land_alloc(self);
    self->tid = tid;
    return self;
}
void kid_command(Player * self, KidState state, bool named) {
    if (self->state == state || self->state == Studying || self->state == Crazy) {
#line 49
        return ;
    }
    if (self->state == Crying || self->state == Monster) {
        if (! named) {
#line 52
            return ;
        }
        if (state != Stopping) {
#line 54
            return ;
        }
    }
#line 56
    self->state = state;
    self->attention_span = 600;
    if (state == Stopping) {
        self->attention_span = 1200;
    }
#line 60
    if (state == Studying) {
        self->attention_span = 300;
    }
}
#line 63
float distance(Player * self, float * rx, float * ry, float tx, float ty) {
    Game * g = game_global();
    Map * m = g->map;
    int dx = tx - self->x;
    int dy = ty - self->y;
    if (dx > m->w * m->tw / 2) {
#line 68
        dx -= m->w * m->tw;
    }
#line 69
    if (dx < - m->w * m->tw / 2) {
#line 69
        dx += m->w * m->tw;
    }
#line 70
    if (dy > m->h * m->th / 2) {
#line 70
        dy -= m->h * m->th;
    }
#line 71
    if (dy < - m->h * m->th / 2) {
#line 71
        dy += m->h * m->th;
    }
#line 72
    if (rx) {
#line 72
        * rx = dx;
    }
#line 73
    if (ry) {
#line 73
        * ry = dy;
    }
#line 74
    return sqrt(dx * dx + dy * dy);
}
float kid_distance(Player * self, float * rx, float * ry) {
    return distance(self, rx, ry, game_global ()->player->x, game_global ()->player->y);
}
Tile * player_get_under(Player * self) {
    Tile * most_important = NULL;
    Map * map = game_global ()->map;
    Tile * pt = tile_by_id(self->tid);
    int dx [] = {pt->border, pt->w - 1 - pt->border, pt->border, pt->w - 1 - pt->border};
    int dy [] = {pt->h - 10 - 100, pt->h - 10 - 100, pt->h - 10, pt->h - 10};
    for (int i = 0; i < 4; i += 1) {
        int x = map_tx(self->x + dx [i]);
        int y = map_ty(self->y + dy [i]);
        int tid = map_get(map, x, y);
        Tile * t = tile_by_id(tid);
        if (t) {
            if (t->climb) {
                most_important = t;
            }
#line 92
            else {
#line 94
                return t;
            }
        }
    }
#line 96
    return most_important;
}
void player_place_at_start(Player * self, int x, int y, Map * map) {
    //Tile *t = tile_by_id(self.tid)
    self->x = (map->start_x + x) * map->tw;
    self->y = (map->start_y + y) * map->th - 256;
    self->homex = self->x;
    self->homey = self->y;
    map_crowd(map, self->x, self->y);
}
bool player_collision(Player * self) {
    Tile * t = player_get_under(self);
    if (t && ! t->climb) {
        return 1;
    }
#line 110
    return 0;
}
void player_ladder(Player * self) {
    if (! ladder) {
        ladder = tile_by_name("ladder");
    }
#line 115
    Game * g = game_global();
    int x = map_tx(self->x + 64);
    int y = map_ty(self->y + 256 - 10);
    int tid = map_get(g->map, x, y);
    if (tid == 0) {
        if (self->ladders == 0) {
#line 120
            return ;
        }
        tid = map_get(g->map, x, y + gravity);
        if (tid == 0) {
#line 123
            return ;
        }
        map_put(g->map, x, y, ladder);
        particle_smoke(x * 128 + 64, y * 128 + 64, 64);
        land_sound_play(g->toc, 1, 0, 1);
        self->ladders--;
    }
#line 129
    else if (tid == ladder) {
        if (self->ladders >= 25) {
#line 130
            return ;
        }
        tid = map_get(g->map, x, y - gravity);
        if (tid == ladder) {
#line 133
            return ;
        }
        map_put(g->map, x, y, 0);
        particle_smoke(x * 128 + 64, y * 128 + 64, 64);
        land_sound_play(g->toc, 1, 0, 1);
        self->ladders++;
    }
}
#line 140
void player_dig(Player * self, int kx) {
    Game * g = game_global();
    int x = map_tx(self->x + 64 + kx * 128);
    int y = map_ty(self->y + 256 - 10);
    int tid = map_get(g->map, x, y);
    if (tid == g->earth->id) {
        self->dig++;
        particle_smoke(self->x + 64 + kx * 64, self->y + 256 - 70, 1);
        if (self->dig % 10 == 1) {
            land_sound_play(g->toc, 0.5, 0, 0.5);
        }
#line 150
        if (self->dig >= 100) {
            map_put(g->map, x, y, 0);
            land_sound_play(g->knock, 1, 0, 1);
            self->dig = 0;
        }
    }
}
#line 155
bool player_ground(Player * self) {
    Tile * t = player_get_under(self);
    if (t) {
        return 1;
    }
#line 159
    return 0;
}
bool player_move_(Player * self, float dx, float dy, bool fall) {
    Game * g = game_global();
    float ox = self->x;
    float oy = self->y;
    self->x += dx;
    self->y += dy;
    bool c;
    c = fall ? player_ground(self) : player_collision(self);
    if (c) {
        self->x = ox;
        self->y = oy;
        return 0;
    }
#line 173
    self->x = ffmod(self->x, g->map->w * g->map->tw);
    self->y = ffmod(self->y, g->map->h * g->map->th);
    map_crowd(g->map, self->x, self->y);
    map_uncrowd(g->map, ox, oy);
    self->dig = 0;
    return 1;
}
void player_transport(Player * self, float x, float y) {
    Game * g = game_global();
    map_uncrowd(g->map, self->x, self->y);
    self->x = x;
    self->y = y;
    map_crowd(g->map, self->x, self->y);
}
void player_teleport(Player * self) {
    Game * g = game_global();
    for (int t = 0; t < 100; t += 1) {
        int rx = land_rand(0, g->map->w - 1);
        int ry = land_rand(0, g->map->h - 1);
        if (map_get(g->map, rx, ry) == 0) {
            //
            //   0
            //
            // 128  x 256 - 130
            //      x
            // 256  x 256 - 10
            map_uncrowd(g->map, self->x, self->y);
            rx *= g->map->tw;
            ry *= g->map->th;
            self->x = rx;
            self->y = ry + 127 - 256 + 10;
            map_crowd(g->map, self->x, self->y);
        }
    }
}
#line 206
bool player_move(Player * self, float dx, float dy) {
    return player_move_(self, dx, dy, 0);
}
bool player_fall(Player * self, float dx, float dy) {
    return player_move_(self, dx, dy, 1);
}
static void kid_mind(Player * self, int * kx, int * ky) {
    Game * g = game_global();
    if (self->attention_span > 0) {
        self->attention_span--;
    }
#line 216
    int c = map_crowded(g->map, self->x, self->y);
    if (self->state == Wandering) {
        if (self->attention_span == 0) {
            self->wx = land_rand(- 1, 1);
            if (self->wx == 0 && c > 5) {
                self->wx = land_rand(- 1, 1);
            }
#line 222
            self->attention_span = land_rand(60, 300);
        }
#line 223
        if (self->attention_span % 3 == 0) {
            * kx = self->wx;
        }
    }
#line 225
    else if (self->state == Following || self->state == Monster) {
        float dx, dy;
        if (self->state == Following) {
            kid_distance(self, & dx, & dy);
        }
#line 228
        else {
#line 230
            distance(self, & dx, & dy, game_global ()->monster->x, game_global ()->monster->y);
        }
        if (fabs(dy) < 128) {
            if (dx > 150) {
                * kx = 1;
            }
#line 235
            if (dx < - 150) {
                * kx = - 1;
            }
        }
#line 236
        else {
#line 238
            if (dx > 0) {
                * kx = 1;
            }
#line 240
            if (dx < 0) {
                * kx = - 1;
            }
        }
#line 242
        if (dy > 128) {
            * ky = 1;
        }
#line 244
        if (dy < 0) {
            * ky = - 1;
        }
#line 246
        if (self->attention_span == 0) {
            self->state = land_rand(0, 3) == 0 ? Crying : Wandering;
            if (self->state == Crying) {
                self->attention_span = 600;
                land_sound_play(g->cry, 1, 0, 1);
            }
#line 250
            else {
#line 252
                land_sound_play(g->laugh, 1, 0, land_rnd(1, 1.25));
            }
        }
    }
#line 253
    else if (self->state == Stopping) {
        if (self->attention_span == 0) {
            self->state = Wandering;
        }
    }
#line 256
    else if (self->state == Studying) {
        if (self->attention_span == 0) {
            self->state = Crazy;
            self->attention_span = 300;
        }
    }
#line 260
    else if (self->state == Crazy) {
        float a = self->kid * 2 * pi / g->kids_count;
        a += self->attention_span * 2 * pi / 300;
        float dx = cos(a) * 15;
        float dy = sin(a) * 15;
        player_move(self, dx, dy);
        if (self->attention_span == 0) {
            self->state = Wandering;
            player_teleport(self);
        }
    }
#line 269
    else if (self->state == Sitting) {
        Tile * mit = player_get_under(self);
        if (mit && mit->id == g->brick->id) {
            if (c > 1) {
                float dx, dy;
                distance(self, & dx, & dy, self->homex, self->homey);
                if (dx > 0) {
#line 275
                    * kx = 1;
                }
#line 276
                if (dx < 0) {
#line 276
                    * kx = - 1;
                }
#line 277
                if (dy > 0) {
#line 277
                    * ky = 1;
                }
#line 278
                if (dy < 0) {
#line 278
                    * ky = - 1;
                }
            }
        }
#line 278
        else {
#line 280
            self->state = Wandering;
        }
    }
#line 281
    else if (self->state == Crying) {
        Tile * pt = tile_by_id(self->tid);
        if (g->time % 8 == 1) {
            particle_tear(self->x + 20, self->y + 256 - pt->tall + 20, - 1, - gravity * 3, 0.1 * gravity);
        }
#line 285
        if (g->time % 8 == 5) {
            particle_tear(self->x + 128 - 20, self->y + 256 - pt->tall + 20, 1, - gravity * 3, 0.1 * gravity);
        }
    }
#line 287
    else if (self->state == Dancing) {
        if (self->wy == 0) {
#line 288
            self->wy = - 1;
        }
#line 289
        if (self->attention_span == 0) {
            self->attention_span = land_rand(8, 12);
            self->wy *= - 1;
            particle_sparkle(self->x + 64, self->y + 128, 1);
        }
#line 293
        * ky = self->wy;
    }
}
#line 295
static void monster_mind(Player * self, int * kx, int * ky) {
    Game * game = game_global();
    if (self->attention_span > 0) {
        self->attention_span--;
    }
#line 299
    if (self->attention_span == 0) {
#line 301
        int tx = map_tx(self->x + 128 + self->wx * 70);
        int ty = map_ty(self->y + 256 - 10 - 50 + self->wy * 55);
        if (self->ladders > 0) {
            if (map_get(game->map, tx, ty) == game->earth->id) {
                map_put(game->map, tx, ty, 0);
                self->ladders--;
            }
        }
#line 308
        if (game->kids [self->kid]->state != Monster) {
            for (int i = 0; i < game->kids_count; i += 1) {
                Player * kid = game->kids [i];
                if (kid->state == Crying && kid->attention_span == 0) {
                    player_transport(self, kid->x, kid->y);
                    for (int t = 0; t < 50; t += 1) {
                        player_move(self, 0, - 10);
                    }
#line 315
                    kid->state = Monster;
                    kid->attention_span = 36000;
                    self->kid = i;
                    self->ladders = 100;
                    break;
                }
            }
        }
#line 321
        self->wx = land_rand(- 1, 1);
        self->wy = 0;
        if (self->wx == 0) {
            self->wy = 2 * land_rand(0, 1) - 1;
        }
#line 325
        self->attention_span = land_rand(60, 300);
    }
#line 326
    self->flying = 1;
    * kx = self->wx;
    * ky = self->wy;
#line 330
    if (kid_distance(self, NULL, NULL) < 500) {
        gravity = - 1;
        music_play_tune_if_not(music_tune1);
    }
}
#line 334
void player_collide(Player * self, int kx, int ky, int who) {
    if (who == 2) {
        self->attention_span = 0;
    }
#line 336
    else {
#line 338
        if (kx) {
#line 338
            self->wx = - self->wx;
        }
#line 339
        if (ky) {
#line 339
            self->wy = - self->wy;
        }
    }
}
#line 341
void player_input(Player * self, int kx, int ky, int who) {
    Game * game = game_global();
    if (who == 1) {
        kid_mind(self, & kx, & ky);
    }
#line 345
    if (who == 2) {
        monster_mind(self, & kx, & ky);
    }
    self->y += gravity;
    bool ground = player_ground(self);
    self->y -= gravity;
#line 352
    if (kx) {
        self->frame++;
    }
    if (ky * gravity >= 0 || self->jump > 46) {
        self->jump = 0;
    }
    if (ky == - gravity) {
        if (ground || self->jump) {
            self->jump++;
            if (who == 0) {
                if (self->jump == 1) {
                    particle_sparkle(self->x + 64, self->y + 256, 10);
                    land_sound_play(game->ding, 0.5, 0, 4);
                }
            }
        }
    }
#line 366
    Tile * mit = player_get_under(self);
#line 368
    if (who == 0 && mit) {
        if (mit->id == game->brick->id) {
            gravity = 1;
            if (music_current() != music_tune4) {
                music_play_tune_if_not(music_tune2);
            }
        }
    }
#line 374
    if (! mit || ! mit->climb) {
        if (self->jump || self->climbing || self->flying) {
            self->dy += ky;
        }
#line 377
        else if (! ground) {
            self->dy += gravity;
            ky = 0;
        }
    }
#line 379
    else {
#line 381
        self->dy += ky;
    }
    if (ky == gravity) {
        self->climbing = 1;
    }
#line 384
    else {
#line 386
        self->climbing = 0;
    }
    self->falling = 0;
#line 390
    self->dx += kx;
    float lr = self->dx > 0 ? 1 : self->dx < 0 ? - 1 : 0;
    float xa = fabs(self->dx);
    float ud = self->dy > 0 ? 1 : self->dy < 0 ? - 1 : 0;
    float ya = fabs(self->dy);
#line 396
    for (int i = 0; i < 10; i += 1) {
        if (xa > 0) {
            if (xa < 1) {
                lr *= xa;
            }
#line 400
            if (! player_move(self, lr, 0)) {
                player_collide(self, lr, 0, who);
                self->dx = 0;
            }
#line 403
            xa -= 1;
        }
#line 404
        if (ya > 0) {
            if (ya < 1) {
                ud *= ya;
            }
#line 407
            if (ud * gravity > 0 && ! self->climbing) {
                if (! player_fall(self, 0, ud)) {
                    player_collide(self, 0, ud, who);
                    self->dy = 0;
                }
#line 410
                else {
#line 412
                    self->falling = 1;
                }
            }
#line 412
            else {
#line 414
                if (! player_move(self, 0, ud)) {
                    player_collide(self, 0, ud, who);
                    self->dy = 0;
                    self->jump = 0;
                }
            }
#line 418
            ya -= 1;
        }
    }
#line 420
    self->dx *= 0.9;
    if (fabs(self->dx) < 0.1) {
        self->dx = 0;
    }
#line 423
    self->dy *= 0.9;
    if (fabs(self->dy) < 0.1) {
        self->dy = 0;
    }
}
/* This file was generated by scramble.py. */
