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; } }
/*----------------------------------------------------------------------------*/ 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); } }