Allow solo and last-active-player AFK
This commit is contained in:
+50
-5
@@ -167,11 +167,56 @@ for(const game of ['t5','t6']) {
|
||||
assert.equal(e.p.tws_afk_controls_locked,true);e.p.downed=false;e.p.ignoreme=false;e.tick();assert.equal(e.p.tws_afk_controls_locked,false);
|
||||
assert(!e.source.includes('disableInvulnerability('));assert(!e.source.includes('enableInvulnerability('));
|
||||
});
|
||||
test('last active cannot enter; last active death ends only AFK-only matches, respecting afterlife',()=>{
|
||||
const alone=engine(game);alone.other.downed=true;alone.enter();assert(!alone.p.hud_afk_on);assert.equal(alone.sent.length,0);
|
||||
const e=engine(game);e.enter();e.other.alive=false;e.c.afk_team_watcher().next();assert(!e.p.hud_afk_on);assert.equal(e.stops.at(-1).reason,'match_end');assert(e.log.some(x=>x[0]==='notify'&&x[1]==='end_game'));
|
||||
const recovering=engine(game);recovering.enter();recovering.other.afterlife=true;recovering.c.afk_team_watcher().next();assert(recovering.p.hud_afk_on);
|
||||
const noAfk=engine(game);noAfk.p.alive=false;noAfk.other.alive=false;noAfk.c.afk_team_watcher().next();assert(!noAfk.log.some(x=>x[0]==='notify'));
|
||||
test('solo and last active players can enter with unavailable or pending teammates',()=>{
|
||||
for(const flags of [null,{downed:true},{alive:false},{sessionstate:'spectator'},{afterlife:true},{hud_afk_on:true},{pending:true}]){
|
||||
const e=engine(game);
|
||||
if(flags===null)e.players.splice(1,1);
|
||||
else if(flags.pending)e.other.tws_afk_state.pending=true;
|
||||
else Object.assign(e.other,flags);
|
||||
e.enter();e.advance(1000);e.tick();
|
||||
assert(e.p.hud_afk_on);assert.equal(e.p.afk_remaining(),1799000);
|
||||
assert.equal(e.stops.length,0);assert.equal(e.p.sessionstate,'playing');
|
||||
assert(!e.log.some(x=>x[0]==='notify'));
|
||||
}
|
||||
});
|
||||
test('teammate death or disconnect during authorization does not cancel entry',()=>{
|
||||
for(const at of ['reserve','start'])for(const change of ['death','disconnect']){
|
||||
const e=engine(game,{during:request=>{
|
||||
if(request.action!==at)return;
|
||||
if(change==='death')e.other.alive=false;
|
||||
else e.players.splice(1,1);
|
||||
}});
|
||||
e.enter();e.tick();assert(e.p.hud_afk_on);assert.equal(e.stops.length,0);
|
||||
}
|
||||
});
|
||||
test('all players can be AFK and teammate loss does not force a match end',()=>{
|
||||
const e=engine(game);e.enter();e.c.afk_enter(e.other,e.other.tws_afk_state);
|
||||
e.advance(1000);e.tick();e.other.afk_tick().next();
|
||||
assert(e.p.hud_afk_on);assert(e.other.hud_afk_on);assert.equal(e.stops.length,0);
|
||||
e.other.alive=false;e.other.afk_tick().next();e.tick();
|
||||
assert(e.p.hud_afk_on);assert.equal(e.stops.at(-1).reason,'death');
|
||||
e.players.splice(1,1);e.advance(1000);e.tick();assert(e.p.hud_afk_on);
|
||||
assert(!e.log.some(x=>x[0]==='notify'));
|
||||
assert(!e.source.includes('afk_team_watcher'));
|
||||
assert(!/level\s+notify\("end_game"\)/.test(e.source));
|
||||
});
|
||||
test('solo protection expires normally and manual return preserves bounded grace',()=>{
|
||||
for(const manual of [false,true]){
|
||||
const e=engine(game,{authorized:3});e.players.splice(1,1);e.enter();
|
||||
e.advance(1000);assert.equal(e.p.afk_damage(null,null,10),0);
|
||||
if(manual){e.p.afk_exit();assert.equal(e.stops.at(-1).reason,'manual');}
|
||||
e.advance(2000);e.tick();
|
||||
assert(!e.p.hud_afk_on);assert(!e.p.tws_afk_protected);assert(!e.p.ignoreme);
|
||||
assert(!e.p.tws_afk_controls_locked);assert.equal(e.p.afk_damage(null,null,10),-1);
|
||||
if(!manual)assert.equal(e.stops.at(-1).reason,'expired');
|
||||
}
|
||||
});
|
||||
test('stock match end still releases and settles every AFK player',()=>{
|
||||
const e=engine(game);e.enter();e.c.afk_enter(e.other,e.other.tws_afk_state);
|
||||
const watcher=e.c.afk_end_watcher();watcher.next();watcher.next();
|
||||
assert(e.level.afk_ended);assert.equal(e.stops.length,2);
|
||||
for(const p of e.players){assert(!p.hud_afk_on);assert(!p.tws_afk_protected);assert(p.tws_afk_state.cancelled);}
|
||||
assert(e.stops.every(s=>s.reason==='match_end'));
|
||||
});
|
||||
test('repeat legitimate teammate revives all count, self/AFK/spectator revives do not',()=>{
|
||||
const e=engine(game);const watcher=e.other.afk_revive_watcher();watcher.next();
|
||||
|
||||
Reference in New Issue
Block a user