int v_credit(struct command *c) { int target = c->a; int amount = c->b; int item = c->c; int pl; extern int gold_times; if (amount) { if (kind(target) != T_char && kind(target) != T_player) { wout(c->who, "%s not a character or player.", c->parse[1]); return FALSE; } if (numargs(c) >= 3 && i_strcmp(c->parse[3], "np") == 0) { if (kind(target) != T_player) { wout(c->who, "%s not a player.", box_code(target)); return FALSE; } add_np(target, amount); wout(c->who, "Credited %s %d NP.", box_name(target), amount); wout(target, "Received GM credit of %d NP.", amount); return TRUE; } if (item == 0) item = 1; gen_item(target, item, amount); wout(c->who, "Credited %s %s.", box_name(target), box_name_qty(item, amount)); wout(target, "Received CLAIM credit of %s.", box_name_qty(item, amount)); return TRUE; } if (kind(target) != T_char) { wout(c->who, "%s not a character.", c->parse[1]); return FALSE; } pl = player(target); if (times_paid(pl)) { wout(c->who, "Already paid faction %s.", box_name(pl)); return FALSE; } p_player(pl)->times_paid = TRUE; wout(target, "The Times pays %s %s.", box_name(target), gold_s(25)); gen_item(target, item_gold, 25); gold_times += 25; return TRUE; }
//产生一个随机地图, rate决定地图的渲染率. 地图大小应在mcMap中设定 int gen_map(McMap * mcMap, double rate) { int i, j, retv = 0, count = 0; int prev = 0, trans = 0, next = 0; double sum; pLinkList pList; pQueuePoint pqp; pList = init_queue(); if (pList == NULL) return -1; srandom(time(NULL)); //随机选择一个渲染点 i = random() % (mcMap->row - 2) + 1; j = random() % (mcMap->col - 2) + 1; sum = mcMap->row * mcMap->col + 0.1; while (count / sum < rate) { //保证一定的渲染率 pqp = calloc(1, sizeof (QueuePoint)); if (pqp == NULL) { retv = -1; goto END; } pqp->i = i; pqp->j = j; insert_node(pList, pqp); //加入渲染队列 mcMap->map[i][j].exit |= NODE_QUEUED; while (!is_empty(pList)) { pqp = read_first(pList); //取队列首点 //产生该点的随机出口 gen_exit(mcMap, pqp->i, pqp->j, count / (rate * sum), &prev, &trans, &next); //产生该点的东东, ncp, box, boss... gen_item(mcMap, pqp->i, pqp->j); //加入该点的出口点 if (check_exit_node(pList, mcMap, pqp->i, pqp->j, 0) || check_exit_node(pList, mcMap, pqp->i, pqp->j, 1) || check_exit_node(pList, mcMap, pqp->i, pqp->j, 2) || check_exit_node(pList, mcMap, pqp->i, pqp->j, 3)) { retv = -1; goto END; } delete_node(pList, 0, 1); //从队列中删除该点 if ((++count) / sum > rate) //渲染率达到就跳出 goto END; } //end of while(...) random_select(mcMap, &i, &j); //如果一个点不够渲染率, 则再选择一个 } END: free_queue(pList, 1); //释放队列资源 return retv; }
/* * Tue Jul 7 09:59:59 1998 -- Scott Turner * * Replenish up to "qty" but not more than max total. * * Tue Jul 7 10:31:23 1998 -- Scott Turner * * For "population" type production, driving the population to zero * is a bad idea. max != qty in the terr_prod table indicates a * population type resource. * */ static void replenish(int where, int item, int qty, int max) { int n; n = has_item(where, item); if (n == 0 && max != qty) { if (rnd(1, 100) > 50) gen_item(where, item, 1); } else if (n < max) { int m = max - n; if (m > qty) m = qty; gen_item(where, item, m); }; }
int v_add_item(struct command *c) { if (kind(c->a) == T_item) { if (kind(c->who) != T_char) out(c->who, "Warning: %s not a character", box_name(c->who)); gen_item(c->who, c->a, c->b); return TRUE; } wout(c->who, "%s is not a valid item.", c->parse[1]); return FALSE; }
int d_capture_beasts(struct command *c) { int type, piety, from = 0; int target = c->a; if (!has_holy_symbol(c->who)) { wout(c->who, "You must have a holy symbol to capture wild beasts."); return FALSE; }; if (!has_holy_plant(c->who)) { wout(c->who, "Capturing wild beasts requires a holy plant."); return FALSE; }; /* * Target should be a character (oddly enough) * */ if (kind(target) != T_char) { wout(c->who, "You cannot capture beasts from %s.",box_name(target)); return FALSE; }; /* * In same location. * */ if (!check_char_here(c->who, target)) { wout(c->who, "%s is not here.",box_name(c->a)); return FALSE; }; if (is_prisoner(target)) { wout(c->who, "Cannot capture beasts from prisoners."); return FALSE; }; if (c->who == target) { wout(c->who, "Can't capture beasts from oneself."); return FALSE; }; if (stack_leader(c->who) == stack_leader(target)) { wout(c->who, "Can't capture beasts from a member of the same stack."); return FALSE; }; /* * Now select a random beast from the target. That can be either the * target itself, or one of the beasts in the target's inventory. In * any case, the beast's statistics determine the piety cost of the * spell. * * Note that who the beast is "from" is also returned. * */ type = get_random_beast(target, &from); if (!type || !item_animal(type)) { wout(c->who, "%s has no beasts that you can capture.", box_name(target)); return FALSE; }; piety = ((item_attack(type) + item_defense(type)) / 50.0) + 1.5; /* * Perhaps he hasn't the piety. * */ if (!has_piety(c->who, piety)) { wout(c->who, "You lack the piety to lure a beast from %s.", box_name(target)); return FALSE; }; /* * Lure the beast away. * */ if (!move_item(from, c->who, type, 1)) { /* * Possibly it is "from" himself who we are capturing. * */ if (subkind(from) == sub_ni && item_animal(noble_item(from))) { wout(c->who, "You capture %s!",box_name(target)); use_piety(c->who, piety); take_prisoner(c->who, from); /* * Fri Mar 24 06:56:46 2000 -- Scott Turner * * Take prisoner doesn't actually transfer the animal into your * inventory, so we'll have to "create" one. * */ gen_item(c->who, type, 1); return TRUE; }; wout(c->who,"For some reason, you capture no beast."); return FALSE; }; wout(c->who, "You capture a %s from %s!",box_name(type), box_name(target)); use_piety(c->who, piety); return TRUE; };
int d_breed(struct command *c) { int i1 = c->a; int i2 = c->b; int offspring; int breed_accident = BREED_ACCIDENT; int killed = FALSE; if (is_real_npc(c->who)) return d_npc_breed(c); if (kind(i1) != T_item) { wout(c->who, "%s is not an item.", c->parse[1]); return FALSE; } if (kind(i2) != T_item) { wout(c->who, "%s is not an item.", c->parse[2]); return FALSE; } if (has_item(c->who, i1) < 1) { wout(c->who, "Don't have any %s.", box_code(i1)); return FALSE; } if (has_item(c->who, i2) < 1) { wout(c->who, "Don't have any %s.", box_code(i2)); return FALSE; } if (i1 == i2 && has_item(c->who, i1) < 2) { wout(c->who, "Don't have two %s.", box_code(i1)); return FALSE; } /* * A normal union just succeeds. * */ if (normal_union(i1, i2)) { offspring = find_breed(i1, i2); wout(c->who, "Produced %s.", box_name_qty(offspring, 1)); gen_item(c->who, offspring, 1); add_skill_experience(c->who, sk_breed_beasts); p_skill(sk_breed_beasts)->use_count++; return TRUE; }; /* * A non-normal union is more problematic. * */ if (!has_holy_symbol(c->who)) { wout(c->who, "A holy symbol is required for that breeding."); return FALSE; }; /* * Wed Feb 23 12:01:17 2000 -- Scott Turner * * Have to directly encode the piety required here so it won't * be charged automatically in use.c * */ if (!use_piety(c->who, 3)) { wout(c->who, "You don't have the piety required to use that prayer."); return FALSE; }; p_skill(sk_breed_beasts)->use_count++; /* * The following isn't quite right -- there is no chance of * killing both the breeders if they are of the same type. */ offspring = find_breed(i1, i2); if (offspring == item_dragon) breed_accident = 13; if (i1 == i2) breed_accident *= 2; if (i1 && rnd(1,100) <= breed_accident) { wout(c->who, "%s was killed in the breeding attempt.", cap(box_name_qty(i1, 1))); consume_item(c->who, i1, 1); killed = TRUE; } if (i2 && rnd(1,100) <= breed_accident && i1 != i2) { wout(c->who, "%s was killed in the breeding attempt.", cap(box_name_qty(i2, 1))); consume_item(c->who, i2, 1); killed = TRUE; } if (offspring == 0 || rnd(1,4) == 1) { wout(c->who, "No offspring was produced."); return FALSE; } wout(c->who, "Produced %s.", box_name_qty(offspring, 1)); gen_item(c->who, offspring, 1); add_skill_experience(c->who, sk_breed_beasts); return TRUE; };
// 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); }
void location_production() { int where; int i, enclosed; int terr, encl_terr; int has_city; float pop_grow = 0.0; int pop_limit = 200, pop, dpop = 0; loop_loc(where) { terr = subkind(where); has_city = 0; for (i = 0; terr_prod[i].terr; i++) if (terr_prod[i].terr == terr) { replenish(where, terr_prod[i].item, terr_prod[i].qty, terr_prod[i].max); } /* * Mon Sep 16 11:42:22 1996 -- Scott Turner * * Now check for production from enclosed locations... * */ loop_here(where, enclosed) { encl_terr = subkind(enclosed); if (encl_terr == sub_city) has_city = 1; for (i = 0; terr_prod2[i].terr; i++) if (terr_prod2[i].terr == encl_terr) { replenish(where, terr_prod2[i].item, terr_prod2[i].qty, terr_prod2[i].max); }; } next_here; /* * First limit poppy fields to normal production level. * Then double opium if poppy field was specially tended. */ if (terr == sub_poppy_field) { int n; n = has_item(where, item_opium); if (n > POPPY_OPIUM) consume_item(where, item_opium, n - POPPY_OPIUM); if (rp_misc(where) && rp_misc(where)->opium_double) { rp_misc(where)->opium_double = FALSE; gen_item(where, item_opium, has_item(where, item_opium)); } } if (terr == sub_island || (loc_depth(where) == LOC_province && has_ocean_access(where))) replenish(where, item_flotsam, 30, 30); /* * Sun Dec 1 10:34:41 1996 -- Scott Turner * * Peasant production. Depends upon the location (and * whether it contains a city). * * Has_city is set up above... * * Tue Sep 22 13:20:18 1998 -- Scott Turner * * Faery ought not have peasants. It should have (I guess) * elf peasants, although what you can do with those is * open to conjecture :-) * */ if (pop = has_item(where, item_peasant)) { if (has_city) { pop_grow = 0.03; pop_limit = 10000; } else { switch (terr) { case sub_plain: case sub_forest: pop_grow = 0.01; pop_limit = 1000; break; case sub_mountain: case sub_swamp: pop_grow = 0.005; pop_limit = 1000; break; default: pop_grow = 0.000; pop_limit = 500; break; }; }; /* * Might be an effect here. * */ if (get_effect(where, ef_grow, 0, 0)) { wout(where, "The peasants seem particularly happy this month."); pop_grow += 0.02; }; dpop = pop * pop_grow; if (pop_grow > 0.0 && dpop < 1) dpop = 1; /* * Lose population at a reasonable rate. * */ if (pop > pop_limit) dpop = -(pop - pop_limit) / 10; if (p_subloc(province(where))->loot && dpop > 0) { wout(where, "Pillaging traumatizes the population and no growth occurs."); } else if (dpop > 0) { if (pop > 100) wout(where, "The population grows by %s peasant%s.", nice_num(dpop), add_s(dpop)); gen_item(where, item_peasant, dpop); } else { if (pop > 100) wout(where, "Overcrowding causes %s peasant death%s.", nice_num(-dpop), add_s(-dpop)); consume_item(where, item_peasant, -dpop); }; }; /* * Sat Apr 18 16:57:53 1998 -- Scott Turner * * Special case for gold production from peasants. * They generate 1 gold per 20 peasants (1/10 in cities) * which accumulates to be removed by various means. * * Only in civilized (> 100) provinces */ if ((pop = has_item(where, item_peasant)) > 100) { if (has_city) { dpop = pop * 0.10; } else { dpop = pop * 0.05; }; gen_item(where, item_gold, dpop); }; }
// 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); }