static void update2(zone * z, int x1, int y1, int x2, int y2) { if (z != NULL && z == world.plyr.z) { zone_update(z, x1, y1); zone_update(z, x2, y2); wrefresh(dispscr); } }
void init_world(void) { int x, y; cform * f; world.zones = malloc(sizeof(zone *)); load_iforms(); load_cforms(); *world.zones = zone_new(500, 300); f = cform_new('@' | A_BOLD); f->weight = TILE_MAX_WEIGHT / 2; f->max_health = 10; crtr_init(&world.plyr, f); world.plyr.nofree = 1; world.plyr.inv = inv_new(500); world.plyr.attack = 5; do { x = random() % get_dispw(); y = random() % get_disph(); } while (!crtr_tele(&world.plyr, x, y, *world.zones)); zone_update(world.plyr.z, x, y); }
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; } }
// // Performs the first initialization of the world // Will call assure_world if it has yet to be called // void init_world(void) { zone * z; assure_world(); z = zone_new(150, 50); vector_append(&world.zones, z); world.plyr.on_death.c_func = (trigger_cfunc)plyr_ev_death; world.plyr.on_lvlup.c_func = (trigger_cfunc)plyr_ev_lvlup; world.plyr.on_act_comp.c_func = (trigger_cfunc)plyr_ev_act_comp; world.plyr.on_act_fail.c_func = (trigger_cfunc)plyr_ev_act_fail; world.plyr.refs = NOFREE; crtr_spawn(&world.plyr, z); zone_update(z, world.plyr.x, world.plyr.y); }
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); }
// this function is really ugly static void generate(zone * z) { static int first = 1; int i, x, y, max; int rc; int ** walls; room * rv; item * it; creature * cr; if (first) { fill_walls(); first = 0; } // generate rooms rc = random() % ((z->width * z->height) / ROOM_INFREQ) + ROOM_MIN; rv = malloc(sizeof(room) * rc); for (i = 0; i < rc; i++) { rv[i].w = random() % 12 + 5; rv[i].h = random() % 8 + 3; rv[i].x = random() % (z->width - rv[i].w - 1) + 1; rv[i].y = random() % (z->height - rv[i].h - 1) + 1; } // cut out rooms walls = malloc(sizeof(int *) * z->width); for (x = 0; x < z->width; x++) { walls[x] = malloc(sizeof(int) * z->height); for (y = 0; y < z->height; y++) { for (i = 0; i < rc; i++) { if (in_room(rv + i, x, y)) break; } z->tiles[x][y].ch = '.'; walls[x][y] = (i == rc); } } // draw walls for (x = 0; x < z->width; x++) { for (y = 0; y < z->height; y++) { if (walls[x][y]) { z->tiles[x][y].impassible = 1; set_wall_char(walls,z,x,y); } } } // place some random junk if (world.iform_cnt != 0) { max = random() % (z->width * z->height / ITEM_INFREQ) + ITEM_MIN; for (i = max; i >= 0; i--) { it = item_new(world.iforms[random() % world.iform_cnt]); do { x = random() % z->width; y = random() % z->height; } while (z->tiles[x][y].impassible || !inv_try(z->tiles[x][y].inv, it)); item_tele(it, x, y, z); zone_update(z, x, y); } } // place some more random junk if (world.cform_cnt != 0) { max = random() % (z->width * z->height / CRTR_INFREQ) + CRTR_MIN; for (i = max; i >= 0; i--) { cr = crtr_new(world.cforms[random() % world.cform_cnt]); do { x = random() % z->width; y = random() % z->height; } while (z->tiles[x][y].impassible || z->tiles[x][y].crtr != NULL); crtr_tele(cr, x, y, z); zone_update(z, x, y); } } }
static time_t perform_enforce(int sockfd, engine_type *engine, int bForceUpdate, task_type* task, db_connection_t *dbconn) { zone_list_t *zonelist = NULL; zone_t *zone, *firstzone = NULL; policy_t *policy; key_data_list_t *keylist; const key_data_t *key; time_t t_next, t_now = time_now(), t_reschedule = -1; /* Flags that indicate tasks to be scheduled after zones have been * enforced. */ int bSignerConfNeedsWriting = 0; int bSubmitToParent = 0; int bRetractFromParent = 0; int zone_updated; if (!(zonelist = zone_list_new(dbconn)) /*|| zone_list_associated_fetch(zonelist)*/ || zone_list_get(zonelist)) { zone_list_free(zonelist); zonelist = NULL; } if (!zonelist) { /* TODO: log error */ ods_log_error("[%s] zonelist NULL", module_str); /* TODO: backoff? */ return t_reschedule; } for (zone = zone_list_get_next(zonelist); zone; zone_free(zone), zone = zone_list_get_next(zonelist)) { if (engine->need_to_reload || engine->need_to_exit) break; if (!bForceUpdate && (zone_next_change(zone) == -1)) { continue; } else if (zone_next_change(zone) > t_now && !bForceUpdate) { /* This zone needs no update, however it might be the first * for future updates */ if (zone_next_change(zone) < t_reschedule || !firstzone) { t_reschedule = zone_next_change(zone); if (firstzone) { zone_free(firstzone); } firstzone = zone; zone = NULL; /* keeps firstzone from being freed. */ } continue; } if (!(policy = zone_get_policy(zone))) { client_printf(sockfd, "Next update for zone %s NOT scheduled " "because policy is missing !\n", zone_name(zone)); if (zone_next_change(zone) != -1 && (zone_set_next_change(zone, -1) || zone_update(zone))) { /* TODO: Log error */ } continue; } if (policy_passthrough(policy)) { ods_log_info("Passing through zone %s.\n", zone_name(zone)); zone_set_signconf_needs_writing(zone, 1); zone_update(zone); bSignerConfNeedsWriting = 1; policy_free(policy); continue; } zone_updated = 0; t_next = update(engine, dbconn, zone, policy, t_now, &zone_updated); policy_free(policy); bSignerConfNeedsWriting |= zone_signconf_needs_writing(zone); keylist = zone_get_keys(zone); while ((key = key_data_list_next(keylist))) { if (key_data_ds_at_parent(key) == KEY_DATA_DS_AT_PARENT_SUBMIT) { ods_log_warning("[%s] please submit DS " "with keytag %d for zone %s", module_str, key_data_keytag(key)&0xFFFF, zone_name(zone)); bSubmitToParent = 1; } else if (key_data_ds_at_parent(key) == KEY_DATA_DS_AT_PARENT_RETRACT) { ods_log_warning("[%s] please retract DS " "with keytag %d for zone %s", module_str, key_data_keytag(key)&0xFFFF, zone_name(zone)); bRetractFromParent = 1; } } key_data_list_free(keylist); if (t_next == -1) { client_printf(sockfd, "Next update for zone %s NOT scheduled " "by enforcer !\n", zone_name(zone)); ods_log_debug("Next update for zone %s NOT scheduled " "by enforcer !\n", zone_name(zone)); } else { /* Invalid schedule time then skip the zone.*/ char tbuf[32] = "date/time invalid\n"; /* at least 26 bytes */ ctime_r(&t_next, tbuf); /* note that ctime_r inserts \n */ client_printf(sockfd, "Next update for zone %s scheduled at %s", zone_name(zone), tbuf); ods_log_debug("Next update for zone %s scheduled at %s", zone_name(zone), tbuf); } if (zone_next_change(zone) != t_next) { zone_set_next_change(zone, t_next); zone_updated = 1; } /* * Commit the changes to the zone if there where any. */ if (zone_updated) { if (zone_update(zone)) { ods_log_debug("[%s] error zone_update(%s)", module_str, zone_name(zone)); } } /* * Find out when to schedule the next change. */ if (zone_next_change(zone) != -1 && (zone_next_change(zone) < t_reschedule || !firstzone)) { t_reschedule = zone_next_change(zone); if (firstzone) { zone_free(firstzone); } firstzone = zone; zone = NULL; } } zone_list_free(zonelist); /* * Schedule the next change if needed. */ if (firstzone) { reschedule_enforce(task, t_reschedule, zone_name(firstzone)); zone_free(firstzone); } /* Launch signer configuration writer task when one of the * zones indicated that it needs to be written. * TODO: unschedule it first! */ if (bSignerConfNeedsWriting) { task_type *signconf = signconf_task(dbconn, "signconf", "signer configurations"); enf_schedule_task(sockfd,engine,signconf,"signconf"); } else { ods_log_info("[%s] No changes to any signconf file required", module_str); } /* Launch ds-submit task when one of the updated key states has the * DS_SUBMIT flag set. */ if (bSubmitToParent) { task_type *submit = keystate_ds_submit_task(engine); enf_schedule_task(sockfd, engine, submit, "ds-submit"); } /* Launch ds-retract task when one of the updated key states has the * DS_RETRACT flag set. */ if (bRetractFromParent) { task_type *retract = keystate_ds_retract_task(engine); enf_schedule_task(sockfd, engine, retract, "ds-retract"); } return t_reschedule; }
// // Throws an item from a position along the given direction // (x, y, z) + (dx, dy) is the starting position. // (dx, dy) is the direction the item moves in. // f is the force of the throw, effects duration and damage of the throw // Returns 1 on success and 0 on failure of placing the item // int item_throw(item * it, int x, int y, zone * z, int dx, int dy, int force) { creature * c; int ret, dam; int anim = (z == PLYR.z) && config.throw_anim_delay; int timeout = 100 * force / it->weight; chtype tmp = 0; x += dx; y += dy; while (x >= 0 && y >= 0 && x < z->width && y < z->height && !z->tiles[x][y].impassible && timeout) { if (x < 0 || x >= z->width) break; if (y < 0 || y >= z->height) break; if (z->tiles[x][y].impassible) break; // handle the animation if (anim) { if (tmp) { z->tiles[x-dx][y-dy].ch = tmp; zone_draw_tile(z, x-dx, y-dy); } tmp = z->tiles[x][y].ch; z->tiles[x][y].ch = it->ch; zone_draw_tile(z, x, y); wrefresh(dispscr); usleep(1000 * config.throw_anim_delay); } // creature collision c = z->tiles[x][y].crtr; if (c != NULL) { if (crtr_dodges(c, force / 10)) { memo("The %s artfully dodges the %s!", crtr_name(c), it->name); } else { dam = (it->spikiness + force) / 4 - 4; if (dam < 0) dam = 0; c->health -= dam; if (c->health <= 0) { memo("The %s kills the %s!\n", it->name, crtr_name(c)); crtr_death(c, "projectile impact"); } else { memo("The %s is hit with the %s for %d damage!", crtr_name(c), it->name, dam); } goto cleanup; } } x += dx; y += dy; timeout--; } x -= dx; y -= dy; cleanup: ret = item_tele(it, x, y, z); zone_update(z, x, y); wrefresh(dispscr); return ret; }
// this function is really ugly static void generate(zone * z) { static int first = 1; int i, x, y, max, timeout; int rc; int ** walls; room * rv; item * it; creature * cr; if (first) { fill_walls(); first = 0; } z->name = place_name(world.eth); // generate rooms rc = random() % ((z->width * z->height) / ROOM_INFREQ) + ROOM_MIN; rv = malloc(sizeof(room) * rc); for (i = 0; i < rc; i++) { rv[i].w = random() % 12 + 5; rv[i].h = random() % 8 + 3; rv[i].x = random() % (z->width - rv[i].w - 1) + 1; rv[i].y = random() % (z->height - rv[i].h - 1) + 1; } // cut out rooms walls = malloc(sizeof(int *) * z->width); for (x = 0; x < z->width; x++) { walls[x] = malloc(sizeof(int) * z->height); for (y = 0; y < z->height; y++) { for (i = 0; i < rc; i++) { if (in_room(rv + i, x, y)) break; } z->tiles[x][y].ch = '.'; z->tiles[x][y].show_ch = '.'; z->tiles[x][y].linked = 0; walls[x][y] = (i == rc); } } // draw walls for (x = 0; x < z->width; x++) { for (y = 0; y < z->height; y++) { if (walls[x][y]) { z->tiles[x][y].impassible = 1; set_wall_char(walls,z,x,y); } } } // place some random junk max = random() % (z->width * z->height / ITEM_INFREQ) + ITEM_MIN; for (i = max; i >= 0; i--) { it = gen_item(world.gitems, 1); timeout = 1000; do { x = random() % z->width; y = random() % z->height; timeout--; } while ((z->tiles[x][y].impassible || !inv_try(z->tiles[x][y].inv, it)) && timeout); if (timeout) { item_tele(it, x, y, z); zone_update(z, x, y); } else { item_free(it); } } // place some more random junk if (!config.all_alone) { max = random() % (z->width * z->height / CRTR_INFREQ) + CRTR_MIN; for (i = max; i >= 0; i--) { cr = gen_crtr(world.gcrtrs, 1); crtr_spawn(cr, z); zone_update(z, cr->x, cr->y); } } // place random zone jumpers for (i = 0; i < 4; i++) { do { x = random() % z->width; y = random() % z->height; timeout--; } while (z->tiles[x][y].impassible); z->tiles[x][y].linked = 1; z->tiles[x][y].link_z = NULL; z->tiles[x][y].ch = '@'; z->tiles[x][y].show_ch = '@'; } // cleanup for (x = 0; x < z->width; x++) free(walls[x]); free(walls); free(rv); }
// this function is really ugly static void generate(zone * z) { static int first = 1; int i, x, y, max, timeout; int wall; int x1,x2,y1,y2; int rc; room ** rooms; item * it; creature * cr; if (first) { fill_walls(); first = 0; } z->name = place_name(world.eth); rc = random() % ((z->width * z->height) / ROOM_INFREQ) + ROOM_MIN; rooms = malloc(sizeof(room*) * rc); //make everything walls! for (x = 0; x < z->width; x++) { for (y = 0; y < z->height; y++) { z->tiles[x][y].impassible = 1; } } //gen rooms and cut out for(i=0; i< rc; i++){ rooms[i]=gen_room(world.grooms,1); build_room(z,rooms[i]); } //make sure rooms are connected! //connect each room to one other room for(i=0; i< rc; i++){ max = random() % rc; room_spot(z,rooms[i],&x1,&y1); room_spot(z,rooms[max],&x2,&y2); wall=0; if(x1 == -1 || x2 == -1){ warning("Room generation timed out!"); break; } for(;x1 != x2; x1-= sign(x1-x2)){ if(z->tiles[x1][y1].impassible) wall=1; else if (wall) break; zone_empty_tile(z,x1,y1); } for(;y1 != y2; y1-= sign(y1-y2)){ if(z->tiles[x1][y1].impassible) wall=1; else if (wall) break; zone_empty_tile(z,x1,y1); } } //do rendering thing for (x = 0; x < z->width; x++) { for (y = 0; y < z->height; y++) { if (z->tiles[x][y].impassible) { set_wall_char(z,x,y); } } } for(i=0; i< rc; i++) free(rooms[i]); free(rooms); // place some random junk max = random() % (z->width * z->height / ITEM_INFREQ) + ITEM_MIN; for (i = max; i >= 0; i--) { it = gen_item(world.gitems, 1); timeout = 1000; do { x = random() % z->width; y = random() % z->height; timeout--; } while ((z->tiles[x][y].impassible || !inv_try(z->tiles[x][y].inv, it)) && timeout); if (timeout) { item_tele(it, x, y, z); zone_update(z, x, y); } else { item_free(it); } } // place some more random junk if (!config.all_alone) { max = random() % (z->width * z->height / CRTR_INFREQ) + CRTR_MIN; for (i = max; i >= 0; i--) { cr = gen_crtr(world.gcrtrs, 1); crtr_spawn(cr, z); zone_update(z, cr->x, cr->y); } } // place random zone jumpers for (i = 0; i < 4; i++) { do { x = random() % z->width; y = random() % z->height; timeout--; } while (z->tiles[x][y].impassible); z->tiles[x][y].linked = 1; z->tiles[x][y].link_z = NULL; z->tiles[x][y].ch = '@'; z->tiles[x][y].show_ch = '@'; } // cleanup //for (x = 0; x < z->width; x++) free(walls[x]); //free(walls); //free(rv); }