int crtr_attack(creature * attacker, creature * defender) { int damage, xp; damage = random() % (attacker->attack + 1); damage -= random() % (defender->ac + 1); if (damage < 0) damage = 0; defender->health -= damage; if (defender->health <= 0) { // death comes to us all xp = (defender->level + XP_LEVEL_DIFF) - attacker->level; if (xp < 0) xp = 0; crtr_xp_up(attacker, xp); if (plyr_is_me(defender)) { plyr_ev_death("violence"); } else if (!plyr_is_me(attacker)) { // the player wants the name of what he killed tileof(defender)->crtr = NULL; crtr_free(defender); } return DEAD; } return damage; }
void crtr_step(creature * c, int step) { int dam; int dx = 0, dy = 0; int x, y; zone * z; if (c->step != step) { // stamina upkeep c->stamina -= 1; if (c->stamina <= 0) { if (plyr_is_me(c)) { plyr_ev_death("starvation"); } else { memo("%s dies of starvation", c->f->name); x = c->x; y = c->y; z = c->z; tileof(c)->crtr = NULL; crtr_free(c); zone_update(z, x, y); wrefresh(dispscr); } return; } // ai section if (!plyr_is_me(c)) { // this is pretty ugly if (c->x > world.plyr.x) dx = -1; else if (c->x < world.plyr.x) dx = 1; if (c->y > world.plyr.y) dy = -1; else if (c->y < world.plyr.y) dy = 1; if (PLYR.x == c->x + dx && PLYR.y == c->y + dy) { dam = crtr_attack(c, &PLYR); if (dam) { memo("%s hits you for %d damage", c->f->name, dam); } else { memo("%s misses you", c->f->name); } } else { if (!crtr_move(c, dx, dy) && dx && dy) { if (!crtr_move(c, dx, 0)) { crtr_move(c, 0, dy); } } } } c->step = step; } }
void plyr_act_enter(int argc, char ** argv) { int ox, oy; zone * oz; tile * t = tileof(&PLYR); if (t->linked) { // TODO generalize if (t->link_z == NULL) { ox = PLYR.x; oy = PLYR.y; oz = PLYR.z; // generate new zone vector_append(&world.zones, zone_new(150, 50)); // TODO why 150,50? t->link_z = world.zones.arr[world.zones.cnt - 1]; // place player randomly crtr_spawn(&PLYR, t->link_z); t->link_x = PLYR.x; t->link_y = PLYR.y; // link back t = tileof(&PLYR); t->linked = 1; t->link_x = ox; t->link_y = oy; t->link_z = oz; t->ch = '@'; t->show_ch = '@'; } else { if (!crtr_tele(&PLYR, t->link_x, t->link_y, t->link_z)) { memo("Your way appears to be blocked?"); } } update_vis(); zone_draw(PLYR.z); } else { memo("I see no visible method of doing that."); } }
void zone_rm_crtr(zone * z, creature * c) { assert(c->z == z); assert(c == z->crtrs.arr[c->z_ind]); assert(z->crtrs.cnt > c->z_ind); // remove from crtrs list z->crtrs.arr[c->z_ind] = z->crtrs.arr[--z->crtrs.cnt]; ((creature *)z->crtrs.arr[c->z_ind])->z_ind = c->z_ind; // remove from tile assert(tileof(c)->crtr == c); tileof(c)->crtr = NULL; zone_update(c->z, c->x, c->y); if (c->z == PLYR.z) wrefresh(dispscr); c->z = NULL; crtr_free(c); }
int crtr_tele(creature * crtr, int x, int y, zone * z) { tile * t = zone_at(z, x, y); if (t != NULL && t->crtr == NULL && !t->impassible) { z->tiles[x][y].crtr = crtr; if (crtr->z != NULL) { tileof(crtr)->crtr = NULL; } update2(crtr->z, x, y, crtr->x, crtr->y); crtr->x = x; crtr->y = y; crtr->z = z; return 1; } return 0; }