Esempio n. 1
0
int
walk_map(McMap * mcMap)
{
	int i, j, ch, r, walk;
	unsigned short exits;

	i = mcMap->prev_x;
	j = mcMap->prev_y;

	for (walk = 0; map_valid(mcMap);) {
		r = 4;
		myInfo->pos_x = i;
		myInfo->pos_y = j;
		money_show_stat("邪恶荒原");
		move(r++, 0);
		prints
		    ("这里是大富翁城外不远的邪恶荒原, 周围荒草凄凄, 静寂得令人毛骨悚然.");
		if (myInfo->health < 1) {
			showAt(++r, 0, "你没有足够的体力行走了...", YEA);
			continue;
		}
		move(t_lines - 2, 0);
		prints("[h 帮助]这里明显的出口是:");
		exits = mcMap->map[i][j].exit;
		if (exits & NODE_LEFT)
			prints("%s、", "←");
		if (exits & NODE_RIGHT)
			prints("%s、", "→");
		if (exits & NODE_UP)
			prints("%s、", "↑");
		if (exits & NODE_DOWN)
			prints("%s。", "↓");

		print_item(&mcMap->map[i][j], &r);

		ch = igetkey();
		if (ch == KEY_LEFT && (exits & NODE_LEFT)) {
			walk++;
			j--;
		} else if (ch == KEY_RIGHT && (exits & NODE_RIGHT)) {
			walk++;
			j++;
		} else if (ch == KEY_UP && (exits & NODE_UP)) {
			walk++;
			i--;
		} else if (ch == KEY_DOWN && (exits & NODE_DOWN)) {
			walk++;
			i++;
		} else if (ch == 'q' || ch == 'Q') {
			return 0;
		} else if (ch == 'h' || ch == 'H') {
			print_map_help();
		} else if (ch == KEY_TAB) {
			nomoney_show_stat("邪恶荒原");
			move(4, 0);
			print_map(mcMap, 1);
			pressanykey();
		} else if (ch == 'k' || ch == 'K') {
			kill_npc();
		} else if (ch == 'o') {
			open_box();
		} else {
			showAt(t_lines - 1, 0, ">你要做什么?", YEA);
		}
		//更新身体状态
		update_health();
		if (walk % 4 == 1) {
			walk++;
			myInfo->health--;
			limit_cpu();
		}
	}
	return 0;
}
void LVL_Player::solveCollision(PGE_Phys_Object *collided)
{
    if(!collided) return;

    switch(collided->type)
    {
        case PGE_Phys_Object::LVLBlock:
        {
            LVL_Block *blk= static_cast<LVL_Block*>(collided);
            if(blk)
            {
                if(blk->destroyed)
                {
                    #ifdef COLLIDE_DEBUG
                    qDebug() << "Destroyed!";
                    #endif
                    break;
                }
            }
            else
            {
                #ifdef COLLIDE_DEBUG
                qDebug() << "Wrong cast";
                #endif
                break;
            }

            if( ((!forceCollideCenter)&&(!collided->posRect.collideRect(posRect)))||
                ((forceCollideCenter)&&(!collided->posRect.collideRectDeep(posRect, 1.0, -3.0))) )
            {
                #ifdef COLLIDE_DEBUG
                qDebug() << "No, is not collidng";
                #endif
                break;
            }
            #ifdef COLLIDE_DEBUG
            qDebug() << "Collided item! "<<collided->type<<" " <<collided->posRect.center().x()<<collided->posRect.center().y();
            #endif

            if((bumpUp||bumpDown)&&(!forceCollideCenter))
            {
                #ifdef COLLIDE_DEBUG
                qDebug() << "Bump? U'r dumb!";
                #endif
                break;
            }

//            PGE_PointF c1 = posRect.center();
//            PGE_RectF &r1 = posRect;
//            PGE_PointF cc = collided->posRect.center();
//            PGE_RectF  rc = collided->posRect;

            switch(collided->collide_player)
            {
                case COLLISION_TOP:
                {
                    if(isCollideFloorToponly(collided))
                    {
                        if(blk->isHidden) break;
                        collided_bottom[(intptr_t)collided]=collided;//bottom of player
                        if(blk->setup->lava) kill(DEAD_burn);
                        else if(blk->setup->danger==2||blk->setup->danger==-3||blk->setup->danger==4) harm(1);
                        #ifdef COLLIDE_DEBUG
                        qDebug() << "Top of block";
                        #endif
                    }
                }
                break;
                case COLLISION_ANY:
                {
                    #ifdef COLLIDE_DEBUG
                    bool found=false;
                    #endif
                    //*****************************Feet of player****************************/
                    if(
                        (( (blk->shape==LVL_Block::shape_rect)||
                           (blk->shape==LVL_Block::shape_tr_bottom_left)||
                           (blk->shape==LVL_Block::shape_tr_bottom_right) ) && isCollideFloor(collided))||
                        ((blk->shape==LVL_Block::shape_tr_top_right)&&isCollideSlopeFloor(collided, SLOPE_RIGHT)) ||
                        ((blk->shape==LVL_Block::shape_tr_top_left)&&isCollideSlopeFloor(collided, SLOPE_LEFT))

                      ){
                        if(blk->isHidden) break;
                        collided_bottom[(intptr_t)collided]=collided;//bottom of player
                        if(blk->setup->lava) kill(DEAD_burn);
                        else if(blk->setup->danger==2||blk->setup->danger==-3||blk->setup->danger==4) harm(1);
                    }
                    //*****************************Head of player****************************/
                    else if(
                            (( (blk->shape==LVL_Block::shape_rect)||
                                (blk->shape==LVL_Block::shape_tr_top_left)||
                                (blk->shape==LVL_Block::shape_tr_top_right)) &&
                                isCollideCelling(collided, _heightDelta, forceCollideCenter))||
                            ((blk->shape==LVL_Block::shape_tr_bottom_right)&&isCollideSlopeCelling(collided, SLOPE_RIGHT)) ||
                            ((blk->shape==LVL_Block::shape_tr_bottom_left)&&isCollideSlopeCelling(collided, SLOPE_LEFT))
                           )
                    {
                        collided_top[(intptr_t)collided]=collided;//top of player
                        if(blk->setup->lava) kill(DEAD_burn);
                        else if(blk->setup->danger==-2||blk->setup->danger==-3||blk->setup->danger==4) harm(1);
                    }
                    //*****************************Left****************************/
                    else if( (isCollideLeft(collided)&&(blk->shape==LVL_Block::shape_rect))||
                             (isCollideLeft(collided)&&(blk->shape==LVL_Block::shape_tr_top_left)
                              &&(posRect.bottom()>=(collided->posRect.top()+SL_HeightTopRight(collided)+1.0)))||
                             (isCollideLeft(collided)&&(blk->shape==LVL_Block::shape_tr_bottom_left)
                              &&(posRect.top()<=(collided->posRect.bottom()-SL_HeightTopRight(collided)-1.0))) )
                    {
                        if(blk->isHidden) break;
                        collided_left[(intptr_t)collided]=collided;//right of player
                        if(blk->setup->lava) kill(DEAD_burn);
                        else if(blk->setup->danger==-1||blk->setup->danger==3||blk->setup->danger==4) harm(1);
                    }
                    //*****************************Right****************************/
                    else if( (isCollideRight(collided)&&(blk->shape==LVL_Block::shape_rect))||
                             (isCollideRight(collided)&&(blk->shape==LVL_Block::shape_tr_top_right)
                             &&(posRect.bottom()>=(collided->posRect.top()+SL_HeightTopLeft(collided)+1.0)))||
                             (isCollideRight(collided)&&(blk->shape==LVL_Block::shape_tr_bottom_right)
                             &&(posRect.top()<=(collided->posRect.bottom()-SL_HeightTopLeft(collided)-1.0)))
                           )
                    {
                        if(blk->isHidden) break;
                        collided_right[(intptr_t)collided]=collided;//left of player
                        if(blk->setup->lava) kill(DEAD_burn);
                        else if(blk->setup->danger==1||blk->setup->danger==3||blk->setup->danger==4) harm(1);
                    }


                    float c=forceCollideCenter? 0.0f : 1.0f;
                    //*****************************Center****************************/
                    if( ((!forceCollideCenter && blk->shape==LVL_Block::shape_rect)||(forceCollideCenter))
                            && blk->posRect.collideRectDeep(posRect,
                                                     fabs(_velocityX_prev+_velocityX_add)*c+c*2.0,
                                                     fabs(_velocityY_prev+_velocityY_add)*c+c*2.0)
                            )
                    {
                        if(blk->isHidden && !forceCollideCenter) break;
                        collided_center[(intptr_t)collided]=collided;
                    }
                    break;
                }
            default: break;
            }
            break;
        }
        case PGE_Phys_Object::LVLWarp:
        {
            contactedWarp = static_cast<LVL_Warp*>(collided);
            if(contactedWarp)
                contactedWithWarp=true;
            break;
        }
        case PGE_Phys_Object::LVLBGO:
        {
            LVL_Bgo *bgo= static_cast<LVL_Bgo*>(collided);
            if(bgo)
            {
                if(bgo->setup->climbing)
                {
                    bool set=climbable_map.isEmpty();
                    climbable_map[(intptr_t)collided]=collided;
                    if(set)
                        climbableHeight=collided->posRect.top();
                    else if(collided->top()<climbableHeight)
                        climbableHeight=collided->top();
                }
            }
            break;
        }
        case PGE_Phys_Object::LVLNPC:
        {
            LVL_Npc *npc= static_cast<LVL_Npc*>(collided);
            if(npc)
            {
                if(npc->isKilled())        break;

                if(!npc->data.msg.isEmpty())
                {
                    collided_talkable_npc=npc;
                }
                if(npc->data.friendly) break;
                if(npc->isGenerator) break;
                if(npc->setup->climbable)
                {
                    bool set=climbable_map.isEmpty();
                    climbable_map[(intptr_t)collided]=collided;
                    if(set)
                        climbableHeight=collided->posRect.top();
                    else if(collided->top()<climbableHeight)
                        climbableHeight=collided->top();
                }

                if((!npc->data.friendly)&&(npc->setup->takable))
                {
                    collided_talkable_npc=NULL;
                    npc->doHarm(LVL_Npc::DAMAGE_TAKEN);
                    kill_npc(npc, LVL_Player::NPC_Taked_Coin);
                }


                if( ((!forceCollideCenter)&&(!collided->posRect.collideRect(posRect)))||
                    ((forceCollideCenter)&&(!collided->posRect.collideRectDeep(posRect, 1.0, -3.0))) )
                {
                    break;
                }

                if((bumpUp||bumpDown)&&(!forceCollideCenter))
                    break;

                if(!npc->isActivated) break;

                //PGE_PointF c1 = posRect.center();
                //PGE_RectF &r1 = posRect;
                //PGE_PointF cc = collided->posRect.center();
                //PGE_RectF  rc = collided->posRect;

                switch(collided->collide_player)
                {
                    case COLLISION_TOP:
                    {
                        if(isCollideFloorToponly(collided))
                        {
                            collided_bottom[(intptr_t)collided]=collided;//bottom of player
                            #ifdef COLLIDE_DEBUG
                            qDebug() << "Top of block";
                            #endif
                        } else {
                            if( npc->posRect.collideRect(posRect))
                            {
                               if(npc->setup->hurt_player & !npc->setup->kill_on_jump) harm(1);
                            }
                        }

                    }
                    break;
                    case COLLISION_ANY:
                    {
                        #ifdef COLLIDE_DEBUG
                        bool found=false;
                        #endif
                        //double xSpeed = Maths::max(fabs(speedX()+_velocityX_add), fabs(_velocityX_prev+_velocityX_add)) * Maths::sgn(speedX()+_velocityX_add);
                        //double ySpeed = Maths::max(fabs(speedY()+_velocityY_add), fabs(_velocityY_prev+_velocityY_add)) * Maths::sgn(speedY()+_velocityY_add);
                        //*****************************Feet of player****************************/
                        if(isCollideFloor(collided))
                        {
                                collided_bottom[(intptr_t)collided]=collided;//bottom of player
                                #ifdef COLLIDE_DEBUG
                                qDebug() << "Top of block";
                                found=true;
                                #endif
                        }
                        //*****************************Head of player****************************/
                        else if( isCollideCelling(collided, _heightDelta, forceCollideCenter) )
                        {
                            collided_top[(intptr_t)collided]=collided;//top of player
                            if(npc->setup->hurt_player) harm(1);
                            #ifdef COLLIDE_DEBUG
                            qDebug() << "Bottom of block";
                            found=true;
                            #endif
                        }
                        //*****************************Left****************************/
                        else if( isCollideLeft(collided) )
                        {
                            collided_left[(intptr_t)collided]=collided;//right of player
                            if(npc->setup->hurt_player) harm(1);
                            #ifdef COLLIDE_DEBUG
                            qDebug() << "Right of block";
                            #endif
                        }
                        //*****************************Right****************************/
                        else if( isCollideRight(collided) )
                        {
                            collided_right[(intptr_t)collided]=collided;//left of player
                            if(npc->setup->hurt_player) harm(1);
                            #ifdef COLLIDE_DEBUG
                            qDebug() << "Left of block";
                            found=true;
                            #endif
                        }


                        float c=forceCollideCenter? 0.0f : 1.0f;
                        //*****************************Center****************************/
                        #ifdef COLLIDE_DEBUG
                        qDebug() << "block" <<posRect.top()<<":"<<blk->posRect.bottom()
                                 << "block" <<posRect.bottom()<<":"<<blk->posRect.top()<<" collide?"<<
                                    blk->posRect.collideRectDeep(posRect,
                                                                                         fabs(_velocityX_prev)*c+c*2.0,
                                                                                         fabs(_velocityY_prev)*c+c*2.0) <<
                                    "depths: "<< fabs(_velocityX_prev)*c+c*2.0 <<
                                fabs(_velocityY_prev)*c+c;
                        #endif
                        if( npc->posRect.collideRectDeep(posRect,
                                                         fabs(_velocityX_prev)*c+c*2.0,
                                                         fabs(_velocityY_prev)*c+c*2.0)
                                )
                        {
                            if(npc->setup->hurt_player) harm(1);
                            if(!forceCollideCenter) break;
                            collided_center[(intptr_t)collided]=collided;
                            #ifdef COLLIDE_DEBUG
                            qDebug() << "Center of block";
                            found=true;
                            #endif
                        }

                        #ifdef COLLIDE_DEBUG
                        qDebug() << "---checked---" << (found?"and found!": "but nothing..." )<<
                                    r1.left()<< "<="<< rc.right()<<"+"<<xSpeed ;
                        #endif
                        break;
                    }
                case COLLISION_NONE:
                    { //Detect top of stompable NPC!
                        if(!npc->setup->kill_on_jump)
                        {
                            if( npc->posRect.collideRect(posRect))
                            {
                               if(npc->setup->hurt_player) harm(1);
                            }
                            break;
                        }

//                        PGE_RectF &r1=posRect;
//                        PGE_RectF  rc = collided->posRect;
//                        float summSpeedY=(speedY()+_velocityY_add)-(collided->speedY()+collided->_velocityY_add);
//                        float summSpeedYprv=_velocityY_prev-collided->_velocityY_prev;
                        if(isCollideFloorToponly(collided))
//                                (
//                                    (summSpeedY >= 0.0)
//                                    &&
//                                    (r1.bottom() < rc.top()+summSpeedYprv)
//                                    &&
//                                    (
//                                         (r1.left()<rc.right()-1 ) &&
//                                         (r1.right()>rc.left()+1 )
//                                     )
//                                 )
//                                ||
//                                (r1.bottom() <= rc.top())
//                                )
                        {
                            npc->doHarm(LVL_Npc::DAMAGE_STOMPED);
                            this->bump(true);
                            //Reset floating state
                            floating_timer = floating_maxtime;
                            if(floating_isworks)
                            {
                                floating_isworks=false;
                                setGravityScale(climbing?0:physics_cur.gravity_scale);
                            }
                            kill_npc(npc, NPC_Stomped);
                        } else {
                            if( npc->posRect.collideRect(posRect))
                            {
                                //The second half of this "if" statement is there to fix a bug with falling collisions,
                                //and should NOT remain here because it is not how we should handle this!
                                //The bug occurs when the player is moving fast enough when they land on an enemy that they
                                //partially enter the enemy before the collision is resolved, causing the engine to think
                                //that the player is INSIDE the NPC, when they are actually only JUMPING on the NPC.
                                if(npc->setup->hurt_player & (!npc->setup->kill_on_jump || colliding_ySpeed > -1.0f)) harm(1);
                            }
                        }
                        break;
                    }//case COLLISION_NONE
                default: break;
                }
            }
            break;
        }
        case PGE_Phys_Object::LVLPhysEnv:
        {
            LVL_PhysEnv *env= static_cast<LVL_PhysEnv*>(collided);
            if(env)
            {
                if(env) environments_map[(intptr_t)env]=env->env_type;
            }
            break;
        }
    default: break;
    }
}
Esempio n. 3
0
/*----------------------------------------------------------------------------*/
void  use_bomb_powerup(void)
{
    Mix_Volume(-1,(game.config.Audio_Sound_Volume/2));
    if (!boss_level())
    {
        for (int npc_count = 0; npc_count < MAX_NPCS; npc_count++) //kill all npcs
        {
            sound.explosion_005.play();
            if (game_o.npc[npc_count].active)
            {
                int random_temp = random_int();
                if (random_temp <= game_o.coin_spawn_rate) //spawn coin
                {
                    spawn_coin(game_o.npc[npc_count].x_pos,game_o.npc[npc_count].y_pos,(game_o.npc[npc_count].type_npc+1+random_dec()));
                }
                if ((random_temp > game_o.coin_spawn_rate) && (random_temp <= game_o.wexp_spawn_rate)) //spawn wexp
                {
                    spawn_wexp(game_o.npc[npc_count].x_pos,game_o.npc[npc_count].y_pos,(game_o.npc[npc_count].type_npc+1+random_dec()));
                }
                if (random_temp > game_o.wexp_spawn_rate) //spawn null
                {
                    ;
                }
                game_o.score += (game_o.npc[npc_count].type_npc + 1) * 10;
                game_o.level_score += (game_o.npc[npc_count].type_npc + 1) * 10;
                spawn_explosion(game_o.npc[npc_count].x_pos,game_o.npc[npc_count].y_pos,0.50f);
                kill_npc(npc_count);
                game_o.kills++;
                game_o.level_kills++;
            }
        }
    }
    if (boss_level())
    {
        for (int npc_count = 0; npc_count < MAX_NPCS; npc_count++) //damage all npcs
        {
            sound.explosion_005.play();
            if (game_o.npc[npc_count].active)
            {
                game_o.npc[npc_count].health -= (game_o.enemy[game_o.npc[npc_count].type_npc].health/10);
                if (game_o.npc[npc_count].health <= 0)
                {
                    kill_npc(npc_count);
                    game_o.kills++;
                    game_o.level_kills++;
                }
            }
        }
    }
    for (int npc_count = 0; npc_count < MAX_NPCS; npc_count++)//kill all npc bullets
    {
        for (int bullet_count = 0; bullet_count < MAX_BULLETS-1; bullet_count++)
        {
            if (game_o.npc[npc_count].bullet[bullet_count].active)
            {
                spawn_explosion(game_o.npc[npc_count].bullet[bullet_count].x_pos,game_o.npc[npc_count].bullet[bullet_count].y_pos,0.125f);
                kill_npc_bullet(npc_count,bullet_count);
                kill_npc_bullet(npc_count,bullet_count);
            }
        }
    }
    Mix_Volume(-1,game.config.Audio_Sound_Volume);
}
void LVL_Player::attack(LVL_Player::AttackDirection _dir)
{
    PGE_RectF attackZone;

    switch(_dir)
    {
        case Attack_Up:
            attackZone.setRect(posCenterX()-5, top()-17, 10, 5);
        break;
        case Attack_Down:
            attackZone.setRect(posCenterX()-5, bottom(), 10, 5);
        break;
        case Attack_Forward:
            if(_direction>=0)
                attackZone.setRect(right(), bottom()-32, 10, 10);
            else
                attackZone.setRect(left()-10, bottom()-32, 10, 10);
        break;
    }


    QVector<PGE_Phys_Object*> bodies;
    LvlSceneP::s->queryItems(attackZone, &bodies);
    int contacts = 0;

    QList<LVL_Block *> target_blocks;
    QList<LVL_Npc*> target_npcs;
    for(PGE_RenderList::iterator it=bodies.begin();it!=bodies.end(); it++ )
    {
        PGE_Phys_Object*visibleBody=*it;
        contacts++;
        if(visibleBody==this) continue;
        if(visibleBody==NULL)
            continue;
        if(!visibleBody->isVisible()) //Don't whip elements from hidden layers!
            continue;
        switch(visibleBody->type)
        {
            case PGE_Phys_Object::LVLBlock:
                target_blocks.push_back(static_cast<LVL_Block*>(visibleBody));
                break;
            case PGE_Phys_Object::LVLNPC:
                target_npcs.push_back(static_cast<LVL_Npc*>(visibleBody));
                break;
            case PGE_Phys_Object::LVLPlayer:
                default:break;
        }
    }

    foreach(LVL_Block *x, target_blocks)
    {
        if(!x) continue;
        if(x->destroyed) continue;
        if(x->sizable && _dir==Attack_Forward)
            continue;
        x->hit();
        if(!x->destroyed)
        {
            LvlSceneP::s->launchStaticEffectC(69, x->posCenterX(), x->posCenterY(), 1, 0, 0, 0, 0);
            PGE_Audio::playSoundByRole(obj_sound_role::WeaponExplosion);
        }
        x->destroyed=true;
    }
    foreach(LVL_Npc *x, target_npcs)
    {
        if(!x) continue;
        if(x->isPaused()) continue; //Don't attack NPC with paused physics!
        if(x->isKilled()) continue;
        if(x->isGenerator) continue;
        x->doHarm(LVL_Npc::DAMAGE_BY_PLAYER_ATTACK);
        LvlSceneP::s->launchStaticEffectC(75, attackZone.center().x(), attackZone.center().y(), 1, 0, 0, 0, 0);
        kill_npc(x, NPC_Kicked);
    }
}