Exemple #1
0
int
do_look(int type)
{
    int i;
    struct nstr_item ni;
    union empobj_storage unit;
    struct sctstr sect;
    int x, y;
    unsigned char *bitmap;
    int changed = 0;

    if (CANT_HAPPEN(type != EF_LAND && type != EF_SHIP))
	type = EF_SHIP;

    if (!snxtitem(&ni, type, player->argp[1], NULL))
	return RET_SYN;
    bitmap = calloc((WORLD_SZ() + 7) / 8, 1);
    if (!bitmap) {
	logerror("malloc failed in do_look\n");
	pr("Memory error.  Tell the deity.\n");
	return RET_FAIL;
    }
    while (nxtitem(&ni, &unit)) {
	if (!player->owner)
	    continue;
	if (type == EF_LAND) {
	    if (unit.land.lnd_ship >= 0)
		continue;
	    if (unit.land.lnd_land >= 0)
		continue;
	    /* Spies don't need military to do a "llook".  Other
	       units do */
	    if ((unit.land.lnd_item[I_MILIT] <= 0) &&
		!(lchr[(int)unit.land.lnd_type].l_flags & L_SPY))
		continue;
	    look_land(&unit.land);
	} else
	    look_ship(&unit.ship);
	for (i = 0; i <= 6; i++) {
	    x = diroff[i][0] + unit.gen.x;
	    y = diroff[i][1] + unit.gen.y;
	    if (emp_getbit(x, y, bitmap))
		continue;
	    emp_setbit(x, y, bitmap);
	    getsect(x, y, &sect);
	    if (sect.sct_type == SCT_WATER)
		continue;
	    look_at_sect(&sect, 10);
	    changed += map_set(player->cnum, x, y,
			       dchr[sect.sct_type].d_mnem, 0);
	    if (opt_HIDDEN) {
		setcont(player->cnum, sect.sct_own, FOUND_LOOK);
	    }
	}
    }
    if (changed)
	writemap(player->cnum);
    free(bitmap);
    return RET_OK;
}
Exemple #2
0
/* Setup call to metamethod to be run by Assembler VM. */
static TValue *mmcall(lua_State *L, ASMFunction cont, cTValue *mo,
		    cTValue *a, cTValue *b)
{
  /*
  **           |-- framesize -> top       top+1       top+2 top+3
  ** before:   [func slots ...]
  ** mm setup: [func slots ...] [cont|?]  [mo|tmtype] [a]   [b]
  ** in asm:   [func slots ...] [cont|PC] [mo|delta]  [a]   [b]
  **           ^-- func base                          ^-- mm base
  ** after mm: [func slots ...]           [result]
  **                ^-- copy to base[PC_RA] --/     for lj_cont_ra
  **                          istruecond + branch   for lj_cont_cond*
  **                                       ignore   for lj_cont_nop
  ** next PC:  [func slots ...]
  */
  TValue *top = L->top;
  if (curr_funcisL(L)) top = curr_topL(L);
  setcont(top++, cont);  /* Assembler VM stores PC in upper word or FR2. */
  if (LJ_FR2) setnilV(top++);
  copyTV(L, top++, mo);  /* Store metamethod and two arguments. */
  if (LJ_FR2) setnilV(top++);
  copyTV(L, top, a);
  copyTV(L, top+1, b);
  return top;  /* Return new base. */
}
Exemple #3
0
/* Helper for equality comparisons. __eq metamethod. */
TValue *lj_meta_equal(lua_State *L, GCobj *o1, GCobj *o2, int ne)
{
  /* Field metatable must be at same offset for GCtab and GCudata! */
  cTValue *mo = lj_meta_fast(L, tabref(o1->gch.metatable), MM_eq);
  if (mo) {
    TValue *top;
    uint32_t it;
    if (tabref(o1->gch.metatable) != tabref(o2->gch.metatable)) {
      cTValue *mo2 = lj_meta_fast(L, tabref(o2->gch.metatable), MM_eq);
      if (mo2 == NULL || !lj_obj_equal(mo, mo2))
	return (TValue *)(intptr_t)ne;
    }
    top = curr_top(L);
    setcont(top, ne ? lj_cont_condf : lj_cont_condt);
    copyTV(L, top+1, mo);
    it = ~(uint32_t)o1->gch.gct;
    setgcV(L, top+2, o1, it);
    setgcV(L, top+3, o2, it);
    return top+2;  /* Trigger metamethod call. */
  }
  return (TValue *)(intptr_t)ne;
}
Exemple #4
0
static int
showsat(struct sky **skypp, int x, int y)
{
    struct sky *skyp;
    struct sky *todelete = NULL;
    struct sky **prev;
    int nsat = 0;

    prev = NULL;
    skyp = *skypp;
    prev = skypp;
    do {
	/* we delete it, we free it. */
	if (todelete) {
	    free(todelete);
	    todelete = NULL;
	}
	if (skyp->s_sat.pln_x != x || skyp->s_sat.pln_y != y) {
	    prev = &(*prev)->s_next;
	    continue;
	}
	pr(" %12.12s (#%3d) %s @ %s\n",
	   cname(skyp->s_sat.pln_own), skyp->s_sat.pln_own,
	   prplane(&skyp->s_sat), xyas(x, y, player->cnum));
	if (opt_HIDDEN) {
	    /* FOUND_COAST should probably be changed to FOUND_SKY -KHS */
	    setcont(player->cnum, skyp->s_sat.pln_own, FOUND_COAST);
	}
	*prev = skyp->s_next;
	todelete = skyp;
	nsat++;
    } while (NULL != (skyp = skyp->s_next));
    /* check that last one! */
    if (todelete)
	free(todelete);
    return nsat;
}
Exemple #5
0
static int
showship(struct coast **cpp, int x, int y)
{
    struct coast *cp;
    struct coast *todelete = NULL;
    struct coast **prev;
    int nship = 0;

    prev = NULL;
    cp = *cpp;
    prev = cpp;
    do {
	/* we delete it, we free it. */
	if (todelete) {
	    free(todelete);
	    todelete = NULL;
	}
	if (cp->c_shp.shp_x != x || cp->c_shp.shp_y != y) {
	    prev = &(*prev)->c_next;
	    continue;
	}
	pr(" %12.12s (#%3d) %s @ %s\n",
	   cname(cp->c_shp.shp_own), cp->c_shp.shp_own,
	   prship(&cp->c_shp), xyas(x, y, player->cnum));
	if (opt_HIDDEN) {
	    setcont(player->cnum, cp->c_shp.shp_own, FOUND_COAST);
	}
	*prev = cp->c_next;
	todelete = cp;
	nship++;
    } while (NULL != (cp = cp->c_next));
    /* check that last one! */
    if (todelete)
	free(todelete);
    return nship;
}
Exemple #6
0
void
setrel(natid us, natid them, int rel)
{
    struct natstr *mynp = getnatp(us);
    struct natstr *themnp = getnatp(them);
    int oldrel;
    char *whichway;
    int n_up = 0;
    int n_down = 0;
    char *addendum = NULL;

    if (CANT_HAPPEN(rel < AT_WAR))
	rel = AT_WAR;
    if (CANT_HAPPEN(rel > ALLIED))
	rel = ALLIED;
    if (CANT_HAPPEN(!mynp || !themnp))
	return;
    if (us == them)
	return;
    oldrel = relations_with(us, them);
    if (oldrel == rel)
	return;
    if (rel > oldrel)
	whichway = "upgraded";
    else
	whichway = "downgraded";
    if (rel == ALLIED) {
	addendum = "Congratulations!";
	n_up = N_DECL_ALLY;
    } else if (rel == FRIENDLY) {
	n_up = N_UP_FRIENDLY;
	n_down = N_DOWN_FRIENDLY;
    } else if (rel == NEUTRAL) {
	n_up = N_UP_NEUTRAL;
	n_down = N_DOWN_NEUTRAL;
    } else if (rel == HOSTILE) {
	addendum = "Another cold war...";
	n_up = N_UP_HOSTILE;
	n_down = N_DOWN_HOSTILE;
    } else if (rel < HOSTILE) {
	addendum = "Declaration made (give 'em hell).";
	n_down = N_DECL_WAR;
    }

    if (addendum && us == player->cnum && !update_running)
	pr("%s\n", addendum);
    mpr(us, "Diplomatic relations with %s %s to \"%s\".\n",
	cname(them), whichway, relates[rel]);
    if (!(getrejects(us, themnp) & REJ_TELE))
	mpr(them,
	    "Country %s has %s their relations with you to \"%s\"!\n",
	    prnat(mynp), whichway, relates[rel]);

    putrel(mynp, them, rel);
    putnat(mynp);

    if (!player->god) {
	if (oldrel == ALLIED)
	    nreport(us, N_DIS_ALLY, them, 1);
	else if (oldrel < HOSTILE && rel >= HOSTILE)
	    nreport(us, N_DIS_WAR, them, 1);
	if (rel > oldrel)
	    nreport(us, n_up, them, 1);
	else
	    nreport(us, n_down, them, 1);
    }
    if (opt_HIDDEN)
	setcont(them, us, FOUND_TELE);
}
Exemple #7
0
/* Helper for CAT. Coercion, iterative concat, __concat metamethod. */
TValue *lj_meta_cat(lua_State *L, TValue *top, int left)
{
  int fromc = 0;
  if (left < 0) { left = -left; fromc = 1; }
  do {
    if (!(tvisstr(top) || tvisnumber(top)) ||
	!(tvisstr(top-1) || tvisnumber(top-1))) {
      cTValue *mo = lj_meta_lookup(L, top-1, MM_concat);
      if (tvisnil(mo)) {
	mo = lj_meta_lookup(L, top, MM_concat);
	if (tvisnil(mo)) {
	  if (tvisstr(top-1) || tvisnumber(top-1)) top++;
	  lj_err_optype(L, top-1, LJ_ERR_OPCAT);
	  return NULL;  /* unreachable */
	}
      }
      /* One of the top two elements is not a string, call __cat metamethod:
      **
      ** before:    [...][CAT stack .........................]
      **                                 top-1     top         top+1 top+2
      ** pick two:  [...][CAT stack ...] [o1]      [o2]
      ** setup mm:  [...][CAT stack ...] [cont|?]  [mo|tmtype] [o1]  [o2]
      ** in asm:    [...][CAT stack ...] [cont|PC] [mo|delta]  [o1]  [o2]
      **            ^-- func base                              ^-- mm base
      ** after mm:  [...][CAT stack ...] <--push-- [result]
      ** next step: [...][CAT stack .............]
      */
      copyTV(L, top+2*LJ_FR2+2, top);  /* Carefully ordered stack copies! */
      copyTV(L, top+2*LJ_FR2+1, top-1);
      copyTV(L, top+LJ_FR2, mo);
      setcont(top-1, lj_cont_cat);
      if (LJ_FR2) { setnilV(top); setnilV(top+2); top += 2; }
      return top+1;  /* Trigger metamethod call. */
    } else {
      /* Pick as many strings as possible from the top and concatenate them:
      **
      ** before:    [...][CAT stack ...........................]
      ** pick str:  [...][CAT stack ...] [...... strings ......]
      ** concat:    [...][CAT stack ...] [result]
      ** next step: [...][CAT stack ............]
      */
      TValue *e, *o = top;
      uint64_t tlen = tvisstr(o) ? strV(o)->len : STRFMT_MAXBUF_NUM;
      char *p, *buf;
      do {
	o--; tlen += tvisstr(o) ? strV(o)->len : STRFMT_MAXBUF_NUM;
      } while (--left > 0 && (tvisstr(o-1) || tvisnumber(o-1)));
      if (tlen >= LJ_MAX_STR) lj_err_msg(L, LJ_ERR_STROV);
      p = buf = lj_buf_tmp(L, (MSize)tlen);
      for (e = top, top = o; o <= e; o++) {
	if (tvisstr(o)) {
	  GCstr *s = strV(o);
	  MSize len = s->len;
	  p = lj_buf_wmem(p, strdata(s), len);
	} else if (tvisint(o)) {
	  p = lj_strfmt_wint(p, intV(o));
	} else {
	  lua_assert(tvisnum(o));
	  p = lj_strfmt_wnum(p, o);
	}
      }
      setstrV(L, top, lj_str_new(L, buf, (size_t)(p-buf)));
    }
  } while (left >= 1);
  if (LJ_UNLIKELY(G(L)->gc.total >= G(L)->gc.threshold)) {
    if (!fromc) L->top = curr_topL(L);
    lj_gc_step(L);
  }
  return NULL;
}
Exemple #8
0
int
tele(void)
{
    natid to;
    struct natstr *natp;
    char buf[MAXTELSIZE + 1];	/* UTF-8 */
    int n;

    if (*player->argp[0] == 'a') {
	if (getele("everybody", buf) <= 0) {
	    pr("Announcement aborted\n");
	    return RET_FAIL;
	}
	pr("\n");
	to = 0;
	if (typed_wu(player->cnum, to, buf, TEL_ANNOUNCE) < 0)
	    logerror("tele: typed_wu failed to #%d", to);
    } else if (*player->argp[0] == 'p') {
	if (getele("your Gracious Deity", buf) <= 0) {
	    pr("Prayer aborted\n");
	    return RET_FAIL;
	}
	pr("\n");
	if (typed_wu(player->cnum, 0, buf, TEL_NORM) < 0)
	    logerror("tele: typed_wu failed to #0");
    } else {
	int kk;

	kk = 1;
	do {
	    if ((n = natarg(player->argp[kk], "for which country? ")) < 0)
		return RET_SYN;
	    to = n;

	    if (kk == 1) {
		if (player->argp[2]) {
		    if (getele("multiple recipients", buf) < 0) {
			pr("Telegram aborted\n");
			return RET_FAIL;
		    }
		} else {
		    if (getele(cname(to), buf) < 0) {
			pr("Telegram aborted\n");
			return RET_FAIL;
		    }
		}
		pr("\n");
	    }

	    natp = getnatp(to);
	    if (natp->nat_stat < STAT_SANCT) {
		pr("%s has no \"telegram privileges\".\n", cname(to));
		kk++;
		continue;
	    }
	    if (!player->god
		&& (getrejects(player->cnum, natp) & REJ_TELE)) {
		pr("%s is rejecting your telegrams.\n", cname(to));
		return RET_SYN;
	    }
	    if (typed_wu(player->cnum, to, buf, TEL_NORM) < 0) {
		logerror("tele: typed_wu failed to #%d", n);
		return RET_FAIL;
	    }

	    if (!player->god && natp->nat_stat != STAT_GOD
		&& player->cnum != to)
		nreport(player->cnum, N_SENT_TEL, to, 1);
	    if (opt_HIDDEN) {
		setcont(to, player->cnum, FOUND_TELE);
	    }
	    kk++;
	} while (player->argp[kk] != NULL);
    }
    return RET_OK;
}
Exemple #9
0
/* Helper for CAT. Coercion, iterative concat, __concat metamethod. */
TValue *lj_meta_cat(lua_State *L, TValue *top, int left)
{
  do {
    int n = 1;
    if (!(tvisstr(top-1) || tvisnumber(top-1)) || !tostring(L, top)) {
      cTValue *mo = lj_meta_lookup(L, top-1, MM_concat);
      if (tvisnil(mo)) {
	mo = lj_meta_lookup(L, top, MM_concat);
	if (tvisnil(mo)) {
	  if (tvisstr(top-1) || tvisnumber(top-1)) top++;
	  lj_err_optype(L, top-1, LJ_ERR_OPCAT);
	  return NULL;  /* unreachable */
	}
      }
      /* One of the top two elements is not a string, call __cat metamethod:
      **
      ** before:    [...][CAT stack .........................]
      **                                 top-1     top         top+1 top+2
      ** pick two:  [...][CAT stack ...] [o1]      [o2]
      ** setup mm:  [...][CAT stack ...] [cont|?]  [mo|tmtype] [o1]  [o2]
      ** in asm:    [...][CAT stack ...] [cont|PC] [mo|delta]  [o1]  [o2]
      **            ^-- func base                              ^-- mm base
      ** after mm:  [...][CAT stack ...] <--push-- [result]
      ** next step: [...][CAT stack .............]
      */
      copyTV(L, top+2, top);  /* Careful with the order of stack copies! */
      copyTV(L, top+1, top-1);
      copyTV(L, top, mo);
      setcont(top-1, lj_cont_cat);
      return top+1;  /* Trigger metamethod call. */
    } else if (strV(top)->len == 0) {  /* Shortcut. */
      (void)tostring(L, top-1);
    } else {
      /* Pick as many strings as possible from the top and concatenate them:
      **
      ** before:    [...][CAT stack ...........................]
      ** pick str:  [...][CAT stack ...] [...... strings ......]
      ** concat:    [...][CAT stack ...] [result]
      ** next step: [...][CAT stack ............]
      */
      MSize tlen = strV(top)->len;
      char *buffer;
      int i;
      for (n = 1; n <= left && tostring(L, top-n); n++) {
	MSize len = strV(top-n)->len;
	if (len >= LJ_MAX_STR - tlen)
	  lj_err_msg(L, LJ_ERR_STROV);
	tlen += len;
      }
      buffer = lj_str_needbuf(L, &G(L)->tmpbuf, tlen);
      n--;
      tlen = 0;
      for (i = n; i >= 0; i--) {
	MSize len = strV(top-i)->len;
	memcpy(buffer + tlen, strVdata(top-i), len);
	tlen += len;
      }
      setstrV(L, top-n, lj_str_new(L, buffer, tlen));
    }
    left -= n;
    top -= n;
  } while (left >= 1);
  lj_gc_check_fixtop(L);
  return NULL;
}
Exemple #10
0
static void
look_land(struct lndstr *lookland)
{
    struct plnstr *pp;
    struct lndstr *lp;
    double drange;
    int range;
    int vrange;
    int i;
    int dist;

    drange = techfact(lookland->lnd_tech, lchr[lookland->lnd_type].l_spy);
    drange *= lookland->lnd_effic / 100.0;
    range = ldround(drange, 1);

    if (range == 0)
	return;

    for (i = 0; NULL != (lp = getlandp(i)); i++) {
	if (lp->lnd_own == player->cnum || lp->lnd_own == 0)
	    continue;
	if (lp->lnd_ship >= 0 || lp->lnd_land >= 0)
	    continue;
	/* Don't always see spies */
	if (lchr[(int)lp->lnd_type].l_flags & L_SPY) {
	    /* If it's on a ship or unit, assume it's hidden
	       enough not to be seen */
	    if (lp->lnd_ship >= 0 || lp->lnd_land >= 0)
		continue;
	    if (!(chance(LND_SPY_DETECT_CHANCE(lp->lnd_effic))))
		continue;
	}
	vrange = ldround((lnd_vis(lp) * range) / 20.0, 1);
	dist = mapdist(lp->lnd_x, lp->lnd_y,
		       lookland->lnd_x, lookland->lnd_y);
	if (dist > vrange)
	    continue;

	pr("%s %s (approx %d mil) @ %s\n",
	   prnatid(lp->lnd_own), prland(lp),
	   roundintby(lp->lnd_item[I_MILIT], 20),
	   xyas(lp->lnd_x, lp->lnd_y, player->cnum));
	if (opt_HIDDEN)
	    setcont(player->cnum, lp->lnd_own, FOUND_LOOK);
    }
    for (i = 0; NULL != (pp = getplanep(i)); i++) {
	if (pp->pln_own == player->cnum || pp->pln_own == 0)
	    continue;
	if (pp->pln_ship >= 0 || pp->pln_land >= 0)
	    continue;
	if (pp->pln_flags & PLN_LAUNCHED)
	    continue;
	vrange = ldround((10 * range) / 20.0, 1);
	dist = mapdist(pp->pln_x, pp->pln_y,
		       lookland->lnd_x, lookland->lnd_y);
	if (dist > vrange)
	    continue;

	pr("%s %s @ %s\n",
	   prnatid(pp->pln_own), prplane(pp),
	   xyas(pp->pln_x, pp->pln_y, player->cnum));
	if (opt_HIDDEN)
	    setcont(player->cnum, pp->pln_own, FOUND_LOOK);
    }
}
Exemple #11
0
static void
look_ship(struct shpstr *lookship)
{
    struct shpstr *sp;
    struct mchrstr *smcp;
    struct mchrstr *tmcp;
    struct sctstr sect;
    int range;
    int vrange;
    int i;
    int dist;

    range = (int)techfact(lookship->shp_tech,
			  mchr[(int)lookship->shp_type].m_vrnge);
    range = range * (lookship->shp_effic / 100.0);
    smcp = &mchr[(int)lookship->shp_type];
    if (smcp->m_flags & M_SUB)
	range = MIN(range, 1);
    for (i = 0; NULL != (sp = getshipp(i)); i++) {
	if (sp->shp_own == player->cnum || sp->shp_own == 0)
	    continue;
	dist = mapdist(sp->shp_x, sp->shp_y,
		       lookship->shp_x, lookship->shp_y);
	if (dist > ship_max_interdiction_range)
	    continue;
	tmcp = &mchr[(int)sp->shp_type];
	if (smcp->m_flags & M_SUB)
	    vrange = (int)(shp_visib(sp) * range / 30.0);
	else
	    vrange = (int)(shp_visib(sp) * range / 20.0);
	getsect(sp->shp_x, sp->shp_y, &sect);
	if (sect.sct_type != SCT_WATER)
	    vrange = MAX(1, vrange);
	if (dist > vrange)
	    continue;
	if (smcp->m_flags & M_SUB) {
	    if (tmcp->m_flags & M_SONAR && dist < 2) {
		if (sp->shp_own != 0)
		    wu(0, sp->shp_own,
		       "%s detected surfacing noises in %s.\n",
		       prship(sp),
		       xyas(lookship->shp_x, lookship->shp_y,
			    sp->shp_own));
	    }
	    if (dist == 0 && (tmcp->m_flags & M_SUB) == 0)
		if (sp->shp_own != 0)
		    wu(0, sp->shp_own,
		       "Periscope spotted in %s by %s\n",
		       xyas(lookship->shp_x, lookship->shp_y,
			    sp->shp_own), prship(sp));
	}
	/* subs at sea only seen by sonar */
	if (tmcp->m_flags & M_SUB && sect.sct_type == SCT_WATER)
	    continue;
	pr("%s %s @ %s\n",
	   prnatid(sp->shp_own), prship(sp),
	   xyas(sp->shp_x, sp->shp_y, player->cnum));
	if (opt_HIDDEN)
	    setcont(player->cnum, sp->shp_own, FOUND_LOOK);
    }
}