Example #1
0
/*
 * Does falling drawbridge or portcullis miss etmp?
 */
static boolean
e_missed(struct entity *etmp, boolean chunks)
{
    int misses;

    if (automiss(etmp))
        return TRUE;

    if (flying(etmp->emon) &&
        (is_u(etmp) ? !u_helpless(hm_all)
         : (etmp->emon->mcanmove && !etmp->emon->msleeping)))
        /* flying requires mobility */
        misses = 5;     /* out of 8 */
    else if (levitates(etmp->emon) || (is_u(etmp) && Levitation))
        /* doesn't require mobility */
        misses = 3;
    else if (chunks && is_pool(level, etmp->ex, etmp->ey))
        misses = 2;     /* sitting ducks */
    else
        misses = 0;

    if (is_db_wall(etmp->ex, etmp->ey))
        misses -= 3;    /* less airspace */

    enum rng rng = is_u(etmp) ? rng_survive_dbridge : rng_main;

    return (boolean) ((misses > rn2_on_rng(8, rng)) ? TRUE : FALSE);
}
Example #2
0
/*
 * Simple-minded "can it be here?" routine
 */
static boolean
e_survives_at(struct entity *etmp, int x, int y)
{
    if (noncorporeal(etmp->edata))
        return TRUE;
    if (is_pool(level, x, y))
        return (boolean) (waterwalks(etmp->emon) || unbreathing(etmp->emon) ||
                          swims(etmp->emon) || flying(etmp->emon) ||
                          levitates(etmp->emon));
    /* must force call to lava_effects in e_died if is_u */
    if (is_lava(level, x, y))
        return (boolean) (likes_lava(etmp->edata) || flying(etmp->emon) ||
                          levitates(etmp->emon));
    if (is_db_wall(x, y))
        return !!phasing(etmp->emon);
    return TRUE;
}
Example #3
0
void Steven::update( float delta )
{
	//keep speed 
	b2Body* body = getB2Body();
	b2Vec2 v = body->GetLinearVelocity();
	b2Vec2 impulse = skiSpeed(v);
	impulse *= body->GetMass();
	//b2Vec2 impulse = b2Vec2( (10 - v.x)*body->GetMass(), 0);
	body->ApplyLinearImpulse(impulse, body->GetWorldCenter());

	////compute distance to hill
	b2Vec2 rayStart = this->m_pB2Body->GetWorldCenter();
	b2Vec2 rayEnd = b2Vec2(rayStart.x, rayStart.y - 100);
	class RayCastCallback : public b2RayCastCallback
	{
		virtual float32 ReportFixture(b2Fixture* fixture, const b2Vec2& point, const b2Vec2& normal, float32 fraction)
		{
			CCString* name = b2Helper::getBodyName(fixture->GetBody());
			if (name->compare("hill") == 0)
			{
				Steven* steven = Steven::sharedSteven();
				steven->mSkiHigh = (steven->m_pB2Body->GetWorldCenter().y - point.y) * G.PTM_RATIO - mRadius;
				return 0;
			}
			return 1;
		}
	} callback;
	G.world->RayCast(&callback,rayStart, rayEnd);

	//auto rotation in sky
	if (flying())
	{
		rotationBy(-30 * delta);
	}
	if (flying() && mStatus == StevenStatus::SS_Ski)
	{
		fly();
	}
}
Example #4
0
void move_sound(ter_num_t ter,short step){
	static bool on_swamp = false;
	short pic;
	eTerSpec spec;
	
	pic = univ.scenario.ter_types[ter].picture;
	spec = univ.scenario.ter_types[ter].special;
	eStepSnd snd = univ.scenario.ter_types[ter].step_sound;
	
	// if on swamp don't play squish sound : BoE legacy behavior, can be removed safely
	if(snd == eStepSnd::SPLASH && !flying() && univ.party.in_boat < 0){
		if(on_swamp && get_ran(1,1,100) >= 10) return;
		on_swamp = true;
	} else on_swamp = false;
	
	if(!monsters_going && (overall_mode < MODE_COMBAT) && (univ.party.in_boat >= 0)) {
		if(spec == eTerSpec::TOWN_ENTRANCE)
			return;
		play_sound(48); //play boat sound
	} else if(!monsters_going && (overall_mode < MODE_COMBAT) && (univ.party.in_horse >= 0)) {
		play_sound(85); //so play horse sound
	} else switch(univ.scenario.ter_types[ter].step_sound){
		case eStepSnd::SQUISH:
			play_sound(55);
			break;
		case eStepSnd::CRUNCH:
			play_sound(47);
			break;
		case eStepSnd::NONE:
			break;
		case eStepSnd::SPLASH:
			play_sound(17);
			break;
		case eStepSnd::STEP:
			if(step % 2 == 0) //footsteps alternate sound
				play_sound(49);
			else play_sound(50);
	}
}
Example #5
0
/* Generate earthquake :-) of desired force. That is: create random chasms
   (pits). Currently assumes that the player created it (you'll need to change
   at least messages, angering, and kill credit if you generalize it). */
