Example #1
0
static void Paint_self_radar(double xf, double yf)
{
    int		x, y, x_1, y_1, xw, yw;

    if (selfVisible != 0 && loops % 16 < 13) {
	x = (int)(selfPos.x * xf + 0.5) - slidingradar_x;
	y = RadarHeight - (int)(selfPos.y * yf + 0.5) - 1 - slidingradar_y;
	if (x <= 0)
	    x += 256;
	if (y <= 0)
	    y += RadarHeight;

	x_1 = (int)(x + 8 * tcos(heading));
	y_1 = (int)(y - 8 * tsin(heading));
	XDrawLine(dpy, radarPixmap, radarGC,
		  x, y, x_1, y_1);
	if (BIT(Setup->mode, WRAP_PLAY)) {
	    xw = x_1 - (x_1 + 256) % 256;
	    yw = y_1 - (y_1 + RadarHeight) % RadarHeight;
	    if (xw != 0)
		XDrawLine(dpy, radarPixmap, radarGC,
			  x - xw, y, x_1 - xw, y_1);
	    if (yw != 0) {
		XDrawLine(dpy, radarPixmap, radarGC,
			  x, y - yw, x_1, y_1 - yw);
		if (xw != 0)
		    XDrawLine(dpy, radarPixmap, radarGC,
			      x - xw, y - yw, x_1 - xw, y_1 - yw);
	    }
	}
    }
}
Example #2
0
void Cannon_throw_items(cannon_t *c)
{
    int i, dir;
    itemobject_t *item;
    double velocity;

    for (i = 0; i < NUM_ITEMS; i++) {
	if (i == ITEM_FUEL)
	    continue;
	c->item[i] -= Cannon_get_initial_item(c, (Item_t)i);
	while (c->item[i] > 0) {
	    int amount = world->items[i].max_per_pack
			 - (int)(rfrac() * (1 + world->items[i].max_per_pack
					    - world->items[i].min_per_pack));
	    LIMIT(amount, 0, c->item[i]);
	    if (rfrac() < (options.dropItemOnKillProb * CANNON_DROP_ITEM_PROB)
		&& (item = ITEM_PTR(Object_allocate())) != NULL) {

		item->type = OBJ_ITEM;
		item->item_type = i;
		item->color = RED;
		item->obj_status = GRAVITY;
		dir = (int)(c->dir
			   - (CANNON_SPREAD * 0.5)
			   + (rfrac() * CANNON_SPREAD));
		dir = MOD2(dir, RES);
		item->id = NO_ID;
		item->team = TEAM_NOT_SET;
		Object_position_init_clpos(OBJ_PTR(item), c->pos);
		velocity = rfrac() * 6;
		item->vel.x = tcos(dir) * velocity;
		item->vel.y = tsin(dir) * velocity;
		item->acc.x = 0;
		item->acc.y = 0;
		item->mass = 10;
		item->life = 1500 + rfrac() * 512;
		item->item_count = amount;
		item->pl_range = ITEM_SIZE / 2;
		item->pl_radius = ITEM_SIZE / 2;
		world->items[i].num++;
		Cell_add_object(OBJ_PTR(item));
	    }
	    c->item[i] -= amount;
	}
    }
}
Example #3
0
/* does the actual firing. also determines in which way to use weapons that
   have more than one possible use. */
