void Debri::init( int ind ) { tex_epsilon = DEFAULT_TEX_EPS; setIndex(ind); if( index < 13*16 ) setScl(PPC*0.6); else setScl(PPC); falling_to_pit = false; if( ind == B_ATLAS_ITEM_DARK_MATTER_PARTICLE ) { setFragmentShader( g_eye_col_replacer ); } }
bool Debri::charPoll( double dt ) { if( falling_to_pit ) { if( scl.x < 0.1 ) return false; else return true; } if( index == B_ATLAS_ITEM_ENERGY_PARTICLE ) { setScl(PPC*range(0.1,1)); } if( index == B_ATLAS_ITEM_HYPER_PARTICLE ) { if( updateInterval(0, 0.25f) && range(0,100)< 20 ) { Particle *p = createHyperSpark(loc); p->v = Vec2(0,0).randomize(100); } } Vec2 nextloc = loc + v * dt; Cell *c = g_fld->get(nextloc); if( c && c->isWall(false) ) { // Just reversing. First X and then Y bool xhit=false, yhit=false; Vec2 nxloc = loc + Vec2( v.x * dt, 0 ); Cell *nxc = g_fld->get(nxloc); if( (!nxc) || nxc->isWall(false)) { v.x *= -1; xhit = true; } Vec2 nyloc = loc + Vec2( 0, v.y * dt ); Cell *nyc = g_fld->get(nyloc); if( (!nyc) || nyc->isWall(false) ) { v.y *= -1; yhit = true; } if( xhit && yhit ) v *= 0; } else if(c && c->gt == GT_PIT ) { Cell *cells[4]; g_fld->getCorner4(loc, PPC/3, &cells[0], &cells[1], &cells[2], &cells[3] ); bool tofall = true; for(int i=0;i<4;i++) { if( cells[i] && cells[i]->gt != GT_PIT ) tofall = false; } if( tofall ) { soundPlayAt( g_fall_sound, loc,1 ); falling_to_pit = true; seekScl( 0,0, 0.5 ); } } loc = nextloc; v *= 0.98; if( v.len() < 5 ) v *=0; // Timeout flickering if( accum_time > DEBRI_WARN_ERASE_SEC ) { setVisible( (int)(accum_time * 20) % 2 ); if( accum_time > DEBRI_ERASE_SEC ) { return false; } } // Field class implements item gathering by PCs if( g_fld->checkGatherDebri(this) ) { realtimeCharDeleteSend(this); return false; } rot += rotate_speed; return true; }
bool Beam::charPoll( double dt ) { // Shifter tile bends beam Cell *c = g_fld->get(loc); if( c->gt == GT_SHIFTER && c->st == ST_NONE && c->bt == BT_AIR ) { Vec2 dv = dirToVec2(c->dir) * PPC* SHIFTER_ACCEL; v += dv * dt; if( v.len() > BEAM_NORMAL_VEL ) { v = v.normalize(BEAM_NORMAL_VEL); } setRot( atan2(v.y,v.x)); // print("v:%f %f dv:%f %f d:%d",v.x,v.y, dv.x, dv.y, c->dir ); } loc += v * dt; // Stronger is bigger float s = PPC; if( ene >= 64 ) s *= 3; else if( ene >= 16 ) s *= 2; else if( ene >= 4 ) s *= 1.5; setScl(s); // Shoot on blocks Vec2 rt,lt,rb,lb; Cell *rtc = g_fld->get( rt = loc + Vec2(hitsz,hitsz)); Cell *ltc = g_fld->get( lt = loc + Vec2(-hitsz,hitsz)); Cell *rbc = g_fld->get( rb = loc + Vec2(hitsz,-hitsz)); Cell *lbc = g_fld->get( lb = loc + Vec2(-hitsz,-hitsz)); Cell *tgtc = NULL; Vec2 tgtat; Vec2 candat[4]; Cell *cands[4]; int candi=0; // if(rtc&&rtc->isBeamHit() && rtc->isImmutableAgainstBeam()==false ) { cands[candi] = rtc; candat[candi] = rt; candi++; } if(rbc&&rbc->isBeamHit() && rbc->isImmutableAgainstBeam()==false ) { cands[candi] = rbc; candat[candi] = rb; candi++; } if(ltc&<c->isBeamHit() && ltc->isImmutableAgainstBeam()==false ) { cands[candi] = ltc; candat[candi] = lt; candi++; } if(lbc&&lbc->isBeamHit() && lbc->isImmutableAgainstBeam()==false ) { cands[candi] = lbc; candat[candi] = lb; candi++; } if( candi > 0 ) { int ind = irange(0,candi); tgtc = cands[ind]; tgtat = candat[ind]; } // Out of the world if(!rtc)return false; if( rtc && rtc->gt == GT_JUNGLE && range(0,100) < 1 ) { createLeafEffect(loc); } updateIndex(); if( isRemote() ) return true; if(tgtc) { int consumed; BLOCKTYPE orig_bt = tgtc->bt; if( g_fld->damage(tgtat,ene,&consumed,this) ) { createSparkEffect(); if( orig_bt == BT_CELL || orig_bt == BT_FLYGEN ) { soundPlayAt(g_wormdamage_sound,loc,1); } else if( orig_bt != BT_SNOW && orig_bt != BT_IVY && orig_bt != BT_TREE && orig_bt != BT_BOMBFLOWER ) { soundPlayAt(g_beamhithard_sound,loc,1); } if( orig_bt == BT_BARRIER && tgtc->hyper_count > 0 ) { Vec2 tgt; if( g_fld->findEnemyAttackTarget(loc,&tgt, MACHINE_SHOOT_DISTANCE ) ) { int n = irange(1,4); for(int i=0;i<n;i++) Bullet::shootAt( BLT_SPARIO, loc, tgt ); } } ene -= consumed; if( ene <= 0 ) return false; else return true; } } else { // Immutable cells Cell *cells[4]; g_fld->getCorner4( loc, 1, &cells[0], &cells[1], &cells[2], &cells[3] ); for(int i=0;i<4;i++) { if(cells[i] && cells[i]->isImmutableAgainstBeam()) { soundPlayAt(g_beamhithard_sound,loc,1); createSparkEffect(); return false; } } } if( type == BEAMTYPE_BLASTER ) { float s = PPC; g_fld->meltSnow(loc + Vec2(-s,-s) ); g_fld->meltSnow(loc + Vec2(-s,s) ); g_fld->meltSnow(loc + Vec2(s,-s) ); g_fld->meltSnow(loc + Vec2(s,s) ); } else { if( range(0,100) < (float)(ene)/2.0 ) { g_fld->meltSnow(loc); } } // Shoot on enemies Char *cur = (Char*) g_char_layer->prop_top; while(cur) { if( cur->isEnemyCategory() ) { Enemy *e = (Enemy*) cur; if( e->hitWithFlyHeight(this,PPC/2) && e->beam_hits ) { int dmg = ene; if( dmg > e->hp ) dmg = e->hp; e->notifyHitBeam(this, dmg); createSparkEffect(); // ene -= dmg; if(ene<=0) to_clean = true; g_fld->meltSnow(loc); } } else if( cur->category == CAT_PC ) { // recharging other player characters PC *pc = (PC*) cur; if( pc->hit(this,PPC/2)) { // print("pcid:%d shooter:%d ene:%d/%d", pc->id, shooter_id, pc->ene, pc->maxene ); if( pc->id != shooter_id && shooter_id == g_pc->id ) { // print("PC:E:%d id:%d max:%d", pc->ene, pc->id, pc->maxene ); int charged = pc->charge(ene); if(charged>0) { pc->energy_chain_heat_count ++; // print("sending E-chain e:%d(%d>%d) to: %d-%d heat:%d", // ene, charged, pc->ene, pc->client_id, pc->internal_id ,pc->energy_chain_heat_count ); realtimeEnergyChainSend(pc,charged); return false; } } } } cur = (Char*) cur->next; } return true; }
Char::Char( CATEGORY cat, Vec2 lc, TileDeck *dk, Layer *tgtlayer, int client_id, int internal_id ) : Prop2D(), category(cat), clean_at(0), client_id(client_id), internal_id(internal_id) { setScl(24,24); setDeck(dk); setLoc(lc); tgtlayer->insertProp(this); }
Particle(TileDeck *dk) : Prop2D() { setDeck(dk); setScl(32); setIndex(0); v = Vec2( range(-100,100), range(-100,100) ); }