void scene::scene_box_update(void) { scene_box.set(); OBJECT_HIERARCHY_ITERATOR it = render_hierarchy_next_new(); SCENE_OBJECT_GEOMETRY *p_obj; int objnum = 0; while((p_obj = (SCENE_OBJECT_GEOMETRY *)render_hierarchy_next(&it))) { if(p_obj->object_is_geometry()) { BOX *p_box = p_obj->object_box_global_get(); if(p_box) { AABB tmp(p_box); scene_box.adjust(&tmp); objnum++; } } } if(!objnum) { scene_box.adjust(VECT(-DEFAULT_SCENE_BOX_SIZE, -DEFAULT_SCENE_BOX_SIZE, -DEFAULT_SCENE_BOX_SIZE)); scene_box.adjust(VECT(DEFAULT_SCENE_BOX_SIZE, DEFAULT_SCENE_BOX_SIZE, DEFAULT_SCENE_BOX_SIZE)); } }
int CSurasuta::StepFrame(VECT pos,int state) { VECT vect; m_anmtime++; if(m_state != state) m_anmtime = 0; switch(state) { case 0://normal m_posGun.Goto(m_playerpos[m_index] + c_gun_pos + VECT(0,sin(3.14*2*50*m_anmtime) * 2),SURASUTA_VEL); m_pimg->Draw2(110, m_posGun, 0, 1); //武器 m_posSurasuta.Goto(m_playerpos[m_index] + c_surasuta_pos + VECT(0,sin(3.14*2*50*(m_anmtime-20)) * 2),SURASUTA_VEL); m_pimg->Draw2(120, m_posSurasuta, 0, 0); //スラスタ break; case 1://suikomi m_posGun.Goto(m_playerpos[m_index] + c_gun_pos + VECT(0,sin(3.14*2*50*m_anmtime) * 2),SURASUTA_VEL); m_pimg->Draw2(110, m_posGun, 0, 1); //武器 m_posSurasuta.Goto(m_playerpos[m_index] + c_suikomi_pos+ VECT(0,sin(3.14*2*50*(m_anmtime-20)) * 2),SURASUTA_VEL); m_pimg->Draw2(120, m_posSurasuta, 0, 0); //スラスタ break; case 2://shot m_posSurasuta.Goto(m_playerpos[m_index] + c_gattai_pos + VECT(0,sin(3.14*2*50*(m_anmtime-20) * 2)),SURASUTA_VEL); m_posGun.Goto(m_playerpos[m_index] + c_gattai_pos + VECT(0,sin(3.14*2*50*m_anmtime)*2),SURASUTA_VEL); m_pimg->Draw2(110, m_posGun, 0, 3);//合体 break; case 3://suikomi+shot m_posSurasuta.Goto(m_playerpos[m_index] + c_suikomi_pos+ VECT(0,sin(3.14*2*50*(m_anmtime-20)) * 2),SURASUTA_VEL); m_posGun.Goto(m_playerpos[m_index] + c_gattai_pos+ VECT(0,sin(3.14*2*50*m_anmtime) * 2),SURASUTA_VEL); m_pimg->Draw2(110, m_posSurasuta, 0, 0);//スラスタ m_pimg->Draw2(110, m_posGun, 0, 2);//ショット break; case 4://apear m_posSurasuta = pos+c_surasuta_pos; m_posGun = pos+c_gun_pos; m_pimg->Draw2(120, m_posSurasuta, 0, 0); //スラスタ m_pimg->Draw2(120, m_posGun, 0, 1); //スラスタ break; } //吸い込み効果音 if((state==1 || state==3) && (m_state!=1 && m_state !=3))//開始 g_pResource->sndSuikomi.Play(DSBPLAY_LOOPING ); if((state!=1 && state!=3) && (m_state==1 || m_state==3))//停止 g_pResource->sndSuikomi.Stop(); m_state = state; //吸い込みエフェクト描画 if(state==1||state==3) { g_pResource->imgSuikomi.Draw2(200, m_posSurasuta.x+m_pimg->GetWidth(), m_posSurasuta.y+m_pimg->GetHeight()/2-g_pResource->imgSuikomi.GetHeight()/2, m_anmtime/5%8,0); } //スラスタの遅れ処理 m_playerpos[m_index] = pos; m_index++; if(m_index==SURASUTA_LATE) m_index=0; return 1; }
void rtc_init(void) { /* For detailed description please refer to hardware manual */ SYSTEM.SUBOSCCR.BIT.SUBSTOP = 0; /* Enable SubClock circuit */ RTC.RCR2.BIT.START = 0; while (0 != RTC.RCR2.BIT.START); RTC.RCR2.BIT.RESET = 1; while (1 == RTC.RCR2.BIT.RESET); /* Set initial time and date */ RTC.RSECCNT.BYTE = 0; RTC.RMINCNT.BYTE = 0; RTC.RHRCNT.BYTE = 0; RTC.RDAYCNT.BYTE = 0; RTC.RWKCNT.BYTE = 0; RTC.RMONCNT.BYTE = 0; RTC.RYRCNT.WORD = 0x2000; /* Set periodic interrupt */ RTC.RCR1.BYTE = 0; RTC.RCR1.BIT.PES = 1; /* Set periodic interrupts frequency to 256 Hz */ RTC.RCR1.BIT.PIE = 1; /* Enable periodic interrupts */ _isr_vectors[VECT(RTC,PRD)] = rtc_irq_handler; IR(RTC,PRD) = 0; /* Clear interrupt flag */ IPR(RTC,PRD) = 15; /* Set priority level */ IEN(RTC,PRD) = 1; /* Enable interrupt in ICU */ RTC.RCR2.BIT.START = 1; /* Start RTC */ while (1 != RTC.RCR2.BIT.START); }
CEnemyShot::CEnemyShot(CNkImage* pimg,VECT pos,VECT vel,int anm) { m_pimg=pimg; SetCenter(pos); m_vel=vel; m_velOrg=vel; m_pul=VECT(0,0); m_anm=anm; };
int CPlayer::CollTikei() { return g_pStage->CollTikei(VECT(GetLeft()+PL_OFFSET,GetTop()+PL_OFFSET))|| g_pStage->CollTikei(VECT(GetLeft()+PL_OFFSET,GetBottom()-PL_OFFSET))|| g_pStage->CollTikei(VECT(GetRight()-PL_OFFSET,GetTop()+PL_OFFSET))|| g_pStage->CollTikei(VECT(GetRight()-PL_OFFSET,GetBottom()-PL_OFFSET))|| g_pStage->CollTikei(VECT(GetLeft()+GetWidth()/2,GetTop()))|| g_pStage->CollTikei(VECT(GetLeft()+GetWidth()/2,GetBottom()))|| g_pStage->CollTikei(VECT(GetLeft(),GetTop()+GetHeight()/2))|| g_pStage->CollTikei(VECT(GetRight(),GetTop()+GetHeight()/2)); }
CPlayer::CPlayer(CNkImage* pimg, CNkImage* pimgSurasuta, int zanki,int item):m_surasuta(pimgSurasuta,VECT(-40,105)) { m_pimg = pimg; m_zanki = zanki; m_pos = VECT(-40,105); m_shottime = 0; m_anmtime = 0; m_state = 1; //出現アニメーションする、ということ。 m_muteki = PLAYER_MUTEKI; m_item = 0; m_power = 0; for(m_item=0;m_item<=item;++m_item) if(m_item%(80+150*m_power) == 0 && m_power<10) m_power++; }
//----------------------------------------------------------------------------- // Construction/Destruction //----------------------------------------------------------------------------- CVertex::CVertex() { TRACE_ENTER_FN( CVertex::CVertex ) m_eClassType = VERTEXCLASS; m_vColor = m_vPos = VECT( 0, 0, 0 ); m_fU = m_fV = m_fVirtX = m_fVirtY = m_fVirtZ = 0.0f; m_fPrecision = 0.1f; m_pConnectedVerts = NULL; m_iNumConnectedVerts = 0; sprintf( m_strName, "Vertex:%d", m_UniqueID ); m_UniqueID++; TRACE_LEAVE_FN() }
bool Triangle::checkPoint(const Point& point) const { Point ca = VECT(points[0], points[1]); Point cd = VECT(points[0], point); Point ab = VECT(points[1], points[2]); Point ad = VECT(points[1], point); Point bc = VECT(points[2], points[0]); Point bd = VECT(points[2], point); int mul1 = MUL(ca, cd); int mul2 = MUL(ab, ad); int mul3 = MUL(bc, bd); return ((SGN(mul1) == SGN(mul2)) && (SGN(mul2) == SGN(mul3)) && (SGN(mul3) == SGN(mul1))); }
int CPlayer::StepFrame() { int i; VECT former = m_pos; switch(m_state) { case 0://通常状態 //移動処理 if(GetInputState(INP_RIGHT) && GetRight() < SCREEN_WIDTH) m_pos.x += PLAYER_SPEED; while(CollTikei()) { m_pos.x --; if(m_pos.x < 0 && m_muteki==0) { Damage(); break; } } if(GetInputState(INP_LEFT) && GetLeft() > 0) m_pos.x -= PLAYER_SPEED; if(CollTikei()) m_pos.x = former.x; if(GetInputState(INP_DOWN) && GetBottom() < SCREEN_HEIGHT) m_pos.y += PLAYER_SPEED; if(GetInputState(INP_UP) && GetTop() > 0) m_pos.y -= PLAYER_SPEED; if(CollTikei()) m_pos.y = former.y; //ショット if(GetInputState(INP_B0)) { m_shottime++; if(m_shottime%(8-m_power/2) == 0) { g_pResource->sndShot.Play(0); g_pshot.Add(new CPlayerShot(&g_pResource->imgPlayerShot, m_surasuta.GetPos()-VECT(10,5), VECT(20,0))); g_pshot.Add(new CPlayerShot(&g_pResource->imgPlayerShot, m_surasuta.GetPos()+VECT(-10,5), VECT(20,0))); } if(m_shottime%(10) == 0) { if(m_power>0) { g_pshot.Add(new CPlayerShot(&g_pResource->imgSubShot2, GetCenter()+VECT(0,5), VECT(10,3))); g_pshot.Add(new CPlayerShot(&g_pResource->imgSubShot1, GetCenter()-VECT(0,5), VECT(10,-3))); } if(m_power>3) { g_pshot.Add(new CPlayerShot(&g_pResource->imgSubShot2, GetCenter()+VECT(0,5), VECT(10,1.5))); g_pshot.Add(new CPlayerShot(&g_pResource->imgSubShot1, GetCenter()-VECT(0,5), VECT(10,-1.5))); } if(m_power>5) { g_pshot.Add(new CPlayerShot(&g_pResource->imgSubShot2, GetCenter()+VECT(0,5), VECT(10,7))); g_pshot.Add(new CPlayerShot(&g_pResource->imgSubShot1, GetCenter()-VECT(0,5), VECT(10,-7))); } if(m_power>7) { g_pshot.Add(new CPlayerShot(&g_pResource->imgSubShot2, GetCenter()+VECT(0,5), VECT(10,5))); g_pshot.Add(new CPlayerShot(&g_pResource->imgSubShot1, GetCenter()-VECT(0,5), VECT(10,-5))); } } } //無敵処理 if(m_muteki>0) m_muteki--; //吸い込み if(GetInputState(INP_B1)) { for(i=0; i<ITEM_NUM; ++i) if(g_item[i]) g_item[i]->Pull(); for(i=0; i<ENEMYSHOT_NUM; ++i) if(g_enemyShot[i]) g_enemyShot[i]->Pull(GetCenter()); } //当たり判定:アイテム if(m_anmtime%2) for(i=0; i<ITEM_NUM; ++i){ if(g_item[i]){ if(this->IsColl(g_item[i])){ g_pResource->sndItem.Play(0); g_pScore->item ++; g_pScore->score += SCORE_ITEM; m_item++; if(m_item%(80+150*m_power) == 0 && m_power<10) m_power++; SAFE_DELETE(g_item[i]); break; } } } //当たり判定:敵 if(m_muteki==0){ for(i=0; i<ENEMY_NUM; ++i){ if(g_enemy[i]&&g_enemy[i]->GetHP()!=20){ if(this->IsColl2(g_enemy[i])){ Damage(); break; } } } } //当たり判定:敵弾 if(m_muteki==0){ for(i=0; i<ENEMYSHOT_NUM; ++i){ if(g_enemyShot[i]){ if(this->IsColl2(g_enemyShot[i])){ Damage(); break; } } } } //アニメ処理 m_anmtime++; if(m_anmtime==PLAYER_ANMCYCLE) m_anmtime=0; //描画 //本体(無敵でない・無敵中点滅オン・ポーズ寸前) if(m_muteki==0||m_anmtime%5||GetInputEvent(INP_B3)) m_pimg->Draw2(100, m_pos.x, m_pos.y, m_anmtime*3/PLAYER_ANMCYCLE, GetInputState(INP_LEFT)); //スラスタ if(GetInputState(INP_B0) && GetInputState(INP_B1)) //吸い込み+ショット m_surasuta.StepFrame(m_pos,3); else if(GetInputState(INP_B0))//ショット(変形 m_surasuta.StepFrame(m_pos,2); else if(GetInputState(INP_B1))//吸い込み m_surasuta.StepFrame(m_pos,1); else//なんもなし m_surasuta.StepFrame(m_pos,0); break; case 1://出現モーション中 m_anmtime++; m_pos.x += (30.0-m_anmtime)/5; m_pimg->Draw2(100, m_pos); //本体 m_surasuta.StepFrame(m_pos,4); if(m_anmtime > 40) { m_anmtime = 0; m_muteki = PLAYER_MUTEKI; m_state = 0;//通常状態に戻す } break; case 2://死亡モーション(墜落)中 m_anmtime++; m_pos.y += (double)m_anmtime/5; m_pimg->Draw2(100, m_pos, 0, 2); m_surasuta.StepFrame(m_pos,4); if(m_anmtime > 40) { //ゲームオーバーチェックは墜落が終わってから if(m_zanki<0) return 0; m_pos = VECT(-40,105); m_anmtime = 0; m_state = 1; } break; } //残機数描画 for(i=0;i<m_zanki;++i) g_pResource->imgZanki.Draw2(70,130+i*20,215); return 1; }
int CPlayer::CollTikei() { return g_pStage->CollTikei(VECT(GetLeft()+PL_OFFSET,GetTop()+PL_OFFSET))|| g_pStage->CollTikei(VECT(GetLeft()+PL_OFFSET,GetBottom()-PL_OFFSET))|| g_pStage->CollTikei(VECT(GetRight()-PL_OFFSET,GetTop()+PL_OFFSET))|| g_pStage->CollTikei(VECT(GetRight()-PL_OFFSET,GetBottom()-PL_OFFSET))|| g_pStage->CollTikei(VECT(GetLeft()+GetWidth()/2,GetTop()))|| g_pStage->CollTikei(VECT(GetLeft()+GetWidth()/2,GetBottom()))|| g_pStage->CollTikei(VECT(GetLeft(),GetTop()+GetHeight()/2))|| g_pStage->CollTikei(VECT(GetRight(),GetTop()+GetHeight()/2)); } /*----------------------------------------------------------------------------- スラスタ関係 -----------------------------------------------------------------------------*/ const VECT c_surasuta_pos = VECT( 8, 15); const VECT c_gun_pos = VECT( 4, 20); const VECT c_gattai_pos = VECT( 15, 20); const VECT c_suikomi_pos = VECT(20,15); #define SURASUTA_VEL 5 int CSurasuta::StepFrame(VECT pos,int state) { VECT vect; m_anmtime++; if(m_state != state) m_anmtime = 0; switch(state) { case 0://normal m_posGun.Goto(m_playerpos[m_index] + c_gun_pos + VECT(0,sin(3.14*2*50*m_anmtime) * 2),SURASUTA_VEL); m_pimg->Draw2(110, m_posGun, 0, 1); //武器
// Helper function for the lightning effect. // Creates an recursive lightning bolt void light_bolt(VECT pos1, VECT pos2, int points, float noise, float thickness, int level, float color[4]) { if(level > 6) return; // Don't recurse too deeply // Create the points array VECT *point = new VECT[points]; if(!point) return; // Define the end points point[0] = pos1; point[points-1] = pos2; // Compute the direction from pos1 to pos2 VECT dir = pos2 - pos1; float dist = vector_length(dir); float step = dist / points; normalize(dir); // Make a straight line between pos1 and pos2, and randomize it a bit for(int f=1; f < points-1; f++) { point[f] = point[f-1] + step * dir; point[f].x += RANDF(-noise, noise); point[f].y += RANDF(-noise, noise); point[f].z += RANDF(-noise, noise); // Create some recursive bolts if(RAND(0,100) > 45) { // Choose a destination which isn't too close to the original point VECT dest; dest.x = RANDF(-noise,noise); dest.y = RANDF(-noise,noise); dest.z = RANDF(-noise,noise); bool ok = false; while(!ok) { float bdist = vector_length(VECT(dest - point[f])); float rad = noise * 0.5f; if(bdist > rad) { // Also try to steer the bolts towards the ground if((point[f].y + dest.y) < point[f].y) ok = true; else ok = false; } if(!ok) { dest.x = RANDF(-noise,noise); dest.y = RANDF(-noise,noise); dest.z = RANDF(-noise,noise); } } dest *= RANDF(3.0f, 7.0f); light_bolt(point[f], point[f] + dest, int(points * 0.65f), noise * 0.5f, thickness * 0.5f, level + 1, color); } } glColor4fv(color); glLineWidth(thickness); glBegin(GL_LINE_STRIP); for(int f=0; f<points; f++) { //for(int f=0; f<points-1; f++) { glVertex3f(point[f].x, point[f].y, point[f].z); //glVertex3f(point[f+1].x, point[f+1].y, point[f+1].z); } glEnd(); // Draw some glows if(level == 0) { BIND_TEXTURE(part_glow); glColor4f(.4f, .8f, 1, RANDF(.15f,.25f)); for(int f=0; f<points; f++) { glPushMatrix(); glTranslatef(point[f].x, point[f].y, point[f].z); // Negate the camera rotation glRotatef(45.0f, 0,1,0); glRotatef(-30.0f, 1,0,0); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(1,1); glVertex3f( 1, 1, 1); glTexCoord2f(0,1); glVertex3f(-1, 1, 1); glTexCoord2f(1,0); glVertex3f( 1, -1, -1); glTexCoord2f(0,0); glVertex3f(-1, -1, -1); glEnd(); glPopMatrix(); } BIND_TEXTURE(0); } delete [] point; }
// Move the player void PLAYER::move() { #ifndef EDITOR int who = (this == &p1) ? 1 : 2; int who2 = who-1; // Used for array indices // Reduce the icon alpha if(p_icon_alpha[who2]) { p_icon_alpha[who2] -= 0.005f; if(p_icon_alpha[who2] < 0.0f) p_icon_alpha[who2] = 0.0f; } // If we're dead, reduce the death counter and respawn if(!alive) { death_counter--; if(death_counter == 0) { // Respawn to a block int ox, oy; get_respawn_position((int)get_real_x(), (int)get_real_y(), ox, oy); int odir = dir; //clear(); alive = true; x = ox; y = oy; dir = odir; nextdir = dir; tx = x; ty = y; walking = false; jumping = false; dying = false; offset = 0.0f; create_teleport_effect(x, y); show_icon(who2); // Play the appear sound play_sound(SND_APPEAR, false); } return; } // Advance the dying animation if we're actually dying if(dying) { die_anim -= 0.03f; // Create the blue "burning down" effect float px = get_real_x(); float py = get_real_y(); for(int f=0; f < RAND(2,10); f++) { float rnd = RANDF(-0.3f, 0.3f); VECT pos(px, 2*size - 0.05f - (2.5f*size*(1-die_anim)), py); pos.x += rnd; pos.z -= rnd; if(pos.y < 0.0f) pos.y = 0.0f; VECT dir = 0.0f; float c1[4] = { 0.1f, 0.7f, 1, 1 }; float c2[4] = { 0.1f, 0.7f, 1, 0 }; add_particle(pos, dir, RAND(20,35), 0.1f, 0.4f, c1, c2, part_star); } if(die_anim < 0.0f) { die_anim = 0.0f; alive = false; // Explode the player bombs if(num_bombs > 0) { list<BOMB>::iterator b; for(b = bomblist.begin(); b != bomblist.end(); ++b) if((*b).owner == who && (*b).time > 1) (*b).time = 1; // Makes the bomb explode on the next cycle } } return; } // Jumping stuff if(jumping) { jump_pos += jump_speed; if(jump_pos >= 1.0f) { jump_pos = 1.0f; // We're now on the target tile x = jump_tx; y = jump_ty; tx = x; ty = y; offset = 0.0f; jumping = false; } // Create some particles if we're teleporting if(in_teleport && jumping) { VECT pos(get_real_x(), 0.25f, get_real_y()); pos += jump_dir * jump_pos * jump_dist; pos.y += jump_height * SIN(180.0f * jump_pos); VECT dir; for(int f=0; f<5; f++) { VECT ppos = pos + VECT(RANDF(-0.5f,0.5f),RANDF(-0.5f,0.5f),RANDF(-0.5f,0.5f)); dir.x = dir.y = dir.z = 0.0f; float c1[4] = { 0.3, 0.7f, 1, 1 }; float c2[4] = { 0, 0, 1, 0 }; add_particle(ppos, dir, RAND(10,30), 0.1f, 0.3f, c1, c2, part_teleport); } } // This is a dirty hack. Read the comments from the beginning of this file. if(map[jump_tx][jump_ty][1] && jump_pos > 0.9f) { players_on_block_x[who2] = jump_tx; players_on_block_y[who2] = jump_ty; } return; } // This is a dirty hack. Read the comments from the beginning of this file. if(map[x][y][1]) { players_on_block_x[who2] = x; players_on_block_y[who2] = y; //return; } else { players_on_block_x[who2] = -1; } // Don't move if we're using the napalm or the teleport power if(using_special_power && (which_special_power == RED_POWER_NAPALM)) return; if(using_special_power == who && (which_special_power == BLUE_POWER_TELEPORT)) return; // Don't move if the level is finished if(level_pause) return; // Advance the animation anim += 0.20f; if((int)anim > 3) anim = 0.0f; // Advance the turning animation if(turning) { turning_counter++; if(turning_counter == 5) { dir = nextdir; nextdir = dir + 1; if(nextdir > DIR_W) nextdir = DIR_N; } else if(turning_counter == 10) { dir = nextdir; turning = false; } } if(!walking && ((config.moving_style[who2] == MOV_RELATIVE && !key[config.key_up[who2]]) || (config.moving_style[who2] == MOV_ABSOLUTE && !key[config.key_up[who2]] && !key[config.key_down[who2]] && !key[config.key_left[who2]] && !key[config.key_right[who2]]))) anim = 0.0f; // Check if we're on a block bool on_block = false; if(map_solid(x,y)) on_block = true; // Don't move if we're using the flower power (absolute) if(on_block && config.moving_style[who2] == MOV_ABSOLUTE && (p1.num_flower_bombs > 0 || p2.num_flower_bombs > 0)) return; // Check for turning input if(key[config.key_left[who2]]) { if(config.moving_style[who2] == MOV_RELATIVE) { // Relative moving if(!turn_key_down[0] && !turning) { // Turn left nextdir = dir - 1; if(nextdir < DIR_N) nextdir = DIR_W; if(!walking) dir = nextdir; turn_key_down[0] = true; } } else if(config.moving_style[who2] == MOV_ABSOLUTE && !walking) { // Absolute moving dir = DIR_W; walking = true; offset = 0.0f; tx = x - 1; ty = y; // Check if the target is passable? if(map_solid(tx, ty)) { tx = x; ty = y; walking = false; } if(on_block) { // We're on a block, jump down from it jump(tx, ty, 2.0f, 0.05f); tx = x; ty = y; anim = 0; on_block = true; // Play the jumping sound if(jumping) play_sound(SND_JUMP, false); } } } else turn_key_down[0] = false; if(key[config.key_right[who2]]) { if(config.moving_style[who2] == MOV_RELATIVE) { // Relative moving if(!turn_key_down[1] && !turning) { // Turn right nextdir = dir + 1; if(nextdir > DIR_W) nextdir = DIR_N; if(!walking) dir = nextdir; turn_key_down[1] = true; } } else if(config.moving_style[who2] == MOV_ABSOLUTE && !walking) { // Absolute moving dir = DIR_E; walking = true; offset = 0.0f; tx = x + 1; ty = y; // Check if the target is passable? if(map_solid(tx, ty)) { tx = x; ty = y; walking = false; } if(on_block) { // We're on a block, jump down from it jump(tx, ty, 2.0f, 0.05f); tx = x; ty = y; anim = 0; on_block = true; // Play the jumping sound if(jumping) play_sound(SND_JUMP, false); } } } else turn_key_down[1] = false; // Check for 180 degree turning if(key[config.key_down[who2]]) { if(config.moving_style[who2] == MOV_RELATIVE) { // Relative moving if(!turn_key_down[2] && !turning && !walking && !key[config.key_up[who2]]) { nextdir = dir + 1; if(nextdir > DIR_W) nextdir = DIR_N; turning = true; turning_counter = 0; turn_key_down[2] = true; } } else if(config.moving_style[who2] == MOV_ABSOLUTE && !walking) { // Absolute moving dir = DIR_S; walking = true; offset = 0.0f; tx = x; ty = y + 1; // Check if the target is passable? if(map_solid(tx, ty)) { tx = x; ty = y; walking = false; } if(on_block) { // We're on a block, jump down from it jump(tx, ty, 2.0f, 0.05f); tx = x; ty = y; anim = 0; on_block = true; // Play the jumping sound if(jumping) play_sound(SND_JUMP, false); } } } else turn_key_down[2] = false; // Don't move if we're using the flower power (relative) if(on_block && config.moving_style[who2] == MOV_RELATIVE && (p1.num_flower_bombs > 0 || p2.num_flower_bombs > 0)) return; // Check for walking input if(key[config.key_up[who2]] && !walking && !turning) { if(config.moving_style[who2] == MOV_RELATIVE) { // Relative moving walking = true; offset = 0.0f; dir = nextdir; switch(dir) { default: case DIR_N: tx = x; ty = y - 1; break; case DIR_E: tx = x + 1; ty = y; break; case DIR_S: tx = x; ty = y + 1; break; case DIR_W: tx = x - 1; ty = y; break; } // Check if the target is passable? if(map_solid(tx, ty)) { tx = x; ty = y; walking = false; } if(on_block) { // We're on a block, jump down from it jump(tx, ty, 2.0f, 0.05f); tx = x; ty = y; anim = 0; on_block = true; // Play the jumping sound if(jumping) play_sound(SND_JUMP, false); } } else { // Absolute moving dir = DIR_N; walking = true; offset = 0.0f; tx = x; ty = y - 1; // Check if the target is passable? if(map_solid(tx, ty)) { tx = x; ty = y; walking = false; } if(on_block) { // We're on a block, jump down from it jump(tx, ty, 2.0f, 0.05f); tx = x; ty = y; anim = 0; on_block = true; // Play the jumping sound if(jumping) play_sound(SND_JUMP, false); } } } // Move towards the target tile if(offset < 1.0f && (tx != x || ty != y)) { offset += 0.1f; // If we're reached the target tile, move again if(offset >= 1.0f) { x = tx; y = ty; offset = 0.0f; walking = false; in_teleport = 0; } } // Reload the weapons if(reload > 0) reload--; // Dropping bombs if(key[config.key_shoot[who2]] && reload == 0 && num_bombs < 3 && !on_block && !icon_menu.wait) { reload = 30; // Plant the bomb add_bomb(x, y, BTYP_NORMAL, who); num_bombs++; // Play the sound play_sound(SND_BOMB, false); } // Invoke the special powers if(key[config.key_special[who2]]) { open_icon_menu(who, on_block); show_icon(0); show_icon(1); } #endif }