void testa_random(char * name, project_parameters_t * pps, project_f_t *project_f, project_f_arr_t *project_f_arr, project_f_inv_t *project_f_inv, project_f_arr_inv_t *project_f_arr_inv, gen_lat_t *gen_lat, gen_lon_t *gen_lon) { { double lat, lon, x, y, lat_out, lon_out, lat_deg, lon_deg; int ok; lat_deg = gen_lat(); lon_deg = gen_lon(); lat = lat_deg * DEG_TO_RAD; lon = lon_deg * DEG_TO_RAD; x = y = lat_out = lon_out = HUGE_VAL; ok = FALSE; if (project_f(pps, lat, lon, &x, &y)) { if (project_f_inv(pps, x, y, &lat_out, &lon_out)) { ok = within_tol(lat, lat_out) && within_tol(lon, lon_out); } } if (ok) { ++nok; } else { printf("Fail: %s(%f,%f):" "(%f,%f) forward-> (%f,%f) inverse-> (%f,%f)\n", name, lat_deg, lon_deg, lat, lon, x, y, lat_out, lon_out); ++nfail; } } { double *lat_rad, *lon_rad; double *px, *py; double *lat_out, *lon_out; int i, ok = FALSE; lat_rad = (double *) malloc (sizeof(double) * ARR_TEST_SIZE); lon_rad = (double *) malloc (sizeof(double) * ARR_TEST_SIZE); px = py = lat_out = lon_out = NULL; for (i = 0; i < ARR_TEST_SIZE; ++i) { lat_rad[i] = gen_lat() * DEG_TO_RAD; lon_rad[i] = gen_lon() * DEG_TO_RAD; } if (project_f_arr(pps, lat_rad, lon_rad, &px, &py, ARR_TEST_SIZE)) { if (project_f_arr_inv(pps, px, py, &lat_out, &lon_out, ARR_TEST_SIZE)) { ok = TRUE; for (i = 0; i < ARR_TEST_SIZE; ++i) { if (!within_tol(lat_rad[i], lat_out[i]) || !within_tol(lon_rad[i], lon_out[i])) { printf("Fail: %s_arr:" "(%f,%f) forward-> (%f,%f) inverse-> (%f,%f)\n", name, lat_rad[i], lon_rad[i], px[i], py[i], lat_out[i], lon_out[i]); ok = FALSE; } } } } if (ok) { ++nok; } else { printf("Fail: %s_arr\n", name); ++nfail; } free(lon_out); free(lat_out); free(px); free(py); free(lon_rad); free(lat_rad); } }
/* * Handle monster hitting a real trap. */ void mon_hit_trap(int m_idx, int y, int x) { feature_type *f_ptr; monster_type *m_ptr = &m_list[m_idx]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; int feat = cave_feat[y][x]; bool fear; /* Option */ if (!variant_hit_traps) return; /* Hack --- don't activate unknown invisible traps */ if (cave_feat[y][x] == FEAT_INVIS) return; /* Get feature */ f_ptr = &f_info[cave_feat[y][x]]; /* Hack --- trapped doors */ /* XXX XXX Dangerous */ while (!(f_ptr->spell) && !(f_ptr->blow.method) && (f_ptr->flags1 & (FF1_TRAP))) { pick_trap(y,x); /* Error */ if (cave_feat[y][x] == feat) break; feat = cave_feat[y][x]; /* Get feature */ f_ptr = &f_info[feat]; } /* Use covered or bridged if necessary */ if ((f_ptr->flags2 & (FF2_COVERED)) || (f_ptr->flags2 & (FF2_BRIDGED))) { f_ptr = &f_info[f_ptr->mimic]; } /* Hack -- monster falls onto trap */ if ((m_ptr->fy!=y)|| (m_ptr->fx !=x)) { /* Move monster */ monster_swap(m_ptr->fy, m_ptr->fx, y, x); } /* Apply the object */ if ((cave_o_idx[y][x]) && (f_ptr->flags1 & (FF1_HIT_TRAP))) { object_type *o_ptr = &o_list[cave_o_idx[y][x]]; char o_name[80]; int power = 0; switch (o_ptr->tval) { case TV_BOW: { object_type *j_ptr; u32b f1,f2,f3; int i, shots = 1; /* Get bow */ j_ptr = o_ptr; /* Get bow flags */ object_flags(o_ptr,&f1,&f2,&f3); /* Apply extra shots */ if (f1 & (TR1_SHOTS)) shots += j_ptr->pval; /* Test for hit */ for (i = 0; i < shots; i++) { if (j_ptr->next_o_idx) { int ammo = j_ptr->next_o_idx; object_type *i_ptr; object_type object_type_body; /* Use ammo instead of bow */ o_ptr = &o_list[ammo]; /* Describe ammo */ object_desc(o_name, sizeof(o_name), o_ptr, TRUE, 0); if ((ammo) && (test_hit_fire((j_ptr->to_h + o_ptr->to_h)* BTH_PLUS_ADJ + f_ptr->power, r_ptr->ac * (r_ptr->flags2 & (RF2_ARMOR) ? 2 : 1), TRUE))) { int k, mult; switch (j_ptr->sval) { case SV_SLING: case SV_SHORT_BOW: mult = 2; break; case SV_LONG_BOW: case SV_LIGHT_XBOW: mult = 3; break; case SV_HEAVY_XBOW: mult = 4; break; default: mult = 1; break; } /* Apply extra might */ if (f1 & (TR1_MIGHT)) mult += j_ptr->pval; k = damroll(o_ptr->dd, o_ptr->ds); k *= mult; k = tot_dam_aux(o_ptr, k, m_ptr); k = critical_shot(o_ptr->weight, o_ptr->to_h + j_ptr->to_h, k); k += o_ptr->to_d + j_ptr->to_d; /* No negative damage */ if (k < 0) k = 0; /* Trap description */ msg_format("%^s hits you.",o_name); /* Damage, check for fear and death */ (void)mon_take_hit(cave_m_idx[y][x], k, &fear, NULL); } else { /* Trap description */ msg_format("%^s narrowly misses you.",o_name); } /* Get local object */ i_ptr = &object_type_body; /* Obtain a local object */ object_copy(i_ptr, o_ptr); /* Modify quantity */ i_ptr->number = 1; /* Drop nearby - some chance of breakage */ drop_near(i_ptr,y,x,breakage_chance(i_ptr)); /* Decrease the item */ floor_item_increase(ammo, -1); floor_item_optimize(ammo); break; } else { /* Disarm */ cave_alter_feat(y,x,FS_DISARM); } } } case TV_SHOT: case TV_ARROW: case TV_BOLT: case TV_HAFTED: case TV_SWORD: case TV_POLEARM: { object_type *i_ptr; object_type object_type_body; /* Describe ammo */ object_desc(o_name, sizeof(o_name), o_ptr, TRUE, 0); /* Test for hit */ if (test_hit_norm(o_ptr->to_h * BTH_PLUS_ADJ + f_ptr->power, r_ptr->ac, TRUE)) { int k; k = damroll(o_ptr->dd, o_ptr->ds); k = tot_dam_aux(o_ptr, k, m_ptr); k = critical_norm(o_ptr->weight, o_ptr->to_h, k); k += o_ptr->to_d; /* Armour reduces total damage */ k -= (k * ((p_ptr->ac < 150) ? p_ptr->ac : 150) / 250); /* No negative damage */ if (k < 0) k = 0; /* Trap description */ msg_format("%^s hits you.",o_name); /* Damage, check for fear and death */ (void)mon_take_hit(cave_m_idx[y][x], k, &fear, NULL); } else { /* Trap description */ msg_format("%^s narrowly misses you.",o_name); } /* Get local object */ i_ptr = &object_type_body; /* Obtain a local object */ object_copy(i_ptr, o_ptr); /* Modify quantity */ i_ptr->number = 1; /* Drop nearby - some chance of breakage */ drop_near(i_ptr,y,x,breakage_chance(i_ptr)); /* Decrease the item */ floor_item_increase(cave_o_idx[y][x], -1); floor_item_optimize(cave_o_idx[y][x]); /* Disarm if runs out */ if (!cave_o_idx[y][x]) cave_alter_feat(y,x,FS_DISARM); break; } case TV_WAND: case TV_STAFF: { if (o_ptr->pval > 0) { /* Get item effect */ get_spell(&power, "use", o_ptr, FALSE); /* XXX Hack -- new unstacking code */ o_ptr->stackc++; /* No spare charges */ if (o_ptr->stackc >= o_ptr->number) { /* Use a charge off the stack */ o_ptr->pval--; /* Reset the stack count */ o_ptr->stackc = 0; } /* XXX Hack -- unstack if necessary */ if ((o_ptr->number > 1) && ((!variant_pval_stacks) || ((!object_known_p(o_ptr) && (o_ptr->pval == 2) && (o_ptr->stackc > 1)) || (!object_known_p(o_ptr) && (rand_int(o_ptr->number) <= o_ptr->stackc) && (o_ptr->stackc != 1) && (o_ptr->pval > 2))))) { object_type *i_ptr; object_type object_type_body; /* Get local object */ i_ptr = &object_type_body; /* Obtain a local object */ object_copy(i_ptr, o_ptr); /* Modify quantity */ i_ptr->number = 1; /* Reset stack counter */ i_ptr->stackc = 0; /* Unstack the used item */ o_ptr->number--; /* Reduce the charges on the new item */ if (o_ptr->stackc > 1) { i_ptr->pval-=2; o_ptr->stackc--; } else if (!o_ptr->stackc) { i_ptr->pval--; o_ptr->pval++; o_ptr->stackc = o_ptr->number-1; } (void)floor_carry(y,x,i_ptr); } } else { /* Disarm if runs out */ cave_alter_feat(y,x,FS_DISARM); } break; } case TV_ROD: case TV_DRAG_ARMOR: { if (!((o_ptr->timeout) && ((!o_ptr->stackc) || (o_ptr->stackc >= o_ptr->number)))) { int tmpval; /* Store pval */ tmpval = o_ptr->timeout; /* Time rod out */ o_ptr->timeout = o_ptr->pval; /* Get item effect */ get_spell(&power, "use", o_ptr, FALSE); /* Has a power */ /* Hack -- check if we are stacking rods */ if ((o_ptr->timeout > 0) && (!(tmpval) || stack_force_times)) { /* Hack -- one more rod charging */ if (o_ptr->timeout) o_ptr->stackc++; /* Reset stack count */ if (o_ptr->stackc == o_ptr->number) o_ptr->stackc = 0; /* Hack -- always use maximum timeout */ if (tmpval > o_ptr->timeout) o_ptr->timeout = tmpval; } /* XXX Hack -- unstack if necessary */ if ((o_ptr->number > 1) && (o_ptr->timeout > 0)) { object_type *i_ptr; object_type object_type_body; /* Get local object */ i_ptr = &object_type_body; /* Obtain a local object */ object_copy(i_ptr, o_ptr); /* Modify quantity */ i_ptr->number = 1; /* Clear stack counter */ i_ptr->stackc = 0; /* Restore "charge" */ o_ptr->timeout = tmpval; /* Unstack the used item */ o_ptr->number--; /* Reset the stack if required */ if (o_ptr->stackc == o_ptr->number) o_ptr->stackc = 0; (void)floor_carry(y,x,i_ptr); } } break; } case TV_POTION: case TV_SCROLL: case TV_FLASK: case TV_FOOD: { /* Hack -- boring food */ if ((o_ptr->tval == TV_FOOD) && (o_ptr->sval >= SV_FOOD_MIN_FOOD)) { /* Disarm */ cave_alter_feat(y,x,FS_DISARM); } else { /* Get item effect */ get_spell(&power, "use", o_ptr, FALSE); /* Decrease the item */ floor_item_increase(cave_o_idx[y][x], -1); floor_item_optimize(cave_o_idx[y][x]); /* Disarm if runs out */ if (!cave_o_idx[y][x]) cave_alter_feat(y,x,FS_DISARM); } break; } case TV_RUNESTONE: { u32b runes = p_ptr->cur_runes; int num = 0; s16b book[26]; /* Hack -- use current rune */ p_ptr->cur_runes = (2 << (o_ptr->sval-1)); /* Fill the book with spells */ fill_book(o_ptr,book,&num); /* Unhack */ p_ptr->cur_runes = runes; /* Get a power */ power = book[rand_int(num)]; /* Decrease the item */ floor_item_increase(cave_o_idx[y][x], -1); floor_item_optimize(cave_o_idx[y][x]); /* Disarm if runs out */ if (!cave_o_idx[y][x]) cave_alter_feat(y,x,FS_DISARM); break; } default: { /* Disarm */ cave_alter_feat(y,x,FS_DISARM); break; } } /* Has a power */ if (power > 0) { spell_type *s_ptr = &s_info[power]; int ap_cnt; /* Object is used */ if (k_info[o_ptr->k_idx].used < MAX_SHORT) k_info[o_ptr->k_idx].used++; /* Scan through all four blows */ for (ap_cnt = 0; ap_cnt < 4; ap_cnt++) { int damage = 0; /* Extract the attack infomation */ int effect = s_ptr->blow[ap_cnt].effect; int method = s_ptr->blow[ap_cnt].method; int d_dice = s_ptr->blow[ap_cnt].d_dice; int d_side = s_ptr->blow[ap_cnt].d_side; int d_plus = s_ptr->blow[ap_cnt].d_plus; /* Hack -- no more attacks */ if (!method) break; /* Mega hack -- dispel evil/undead objects */ if (!d_side) { d_plus += 25 * d_dice; } /* Roll out the damage */ if ((d_dice) && (d_side)) { damage = damroll(d_dice, d_side) + d_plus; } else { damage = d_plus; } (void)project_m(0,0,y,x,damage, effect); (void)project_f(0,0,y,x,damage, effect); } } } /* Regular traps */ else { if (f_ptr->spell) { make_attack_spell_aux(0,y,x,f_ptr->spell); } else if (f_ptr->blow.method) { int damage = damroll(f_ptr->blow.d_side,f_ptr->blow.d_dice); /* Apply the blow */ project_m(0, 0, y, x, damage, f_ptr->blow.effect); } /* Get feature */ f_ptr = &f_info[cave_feat[p_ptr->py][p_ptr->px]]; if (f_ptr->flags1 & (FF1_HIT_TRAP)) { /* Modify the location hit by the trap */ cave_alter_feat(y,x,FS_HIT_TRAP); } else if (f_ptr->flags1 & (FF1_SECRET)) { /* Discover */ cave_alter_feat(y,x,FS_SECRET); } } }