/* * Is object @p of type @type visible to the player? * TODO: Fold this into interators. */ static int xdvisible(int type, void *p) { struct empobj *gp = p; struct lonstr *lp = p; struct natstr *natp; int tlev; if (!empobj_in_use(type, p)) return 0; switch (type) { case EF_SECTOR: case EF_SHIP: case EF_PLANE: case EF_LAND: case EF_NUKE: case EF_LOST: case EF_REALM: return gp->own == player->cnum || player->god; case EF_COUNTRY: return gp->own == player->cnum; case EF_NEWS: return !opt_HIDDEN || player->god; /* FIXME */ case EF_LOAN: if (lp->l_status == LS_SIGNED) return 1; return lp->l_loner == player->cnum || lp->l_lonee == player->cnum || player->god; case EF_SHIP_CHR: tlev = ((struct mchrstr *)p)->m_tech; goto tech; case EF_PLANE_CHR: tlev = ((struct plchrstr *)p)->pl_tech; goto tech; case EF_LAND_CHR: tlev = ((struct lchrstr *)p)->l_tech; tech: natp = getnatp(player->cnum); return player->god || tlev <= (int)(1.25 * natp->nat_level[NAT_TLEV]); case EF_NUKE_CHR: tlev = ((struct nchrstr *)p)->n_tech; if (drnuke_const > MIN_DRNUKE_CONST) { natp = getnatp(player->cnum); if (tlev > (int)((int)(1.25 * natp->nat_level[NAT_RLEV]) / drnuke_const)) return player->god; } goto tech; case EF_TABLE: return ((struct empfile *)p)->cadef != NULL; default: return 1; } }
static int verify_tabref(int type, int row, struct castr *ca, int idx, long val) { int tabno = ca->ca_table; struct castr *ca_sym = ef_cadef(tabno); int i; if (ca->ca_flags & NSC_BITS) { /* symbol set */ if (CANT_HAPPEN(ca_sym != symbol_ca)) return -1; for (i = 0; i < (int)sizeof(long) * 8; i++) { if (val & (1UL << i)) { if (!symbol_by_value(1L << i, ef_ptr(tabno, 0))) { verify_fail(type, row, ca, idx, "bit %d is not in symbol table %s", i, ef_nameof(tabno)); return -1; } } } } else if (ca_sym == symbol_ca) { /* symbol */ if (!symbol_by_value(val, ef_ptr(tabno, 0))) { verify_fail(type, row, ca, idx, "value %ld is not in symbol table %s", val, ef_nameof(tabno)); return -1; } } else { /* table index */ if (val >= ef_nelem(tabno) || val < -1) { verify_fail(type, row, ca, idx, "value %ld indexes table %s out of bounds 0..%d", val, ef_nameof(tabno), ef_nelem(tabno)); return -1; } /* laziness: assumes TABNO is EFF_MEM */ if (val >= 0 && !empobj_in_use(tabno, ef_ptr(tabno, val))) { verify_fail(type, row, ca, idx, "value %ld refers to missing element of table %s", val, ef_nameof(tabno)); return -1; } } return 0; }
static int verify_row(int type, int row) { struct castr *ca = ef_cadef(type); struct empobj *row_ref; int i, j, n; struct valstr val; int ret_val = 0; int flags = ef_flags(type); if (flags & EFF_MEM) row_ref = ef_ptr(type, row); else { row_ref = malloc(empfile[type].size); ef_read(type, row, row_ref); } if ((flags & EFF_TYPED) && !EF_IS_VIEW(type)) { if (row_ref->ef_type != type || row_ref->uid != row) { verify_fail(type, row, NULL, 0, "header corrupt"); ret_val = -1; } } if (!empobj_in_use(type, row_ref)) goto out; for (i = 0; ca[i].ca_name; ++i) { if (ca[i].ca_get) continue; /* virtual */ n = CA_ARRAY_LEN(&ca[i]); j = 0; do { if (ca[i].ca_table == EF_BAD) continue; nstr_mksymval(&val, &ca[i], j); nstr_eval(&val, 0, row_ref, NSC_NOTYPE); if (CANT_HAPPEN(val.val_type != NSC_LONG)) { ret_val = -1; continue; } if (ca[i].ca_table == type && i == 0) { /* uid */ if (val.val_as.lng != row) { verify_fail(type, row, &ca[i], j, "value is %ld instead of %d", val.val_as.lng, row); ret_val = -1; } } else { if (verify_tabref(type, row, &ca[i], j, val.val_as.lng) < 0) ret_val = -1; } } while (++j < n); } out: if (!(flags & EFF_MEM)) free(row_ref); return ret_val; }