feat: 2.5s lockout before dropped weapons can be re-picked
This commit is contained in:
1 parent
7aee2f5f64
commit
e801c02ef6
4 files changed
+29
-3
No files matched your search
+1
-1
@@ -117,7 +117,7 @@ function collectPickup(k) {
|
||||
if (old) {
|
||||
const a = rand(0, TAU);
|
||||
spawnPickup('weapon', p.x + Math.cos(a) * 34, p.y + Math.sin(a) * 34,
|
||||
{ wid: old.id, ammo: old.ammo, delay: 0.6 });
|
||||
{ wid: old.id, ammo: old.ammo, delay: WEAPON_DROP_LOCKOUT });
|
||||
}
|
||||
p.weapon = { id: w.id, ammo: k.ammo !== undefined ? k.ammo : w.ammo };
|
||||
p.holstered = null;
|
||||
|
||||
@@ -59,6 +59,8 @@ const PERK_POWER_WEIGHT = 0.5;
|
||||
// ammo economy: global dial for drop frequency (refill size is per-weapon)
|
||||
const AMMO_DROP_SCALE = 0.75;
|
||||
const PRESSURE_MIN = 0.60, PRESSURE_MAX = 2.00;
|
||||
// seconds a player-dropped weapon stays un-pickable (prevents instant swap loops)
|
||||
const WEAPON_DROP_LOCKOUT = 2.5;
|
||||
const PRESSURE_UNIT = 0.01; // one "point" on the dial scale
|
||||
const PRESSURE_GAIN = PRESSURE_UNIT; // retained: dial 0 == 1 point
|
||||
const PRESSURE_DROP_BASE = 3; // dial 0 == 0.03 relief base
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "meatslicer",
|
||||
"version": "0.1.0",
|
||||
"version": "0.5.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "meatslicer",
|
||||
"version": "0.1.0",
|
||||
"version": "0.5.0",
|
||||
"devDependencies": {
|
||||
"electron": "^40.10.2",
|
||||
"electron-builder": "^25.1.8"
|
||||
|
||||
@@ -324,6 +324,30 @@ console.log('== upgrade card click does not fire ==');
|
||||
check('card click fires no bullet (mdown not carried into play)', ctx.G.bullets.length === 0);
|
||||
}
|
||||
|
||||
console.log('== dropped weapon lockout ==');
|
||||
{
|
||||
ctx.startRun(); step(3, 16); // clean, armed player in play mode
|
||||
const p = ctx.G.player;
|
||||
p.weapon = { id: 'cleaver', ammo: 60 }; p.holstered = null;
|
||||
ctx.G.pickups.length = 0;
|
||||
ctx.spawnPickup('weapon', p.x, p.y, { wid: 'repeater', ammo: 30 });
|
||||
ctx.updatePickups(0.016); ctx.updatePickups(0.016); // pick up the repeater
|
||||
check('weapon swap happens instantly on fresh loot', p.weapon.id === 'repeater');
|
||||
const drop = ctx.G.pickups.find(k => k.type === 'weapon');
|
||||
check('old weapon dropped with the lockout delay', !!drop && Math.abs(drop.delay - ctx.WEAPON_DROP_LOCKOUT) < 0.1);
|
||||
if (drop) { drop.vx = 0; drop.vy = 0; } // hold it still for the timing checks
|
||||
// standing on the drop, it must stay uncollectible for ~70% of the lockout
|
||||
const blockedFor = Math.floor(ctx.WEAPON_DROP_LOCKOUT * 0.7 / 0.016);
|
||||
for (let i = 0; i < blockedFor; i++) { p.x = drop.x; p.y = drop.y; ctx.updatePickups(0.016); }
|
||||
const stillBlocked = ctx.G.pickups.some(k => k.type === 'weapon') && p.weapon.id === 'repeater';
|
||||
check('dropped weapon stays un-pickable inside the lockout window', stillBlocked);
|
||||
// the remaining ~30% (plus margin) lets it be re-picked
|
||||
const collectFor = Math.ceil(ctx.WEAPON_DROP_LOCKOUT / 0.016) + 10;
|
||||
for (let i = 0; i < collectFor; i++) { p.x = drop.x; p.y = drop.y; ctx.updatePickups(0.016); }
|
||||
check('dropped weapon re-pickable after the lockout', p.weapon.id === 'cleaver');
|
||||
check('lockout constant is within the 2-3s request', ctx.WEAPON_DROP_LOCKOUT >= 2 && ctx.WEAPON_DROP_LOCKOUT <= 3);
|
||||
}
|
||||
|
||||
autoDraft = true; // later sections must not get stuck in the perk draft
|
||||
|
||||
console.log('== shield heart perk ==');
|
||||
|
||||
Reference in new issue
Block a user