static void Cannon_fire(cannon_t *c, int weapon, player_t *pl, int dir)
{
    modifiers_t	mods;
    bool played = false;
    int i, smartness = Cannon_get_smartness(c);
    double speed = Cannon_get_shot_speed(c);
    vector_t zero_vel = { 0.0, 0.0 };

    Mods_clear(&mods);
    switch (weapon) {
    case CW_MINE:
	if (rfrac() < 0.25)
	    Mods_set(&mods, ModsCluster, 1);

	if (rfrac() >= 0.2)
	    Mods_set(&mods, ModsImplosion, 1);

	Mods_set(&mods, ModsPower,
		 (int)(rfrac() * (MODS_POWER_MAX + 1)));
	Mods_set(&mods, ModsVelocity, 
		 (int)(rfrac() * (MODS_VELOCITY_MAX + 1)));

	if (rfrac() < 0.5) {	/* place mine in front of cannon */
	    Place_general_mine(c->id, c->team, FROMCANNON,
			       c->pos, zero_vel, mods);
	    sound_play_sensors(c->pos, DROP_MINE_SOUND);
	    played = true;
	} else {		/* throw mine at player */
	    vector_t vel;

	    Mods_set(&mods, ModsMini,
		     (int)(rfrac() * MODS_MINI_MAX) + 1);
	    Mods_set(&mods, ModsSpread,
		     (int)(rfrac() * (MODS_SPREAD_MAX + 1)));

	    speed = speed * 0.5 + 0.1 * smartness;
	    vel.x = tcos(dir) * speed;
	    vel.y = tsin(dir) * speed;
	    Place_general_mine(c->id, c->team, GRAVITY|FROMCANNON,
			       c->pos, vel, mods);
	    sound_play_sensors(c->pos, DROP_MOVING_MINE_SOUND);
	    played = true;
	}
	c->item[ITEM_MINE]--;
	break;
    case CW_MISSILE:
	if (rfrac() < 0.333)
	    Mods_set(&mods, ModsCluster, 1);

	if (rfrac() >= 0.25)
	    Mods_set(&mods, ModsImplosion, 1);

	Mods_set(&mods, ModsPower,
		 (int)(rfrac() * (MODS_POWER_MAX + 1)));
	Mods_set(&mods, ModsVelocity, 
		 (int)(rfrac() * (MODS_VELOCITY_MAX + 1)));

	/* Because cannons don't have missile racks, all mini missiles
	   would be fired from the same point and appear to the players
	   as 1 missile (except heatseekers, which would appear to split
	   in midair because of navigation errors (see Move_smart_shot)).
	   Therefore, we don't minify cannon missiles.
	   mods.mini = (int)(rfrac() * MODS_MINI_MAX) + 1;
	   mods.spread = (int)(rfrac() * (MODS_SPREAD_MAX + 1));
	*/

	/* smarter cannons use more advanced missile types */
	switch ((int)(rfrac() * (1 + smartness))) {
	default:
	    if (options.allowSmartMissiles) {
		Fire_general_shot(c->id, c->team, c->pos,
				  OBJ_SMART_SHOT, dir, mods, pl->id);
		sound_play_sensors(c->pos, FIRE_SMART_SHOT_SOUND);
		played = true;
		break;
	    }
	    /* FALLTHROUGH */
	case 1:
	    if (options.allowHeatSeekers
		&& Player_is_thrusting(pl)) {
		Fire_general_shot(c->id, c->team, c->pos,
				  OBJ_HEAT_SHOT, dir, mods, pl->id);
		sound_play_sensors(c->pos, FIRE_HEAT_SHOT_SOUND);
		played = true;
		break;
	    }
	    /* FALLTHROUGH */
	case 0:
	    Fire_general_shot(c->id, c->team, c->pos,
			      OBJ_TORPEDO, dir, mods, NO_ID);
	    sound_play_sensors(c->pos, FIRE_TORPEDO_SOUND);
	    played = true;
	    break;
	}
	c->item[ITEM_MISSILE]--;
	break;
    case CW_LASER:
	/* stun and blinding lasers are very dangerous,
	   so we don't use them often */
	if ((rfrac() * (8 - smartness)) >= 1)
	    Mods_set(&mods, ModsLaser,
		     (int)(rfrac() * (MODS_LASER_MAX + 1)));

	Fire_general_laser(c->id, c->team, c->pos, dir, mods);
	sound_play_sensors(c->pos, FIRE_LASER_SOUND);
	played = true;
	break;
    case CW_ECM:
	Fire_general_ecm(c->id, c->team, c->pos);
	c->item[ITEM_ECM]--;
	sound_play_sensors(c->pos, ECM_SOUND);
	played = true;
	break;
    case CW_TRACTORBEAM:
	/* smarter cannons use tractors more often and also push/pull longer */
	c->tractor_is_pressor = (rfrac() * (smartness + 1) >= 1);
	c->tractor_target_id = pl->id;
	c->tractor_count = 11 + rfrac() * (3 * smartness + 1);
	break;
    case CW_TRANSPORTER:
	c->item[ITEM_TRANSPORTER]--;
	if (Wrap_length(pl->pos.cx - c->pos.cx, pl->pos.cy - c->pos.cy)
	    < TRANSPORTER_DISTANCE * CLICK) {
	    int item = -1;
	    double amount = 0.0;

	    Do_general_transporter(c->id, c->pos, pl, &item, &amount);
	    if (item != -1)
		Cannon_add_item(c, item, amount);
	} else {
	    sound_play_sensors(c->pos, TRANSPORTER_FAIL_SOUND);
	    played = true;
	}
	break;
    case CW_GASJET:
	/* use emergency thrusts to make extra big jets */
	if ((rfrac() * (c->item[ITEM_EMERGENCY_THRUST] + 1)) >= 1) {
	    Make_debris(c->pos,
			zero_vel,
			NO_ID,
			c->team,
			OBJ_SPARK,
			THRUST_MASS,
			GRAVITY|FROMCANNON,
			RED,
			8,
			(int)(300 + 400 * rfrac()),
			dir - 4 * (4 - smartness),
			dir + 4 * (4 - smartness),
			0.1, speed * 4,
			3.0, 20.0);
	    c->item[ITEM_EMERGENCY_THRUST]--;
	} else {
	    Make_debris(c->pos,
			zero_vel,
			NO_ID,
			c->team,
			OBJ_SPARK,
			THRUST_MASS,
			GRAVITY|FROMCANNON,
			RED,
			8,
			(int)(150 + 200 * rfrac()),
			dir - 3 * (4 - smartness),
			dir + 3 * (4 - smartness),
			0.1, speed * 2,
			3.0, 20.0);
	}
	c->item[ITEM_FUEL]--;
	sound_play_sensors(c->pos, THRUST_SOUND);
	played = true;
	break;
    case CW_SHOT:
    default:
	if (options.cannonFlak)
	    Mods_set(&mods, ModsCluster, 1);
	/* smarter cannons fire more accurately and
	   can therefore narrow their bullet streams */
	for (i = 0; i < (1 + 2 * c->item[ITEM_WIDEANGLE]); i++) {
	    int a_dir = dir
			+ (4 - smartness)
			* (-c->item[ITEM_WIDEANGLE] +  i);
	    a_dir = MOD2(a_dir, RES);
	    Fire_general_shot(c->id, c->team, c->pos,
			      OBJ_CANNON_SHOT, a_dir, mods, NO_ID);
	}
	/* I'm not sure cannons should use rearshots.
	   After all, they are restricted to 60 degrees when picking their
	   target. */
	for (i = 0; i < c->item[ITEM_REARSHOT]; i++) {
	    int a_dir = (int)(dir + (RES / 2)
			+ (4 - smartness)
			* (-((c->item[ITEM_REARSHOT] - 1) * 0.5) + i));
	    a_dir = MOD2(a_dir, RES);
	    Fire_general_shot(c->id, c->team, c->pos,
			      OBJ_CANNON_SHOT, a_dir, mods, NO_ID);
	}
    }

    /* finally, play sound effect */
    if (!played) {
	sound_play_sensors(c->pos, CANNON_FIRE_SOUND);
    }
}
Example #4
0
static void
ashiksamp(		/* sample anisotropic Ashikhmin-Shirley specular */
	ASHIKDAT  *np
)
{
	RAY  sr;
	FVECT  h;
	double  rv[2], dtmp;
	double  cosph, sinph, costh, sinth;
	int  maxiter, ntrials, nstarget, nstaken;
	int  i;

	if (np->specfl & SPA_BADU ||
			rayorigin(&sr, SPECULAR, np->rp, np->scolor) < 0)
		return;

	nstarget = 1;
	if (specjitter > 1.5) {			/* multiple samples? */
		nstarget = specjitter*np->rp->rweight + .5;
		if (sr.rweight <= minweight*nstarget)
			nstarget = sr.rweight/minweight;
		if (nstarget > 1) {
			dtmp = 1./nstarget;
			scalecolor(sr.rcoef, dtmp);
			sr.rweight *= dtmp;
		} else
			nstarget = 1;
	}
	dimlist[ndims++] = (int)(size_t)np->mp;
	maxiter = MAXITER*nstarget;
	for (nstaken = ntrials = 0; nstaken < nstarget &&
					ntrials < maxiter; ntrials++) {
		if (ntrials)
			dtmp = frandom();
		else
			dtmp = urand(ilhash(dimlist,ndims)+647+samplendx);
		multisamp(rv, 2, dtmp);
		dtmp = 2.*PI * rv[0];
		cosph = sqrt(np->v_power + 1.) * tcos(dtmp);
		sinph = sqrt(np->u_power + 1.) * tsin(dtmp);
		dtmp = 1./sqrt(cosph*cosph + sinph*sinph);
		cosph *= dtmp;
		sinph *= dtmp;
		costh = pow(rv[1], 1./(np->u_power*cosph*cosph+np->v_power*sinph*sinph+1.));
		if (costh <= FTINY)
			continue;
		sinth = sqrt(1. - costh*costh);
		for (i = 0; i < 3; i++)
			h[i] = cosph*sinth*np->u[i] + sinph*sinth*np->v[i] + costh*np->pnorm[i];

		if (nstaken)
			rayclear(&sr);
		dtmp = -2.*DOT(h, np->rp->rdir);
		VSUM(sr.rdir, np->rp->rdir, h, dtmp);				
						/* sample rejection test */
		if (DOT(sr.rdir, np->rp->ron) <= FTINY)
			continue;
		checknorm(sr.rdir);
		rayvalue(&sr);
		multcolor(sr.rcol, sr.rcoef);
		addcolor(np->rp->rcol, sr.rcol);
		++nstaken;
	}
	ndims--;
}
Example #5
0
static void
agaussamp(		/* sample anisotropic Gaussian specular */
	ANISODAT  *np
)
{
	RAY  sr;
	FVECT  h;
	double  rv[2];
	double  d, sinp, cosp;
	COLOR	scol;
	int  maxiter, ntrials, nstarget, nstaken;
	int  i;
					/* compute reflection */
	if ((np->specfl & (SP_REFL|SP_RBLT)) == SP_REFL &&
			rayorigin(&sr, SPECULAR, np->rp, np->scolor) == 0) {
		nstarget = 1;
		if (specjitter > 1.5) {	/* multiple samples? */
			nstarget = specjitter*np->rp->rweight + .5;
			if (sr.rweight <= minweight*nstarget)
				nstarget = sr.rweight/minweight;
			if (nstarget > 1) {
				d = 1./nstarget;
				scalecolor(sr.rcoef, d);
				sr.rweight *= d;
			} else
				nstarget = 1;
		}
		setcolor(scol, 0., 0., 0.);
		dimlist[ndims++] = (int)(size_t)np->mp;
		maxiter = MAXITER*nstarget;
		for (nstaken = ntrials = 0; nstaken < nstarget &&
						ntrials < maxiter; ntrials++) {
			if (ntrials)
				d = frandom();
			else
				d = urand(ilhash(dimlist,ndims)+samplendx);
			multisamp(rv, 2, d);
			d = 2.0*PI * rv[0];
			cosp = tcos(d) * np->u_alpha;
			sinp = tsin(d) * np->v_alpha;
			d = 1./sqrt(cosp*cosp + sinp*sinp);
			cosp *= d;
			sinp *= d;
			if ((0. <= specjitter) & (specjitter < 1.))
				rv[1] = 1.0 - specjitter*rv[1];
			if (rv[1] <= FTINY)
				d = 1.0;
			else
				d = sqrt(-log(rv[1]) /
					(cosp*cosp/(np->u_alpha*np->u_alpha) +
					 sinp*sinp/(np->v_alpha*np->v_alpha)));
			for (i = 0; i < 3; i++)
				h[i] = np->pnorm[i] +
					d*(cosp*np->u[i] + sinp*np->v[i]);
			d = -2.0 * DOT(h, np->rp->rdir) / (1.0 + d*d);
			VSUM(sr.rdir, np->rp->rdir, h, d);
						/* sample rejection test */
			if ((d = DOT(sr.rdir, np->rp->ron)) <= FTINY)
				continue;
			checknorm(sr.rdir);
			if (nstarget > 1) {	/* W-G-M-D adjustment */
				if (nstaken) rayclear(&sr);
				rayvalue(&sr);
				d = 2./(1. + np->rp->rod/d);
				scalecolor(sr.rcol, d);
				addcolor(scol, sr.rcol);
			} else {
				rayvalue(&sr);
				multcolor(sr.rcol, sr.rcoef);
				addcolor(np->rp->rcol, sr.rcol);
			}
			++nstaken;
		}
		if (nstarget > 1) {		/* final W-G-M-D weighting */
			multcolor(scol, sr.rcoef);
			d = (double)nstarget/ntrials;
			scalecolor(scol, d);
			addcolor(np->rp->rcol, scol);
		}
		ndims--;
	}
					/* compute transmission */
	copycolor(sr.rcoef, np->mcolor);		/* modify by material color */
	scalecolor(sr.rcoef, np->tspec);
	if ((np->specfl & (SP_TRAN|SP_TBLT)) == SP_TRAN &&
			rayorigin(&sr, SPECULAR, np->rp, sr.rcoef) == 0) {
		nstarget = 1;
		if (specjitter > 1.5) {	/* multiple samples? */
			nstarget = specjitter*np->rp->rweight + .5;
			if (sr.rweight <= minweight*nstarget)
				nstarget = sr.rweight/minweight;
			if (nstarget > 1) {
				d = 1./nstarget;
				scalecolor(sr.rcoef, d);
				sr.rweight *= d;
			} else
				nstarget = 1;
		}
		dimlist[ndims++] = (int)(size_t)np->mp;
		maxiter = MAXITER*nstarget;
		for (nstaken = ntrials = 0; nstaken < nstarget &&
						ntrials < maxiter; ntrials++) {
			if (ntrials)
				d = frandom();
			else
				d = urand(ilhash(dimlist,ndims)+1823+samplendx);
			multisamp(rv, 2, d);
			d = 2.0*PI * rv[0];
			cosp = tcos(d) * np->u_alpha;
			sinp = tsin(d) * np->v_alpha;
			d = 1./sqrt(cosp*cosp + sinp*sinp);
			cosp *= d;
			sinp *= d;
			if ((0. <= specjitter) & (specjitter < 1.))
				rv[1] = 1.0 - specjitter*rv[1];
			if (rv[1] <= FTINY)
				d = 1.0;
			else
				d = sqrt(-log(rv[1]) /
					(cosp*cosp/(np->u_alpha*np->u_alpha) +
					 sinp*sinp/(np->v_alpha*np->v_alpha)));
			for (i = 0; i < 3; i++)
				sr.rdir[i] = np->prdir[i] +
						d*(cosp*np->u[i] + sinp*np->v[i]);
			if (DOT(sr.rdir, np->rp->ron) >= -FTINY)
				continue;
			normalize(sr.rdir);	/* OK, normalize */
			if (nstaken)		/* multi-sampling */
				rayclear(&sr);
			rayvalue(&sr);
			multcolor(sr.rcol, sr.rcoef);
			addcolor(np->rp->rcol, sr.rcol);
			++nstaken;
		}
		ndims--;
	}
}