static void
do_earthquake(int force)
{
    int x, y;
    struct monst *mtmp;
    struct obj *otmp;
    struct trap *chasm, *oldtrap;
    int start_x, start_y, end_x, end_y;

    start_x = youmonst.mx - (force * 2);
    start_y = youmonst.my - (force * 2);
    end_x = youmonst.mx + (force * 2);
    end_y = youmonst.my + (force * 2);
    if (start_x < 0)
        start_x = 0;
    if (start_y < 0)
        start_y = 0;
    if (end_x >= COLNO)
        end_x = COLNO - 1;
    if (end_y >= ROWNO)
        end_y = ROWNO - 1;
    for (x = start_x; x <= end_x; x++)
        for (y = start_y; y <= end_y; y++) {
            if ((mtmp = m_at(level, x, y)) != 0) {
                wakeup(mtmp, FALSE);  /* peaceful monster will become hostile */
                if (mtmp->mundetected && is_hider(mtmp->data)) {
                    mtmp->mundetected = 0;
                    if (cansee(x, y))
                        pline(msgc_youdiscover, "%s is shaken loose from %s!",
                              Amonnam(mtmp), mtmp->data == &mons[PM_TRAPPER] ?
                              "its hiding place" : the(ceiling(youmonst.mx, youmonst.my)));
                    else
                        You_hear(msgc_levelsound, "a thumping sound.");
                    if (x == youmonst.mx && y == youmonst.my &&
                        mtmp->data != &mons[PM_TRAPPER])
                        pline(msgc_moncombatgood,
                              "You easily dodge the falling %s.",
                              mon_nam(mtmp));
                    newsym(x, y);
                }
            }
            if (!rn2(14 - force))
                switch (level->locations[x][y].typ) {
                case FOUNTAIN: /* Make the fountain disappear */
                    if (cansee(x, y))
                        pline(msgc_consequence,
                              "The fountain falls into a chasm.");
                    goto do_pit;
                case SINK:
                    if (cansee(x, y))
                        pline(msgc_consequence,
                              "The kitchen sink falls into a chasm.");
                    goto do_pit;
                case ALTAR:
                    if (level->locations[x][y].altarmask & AM_SANCTUM)
                        break;

                    if (cansee(x, y))
                        pline(msgc_consequence,
                              "The altar falls into a chasm.");
                    goto do_pit;
                case GRAVE:
                    if (cansee(x, y))
                        pline(msgc_consequence,
                              "The headstone topples into a chasm.");
                    goto do_pit;
                case THRONE:
                    if (cansee(x, y))
                        pline(msgc_consequence,
                              "The throne falls into a chasm.");
                    /* Falls into next case */
                case ROOM:
                case CORR:     /* Try to make a pit */
                    /* Pits, spiked pits, holes, trapdoors, vibrating squares,
                       magic portals are immune.  A bear trap will leave the
                       trap in the pit.  It would be kind of cool to make
                       landmines detonate, but that's more trouble than it's
                       worth. */
                    if ((oldtrap = t_at(level, x, y))) {
                        if (oldtrap->ttyp == PIT || oldtrap->ttyp == SPIKED_PIT
                            || oldtrap->ttyp == HOLE ||
                            oldtrap->ttyp == TRAPDOOR ||
                            oldtrap->ttyp == VIBRATING_SQUARE ||
                            oldtrap->ttyp == MAGIC_PORTAL)
                            break;

                        if (oldtrap->ttyp == BEAR_TRAP) {
                            if (mtmp)
                                mtmp->mtrapped = 0;
                            cnv_trap_obj(level, BEARTRAP, 1, oldtrap);
                        }
                    }

                do_pit:
                    chasm = maketrap(level, x, y, PIT, rng_main);
                    if (!chasm)
                        break;  /* no pit if portal at that location */
                    chasm->tseen = 1;

                    level->locations[x][y].doormask = 0;

                    mtmp = m_at(level, x, y);

                    if ((otmp = sobj_at(BOULDER, level, x, y)) != 0) {
                        if (cansee(x, y))
                            pline(msgc_consequence,
                                  "KADOOM! The boulder falls into a chasm%s!",
                                  ((x == youmonst.mx) &&
                                   (y == youmonst.my)) ? " below you" : "");
                        if (mtmp)
                            mtmp->mtrapped = 0;
                        obj_extract_self(otmp);
                        flooreffects(otmp, x, y, "");
                        break;
                    }

                    /* We have to check whether monsters or player falls in a
                       chasm... */

                    if (mtmp) {
                        if (!flying(mtmp) && !levitates(mtmp) &&
                            !is_clinger(mtmp->data)) {
                            mtmp->mtrapped = 1;
                            if (cansee(x, y))
                                pline(combat_msgc(&youmonst, mtmp, cr_hit),
                                      "%s falls into a chasm!", Monnam(mtmp));
                            else if (humanoid(mtmp->data))
                                You_hear(msgc_levelsound, "a scream!");
                            mselftouch(mtmp, "Falling, ", &youmonst);
                            if (!DEADMONSTER(mtmp))
                                if ((mtmp->mhp -= rnd(6)) <= 0) {
                                    if (!cansee(x, y))
                                        pline(msgc_kill, "It is destroyed!");
                                    else {
                                        pline(msgc_petfatal, "You destroy %s!",
                                              mtmp->mtame ?
                                              x_monnam(mtmp, ARTICLE_THE,
                                                       "poor", mx_name(mtmp) ?
                                                       SUPPRESS_SADDLE : 0,
                                                       FALSE) : mon_nam(mtmp));
                                    }
                                    xkilled(mtmp, 0);
                                }
                        }
                    } else if (!u.utrap && x == youmonst.mx && y == youmonst.my) {
                        if (Levitation || Flying || is_clinger(youmonst.data)) {
                            pline(msgc_noconsequence,
                                  "A chasm opens up under you!");
                            pline(msgc_noconsequence, "You don't fall in!");
                        } else {
                            pline(msgc_badidea, "You fall into a chasm!");
                            u.utrap = rn1(6, 2);
                            u.utraptype = TT_PIT;
                            turnstate.vision_full_recalc = TRUE;
                            losehp(rnd(6), "fell into a chasm");
                            selftouch("Falling, you",
                                      "falling into a chasm while wielding");
                        }
                    } else
                        newsym(x, y);
                    break;
                case DOOR:     /* Make the door collapse */
                    if (level->locations[x][y].doormask == D_NODOOR)
                        goto do_pit;
                    if (cansee(x, y))
                        pline(msgc_consequence, "The door collapses.");
                    if (*in_rooms(level, x, y, SHOPBASE))
                        add_damage(x, y, 0L);
                    level->locations[x][y].doormask = D_NODOOR;
                    unblock_point(x, y);
                    newsym(x, y);
                    break;
                }
        }
}
Example #6
0
static void
do_entity(struct entity *etmp)
{
    int newx, newy, at_portcullis, oldx, oldy;
    boolean must_jump = FALSE, relocates = FALSE, e_inview;
    struct rm *crm;

    if (!etmp->edata)
        return;

    /* TODO: Long worms? */
    e_inview = e_canseemon(etmp);
    oldx = etmp->ex;
    oldy = etmp->ey;
    at_portcullis = is_db_wall(oldx, oldy);
    crm = &level->locations[oldx][oldy];

    enum msg_channel miss_msgc, hit_msgc;
    if (is_u(etmp)) {
        miss_msgc = msgc_fatalavoid;
        hit_msgc = msgc_fatal_predone;
    } else if (etmp->emon->mtame && canspotmon(etmp->emon))
        miss_msgc = hit_msgc = msgc_petfatal;
    else
        miss_msgc = hit_msgc = msgc_monneutral;

    if (automiss(etmp) && e_survives_at(etmp, oldx, oldy)) {
        if (e_inview && (at_portcullis || IS_DRAWBRIDGE(crm->typ)))
            pline(miss_msgc, "The %s passes through %s!",
                  at_portcullis ? "portcullis" : "drawbridge", e_nam(etmp));
        if (is_u(etmp))
            spoteffects(FALSE);
        return;
    }
    if (e_missed(etmp, FALSE)) {
        if (at_portcullis)
            pline(miss_msgc, "The portcullis misses %s!", e_nam(etmp));
        if (e_survives_at(etmp, oldx, oldy))
            return;
        else {
            if (at_portcullis)
                must_jump = TRUE;
            else
                relocates = TRUE;       /* just ride drawbridge in */
        }
    } else {
        if (crm->typ == DRAWBRIDGE_DOWN) {
            pline(hit_msgc, "%s crushed underneath the drawbridge.",
                  E_phrase(etmp, "are")); /* no jump */
            e_died(etmp, e_inview ? 3 : 2, CRUSHING,
                   killer_msg(CRUSHING, "a falling drawbridge"));  /* no corpse */
            return;     /* Note: Beyond this point, we know we're */
        }       /* not at an opened drawbridge, since all */
        must_jump = TRUE;       /* *missable* creatures survive on the */
    }   /* square, and all the unmissed ones die.  */
    if (must_jump) {
        if (at_portcullis) {
            if (e_jumps(etmp)) {
                relocates = TRUE;
            } else {
                if (e_inview)
                    pline(hit_msgc, "%s crushed by the falling portcullis!",
                          E_phrase(etmp, "are"));
                else
                    You_hear(msgc_levelsound, "a crushing sound.");
                e_died(etmp, e_inview ? 3 : 2, CRUSHING,
                       killer_msg(CRUSHING, "a falling portcullis"));
                /* no corpse */
                return;
            }
        } else {        /* tries to jump off bridge to original square */
            relocates = !e_jumps(etmp);
        }
    }

    /* Here's where we try to do relocation. Assumes that etmp is not arriving
       at the portcullis square while the drawbridge is falling, since this
       square would be inaccessible (i.e. etmp started on drawbridge square) or
       unnecessary (i.e. etmp started here) in such a situation. */
    newx = oldx;
    newy = oldy;
    find_drawbridge(&newx, &newy);
    if ((newx == oldx) && (newy == oldy))
        get_wall_for_db(&newx, &newy);
    if (relocates && (e_at(newx, newy))) {

        /* Standoff problem: one or both entities must die, and/or both switch
           places. Avoid infinite recursion by checking first whether the other
           entity is staying put. Clean up if we happen to move/die in
           recursion. */
        struct entity *other;

        other = e_at(newx, newy);
        if (e_survives_at(other, newx, newy) && automiss(other)) {
            relocates = FALSE;  /* "other" won't budge */
        } else {

            while ((e_at(newx, newy) != 0) && (e_at(newx, newy) != etmp))
                do_entity(other);
            if (e_at(oldx, oldy) != etmp) {
                return;
            }
        }
    }
    if (relocates && !e_at(newx, newy)) {       /* if e_at() entity = worm tail 
                                                 */
        if (!is_u(etmp)) {
            remove_monster(level, etmp->ex, etmp->ey);
            place_monster(etmp->emon, newx, newy, TRUE);
            update_monster_region(etmp->emon);
        } else {
            youmonst.mx = newx;
            youmonst.my = newy;
        }
        etmp->ex = newx;
        etmp->ey = newy;
        e_inview = e_canseemon(etmp);
    }
    if (is_db_wall(etmp->ex, etmp->ey)) {
        if (e_inview) {
            if (is_u(etmp)) {
                pline(msgc_nonmonbad,
                      "You tumble towards the closed portcullis!");
                if (automiss(etmp))
                    pline(miss_msgc, "You pass through it!");
                else
                    pline(e_survives_at(etmp, etmp->ex, etmp->ey) ?
                          miss_msgc : hit_msgc, "The drawbridge closes in...");
            } else
                pline(hit_msgc, "%s behind the drawbridge.",
                      E_phrase(etmp, "disappear"));
        }
        if (!e_survives_at(etmp, etmp->ex, etmp->ey)) {
            e_died(etmp, 0, CRUSHING,
                   killer_msg(CRUSHING, "a closing drawbridge"));
            return;
        }
    } else {
        if (is_pool(level, etmp->ex, etmp->ey) && !e_inview)
            You_hear(msgc_levelsound, "a splash.");
        if (e_survives_at(etmp, etmp->ex, etmp->ey)) {
            if (e_inview && !flying(etmp->emon) && !levitates(etmp->emon))
                pline(miss_msgc, "%s from the bridge.", E_phrase(etmp, "fall"));
            return;
        }
        if (is_pool(level, etmp->ex, etmp->ey) ||
            is_lava(level, etmp->ex, etmp->ey))
            if (e_inview && !is_u(etmp)) {
                /* drown() will supply msgs if nec. */
                boolean lava = is_lava(level, etmp->ex, etmp->ey);

                if (Hallucination)
                    pline(hit_msgc, "%s the %s and disappears.",
                          E_phrase(etmp, "drink"),
                          lava ? "lava" : waterbody_name(etmp->ex, etmp->ey));
                else
                    pline(hit_msgc, "%s into the %s.", E_phrase(etmp, "fall"),
                          lava ? "lava" : waterbody_name(etmp->ex, etmp->ey));
            }
        e_died(etmp, e_inview ? 3 : 2,  /* CRUSHING is arbitrary */
               (is_pool(level, etmp->ex, etmp->ey)) ? DROWNING :
               (is_lava(level, etmp->ex, etmp->ey)) ? BURNING :
               CRUSHING, "fell from a drawbridge");    /* no corpse */
        return;
    }
}