From bc28967023d7352bf49deac0faaa9a0abe137ae9 Mon Sep 17 00:00:00 2001 From: Andy Kernel <171799466+starswaitforus@users.noreply.github.com> Date: Wed, 28 Aug 2024 12:23:52 +0200 Subject: [PATCH] little refactoring --- server/src/Core/Point.php | 8 ++++++++ server/src/Core/World.php | 4 ++-- server/src/Event/DropEvent.php | 4 ++-- server/src/Event/Event.php | 8 +++----- server/src/Event/GrillEvent.php | 3 +-- server/src/Event/ThrowEvent.php | 4 ++-- server/src/Event/VolumetricEvent.php | 15 ++++++++++----- server/src/HitGeometry/HitBoxBack.php | 4 +++- server/src/HitGeometry/HitBoxChest.php | 5 ++++- server/src/HitGeometry/HitBoxHead.php | 4 +++- server/src/HitGeometry/HitBoxStomach.php | 4 +++- server/src/HitGeometry/SphereGroupHitBox.php | 4 ++-- server/src/HitGeometry/SphereHitBox.php | 12 +++++------- server/src/Interface/Flammable.php | 6 ------ server/src/Net/Client.php | 13 ++++--------- server/src/Net/Protocol.php | 8 ++++---- server/src/Net/Server.php | 2 +- server/src/Net/ServerSetting.php | 2 +- test/og/Unit/HitBoxTest.php | 9 ++------- www/assets/js/Game.js | 9 ++++++++- www/assets/js/Setting.js | 1 + www/playerGenerator.php | 9 +++++++-- 22 files changed, 76 insertions(+), 62 deletions(-) diff --git a/server/src/Core/Point.php b/server/src/Core/Point.php index 7762f86..7e5fe78 100644 --- a/server/src/Core/Point.php +++ b/server/src/Core/Point.php @@ -74,6 +74,14 @@ public function set(int $x, int $y, int $z): self return $this; } + public function setScalar(int $xyz): self + { + $this->x = $xyz; + $this->y = $xyz; + $this->z = $xyz; + return $this; + } + public function __toString(): string { return "Point({$this->x},{$this->y},{$this->z})"; diff --git a/server/src/Core/World.php b/server/src/Core/World.php index c03c884..b33c1b7 100644 --- a/server/src/Core/World.php +++ b/server/src/Core/World.php @@ -301,7 +301,7 @@ public function tryPickDropItems(Player $player): void public function dropItem(Player $player, Item $item): void { $dropEvent = new DropEvent($player, $item, $this); - $dropEvent->onLand(function (DropEvent $event): void { + $dropEvent->onFloorLand(function (DropEvent $event): void { $this->dropItems[] = $event->getDropItem(); }); $this->game->addDropEvent($dropEvent); @@ -631,7 +631,7 @@ public function isCollisionWithMolotov(Point $pos): bool } foreach ($molotov->parts as $flame) { - if ($flame->active && Collision::pointWithCylinder($pos, $flame->center, 3 * $flame->radius, $flame->height)) { + if ($flame->active && Collision::pointWithBoxBoundary($pos, $flame->boundaryMin, $flame->boundaryMax)) { return true; } } diff --git a/server/src/Event/DropEvent.php b/server/src/Event/DropEvent.php index b47c23b..4879ab4 100644 --- a/server/src/Event/DropEvent.php +++ b/server/src/Event/DropEvent.php @@ -34,14 +34,14 @@ public function __construct(private readonly Player $player, private readonly It $this->angleHorizontal = $player->getSight()->getRotationHorizontal(); $this->angleVertical = $player->getSight()->getRotationVertical(); $this->velocity = ($player->isMoving() || $player->isJumping()) ? 30.0 : 20.0; - $this->timeIncrement = 1 / Util::millisecondsToFrames(100); + $this->timeIncrement = 1 / $this->timeMsToTick(100); if (!$this->player->isAlive()) { $this->velocity = 7; $this->timeIncrement = 7; } } - public function onLand(Closure $callback): void + public function onFloorLand(Closure $callback): void { $this->onLand = $callback; } diff --git a/server/src/Event/Event.php b/server/src/Event/Event.php index 20cf521..f0f56db 100644 --- a/server/src/Event/Event.php +++ b/server/src/Event/Event.php @@ -15,7 +15,7 @@ abstract class Event implements NetSerializable abstract public function process(int $tick): void; - public function timeMsToTick(int $timeMs): int + public final function timeMsToTick(int $timeMs): int { return Util::millisecondsToFrames($timeMs); } @@ -26,7 +26,7 @@ public function reset(): void $this->onComplete = []; } - public final function runOnCompleteHooks(): void + protected final function runOnCompleteHooks(): void { foreach ($this->onComplete as $func) { call_user_func($func, $this); @@ -40,9 +40,7 @@ public function getCode(): int public function serialize(): array { - return [ - 'class' => get_class($this), - ]; + return []; } } diff --git a/server/src/Event/GrillEvent.php b/server/src/Event/GrillEvent.php index d42ec6d..15476c1 100644 --- a/server/src/Event/GrillEvent.php +++ b/server/src/Event/GrillEvent.php @@ -4,7 +4,6 @@ use cs\Core\Column; use cs\Core\Point; -use cs\Core\Util; use cs\Enum\SoundType; use cs\Interface\Flammable; @@ -18,7 +17,7 @@ final class GrillEvent extends VolumetricEvent protected function setup(): void { - $this->damageCoolDownTickCount = Util::millisecondsToFrames(self::DAMAGE_COOL_DOWN_TIME_MS); + $this->damageCoolDownTickCount = $this->timeMsToTick(self::DAMAGE_COOL_DOWN_TIME_MS); } protected function onProcess(int $tick): void diff --git a/server/src/Event/ThrowEvent.php b/server/src/Event/ThrowEvent.php index 200d13d..fb3764c 100644 --- a/server/src/Event/ThrowEvent.php +++ b/server/src/Event/ThrowEvent.php @@ -56,8 +56,8 @@ public function __construct( $this->floorCandidate = $origin->clone(); $this->ball = new BallCollider($this->world, $origin, $radius); $this->needsToLandOnFloor = !($this->item instanceof Flashbang || $this->item instanceof HighExplosive); - $this->timeIncrement = 1 / Util::millisecondsToFrames(150); // fixme some good value or velocity or gravity :) - $this->tickMax = $this->getTickId() + Util::millisecondsToFrames($this->needsToLandOnFloor ? 99999 : 1200); + $this->timeIncrement = 1 / $this->timeMsToTick(150); // fixme some good value or velocity or gravity :) + $this->tickMax = $this->getTickId() + $this->timeMsToTick($this->needsToLandOnFloor ? 99999 : 1200); } private function makeEvent(Point $point, SoundType $type): Event diff --git a/server/src/Event/VolumetricEvent.php b/server/src/Event/VolumetricEvent.php index 4ab30a0..d35ca34 100644 --- a/server/src/Event/VolumetricEvent.php +++ b/server/src/Event/VolumetricEvent.php @@ -8,7 +8,6 @@ use cs\Core\Player; use cs\Core\Point; use cs\Core\Sequence; -use cs\Core\Util; use cs\Core\World; use cs\Interface\ForOneRoundMax; use cs\Interface\Volumetric; @@ -54,8 +53,8 @@ public function __construct( $this->id = Sequence::next(); $this->partSize = $this->partRadius * 2 + 1; $this->startedTickId = $this->world->getTickId(); - $this->spawnTickCount = Util::millisecondsToFrames(20); - $this->maxTicksCount = Util::millisecondsToFrames($this->item->getMaxTimeMs()); + $this->spawnTickCount = $this->timeMsToTick(20); + $this->maxTicksCount = $this->timeMsToTick($this->item->getMaxTimeMs()); $partArea = ($this->partSize) ** 2; $this->spawnPartCount = (int)ceil($this->item->getSpawnAreaMetersSquared() * 100 / $partArea); @@ -121,7 +120,13 @@ public function process(int $tick): void private function expand(int $tick): void { - foreach ($this->loadParts() as $candidate) { + $candidates = $this->loadParts(); + if ($candidates === []) { + $this->lastPartSpawnTickId = $tick + $this->maxTicksCount; + return; + } + + foreach ($candidates as $candidate) { $this->boundaryMin->set( min($this->boundaryMin->x, $candidate->x - $this->partRadius), min($this->boundaryMin->y, $candidate->y - 0), @@ -133,9 +138,9 @@ private function expand(int $tick): void max($this->boundaryMax->z, $candidate->z + $this->partRadius), ); - $this->lastPartSpawnTickId = $tick; $this->parts[] = $this->expandPart($candidate); } + $this->lastPartSpawnTickId = $tick; } /** @return Point[] */ diff --git a/server/src/HitGeometry/HitBoxBack.php b/server/src/HitGeometry/HitBoxBack.php index b5b5fed..306dc1d 100644 --- a/server/src/HitGeometry/HitBoxBack.php +++ b/server/src/HitGeometry/HitBoxBack.php @@ -7,11 +7,13 @@ class HitBoxBack extends SphereGroupHitBox { + private Point $centerPoint; public function __construct() { + $this->centerPoint = new Point(); parent::__construct(function (Player $player): Point { - return (new Point())->addY($player->getHeadHeight()); + return $this->centerPoint->setScalar(0)->addY($player->getHeadHeight()); }); $this->createBackLeft(); diff --git a/server/src/HitGeometry/HitBoxChest.php b/server/src/HitGeometry/HitBoxChest.php index 4b3c952..2f6e08b 100644 --- a/server/src/HitGeometry/HitBoxChest.php +++ b/server/src/HitGeometry/HitBoxChest.php @@ -7,10 +7,13 @@ class HitBoxChest extends SphereGroupHitBox { + private Point $centerPoint; + public function __construct() { + $this->centerPoint = new Point(); parent::__construct(function (Player $player): Point { - return (new Point())->addY($player->getHeadHeight()); + return $this->centerPoint->setScalar(0)->addY($player->getHeadHeight()); }); $this->createChestLeft(); diff --git a/server/src/HitGeometry/HitBoxHead.php b/server/src/HitGeometry/HitBoxHead.php index cdf90a0..3f98f3a 100644 --- a/server/src/HitGeometry/HitBoxHead.php +++ b/server/src/HitGeometry/HitBoxHead.php @@ -7,11 +7,13 @@ class HitBoxHead extends SphereGroupHitBox { + private Point $centerPoint; public function __construct() { + $this->centerPoint = new Point(); parent::__construct(function (Player $player): Point { - return (new Point())->addY($player->getHeadHeight()); + return $this->centerPoint->setScalar(0)->addY($player->getHeadHeight()); }); $this->addHitBox(new Point(0, -8, 1), 8); diff --git a/server/src/HitGeometry/HitBoxStomach.php b/server/src/HitGeometry/HitBoxStomach.php index 4abbee3..bf05ab4 100644 --- a/server/src/HitGeometry/HitBoxStomach.php +++ b/server/src/HitGeometry/HitBoxStomach.php @@ -7,11 +7,13 @@ class HitBoxStomach extends SphereGroupHitBox { + private Point $centerPoint; public function __construct() { + $this->centerPoint = new Point(); parent::__construct(function (Player $player): Point { - return (new Point())->addY($player->getHeadHeight()); + return $this->centerPoint->setScalar(0)->addY($player->getHeadHeight()); }); $this->createFrontRight(); diff --git a/server/src/HitGeometry/SphereGroupHitBox.php b/server/src/HitGeometry/SphereGroupHitBox.php index a90ca28..7d87cbc 100644 --- a/server/src/HitGeometry/SphereGroupHitBox.php +++ b/server/src/HitGeometry/SphereGroupHitBox.php @@ -23,7 +23,7 @@ public function __construct(public readonly ?Closure $centerPointModifier = null public function intersect(Player $player, Point $point): bool { /** @var Point $modifier */ - $modifier = $this->centerPointModifier ? call_user_func($this->centerPointModifier, $player) : new Point(); + $modifier = $this->centerPointModifier ? call_user_func($this->centerPointModifier, $player) : null; foreach ($this->getParts($player) as $part) { $center = $part->calculateWorldCoordinate($player, $modifier); if (Collision::pointWithSphere($point, $center, $part->radius)) { @@ -36,7 +36,7 @@ public function intersect(Player $player, Point $point): bool public function addHitBox(Point $relativeCenter, int $radius): self { - $this->parts[] = new SphereHitBox($relativeCenter, $radius); + $this->parts[] = $this->createHitBox($relativeCenter, $radius); return $this; } diff --git a/server/src/HitGeometry/SphereHitBox.php b/server/src/HitGeometry/SphereHitBox.php index 2b7a17f..99a2bc7 100644 --- a/server/src/HitGeometry/SphereHitBox.php +++ b/server/src/HitGeometry/SphereHitBox.php @@ -25,19 +25,17 @@ public function intersect(Player $player, Point $point): bool return Collision::pointWithSphere($point, $center, $this->radius); } - public function calculateWorldCoordinate(Player $player, Point $centerModifier = new Point()): Point + public function calculateWorldCoordinate(Player $player, ?Point $centerModifier = null): Point { $angle = $player->getSight()->getRotationHorizontal(); - $center = $player->getPositionClone()->add($centerModifier); + $center = $player->getPositionClone(); + if ($centerModifier) { + $center->add($centerModifier); + } $point = $center->clone()->add($this->relativeCenter); [$x, $z] = Util::rotatePointY($angle, $point->x, $point->z, $center->x, $center->z); return $point->setX($x)->setZ($z); } - public function getRelativeCenter(): Point - { - return $this->relativeCenter; - } - } diff --git a/server/src/Interface/Flammable.php b/server/src/Interface/Flammable.php index 6d74053..45010d6 100644 --- a/server/src/Interface/Flammable.php +++ b/server/src/Interface/Flammable.php @@ -5,12 +5,6 @@ interface Flammable extends Volumetric { - public function getMaxAreaMetersSquared(): int; - - public function getSpawnAreaMetersSquared(): int; - - public function getMaxTimeMs(): int; - public function getBoundingRadius(): int; public function calculateDamage(bool $hasKevlar): int; diff --git a/server/src/Net/Client.php b/server/src/Net/Client.php index 789dada..1126d20 100644 --- a/server/src/Net/Client.php +++ b/server/src/Net/Client.php @@ -2,20 +2,15 @@ namespace cs\Net; -class Client +final class Client { public function __construct( - private PlayerControl $playerControl, - public readonly string $ip, - public readonly int $port + public readonly PlayerControl $playerControl, + public readonly string $ip, + public readonly int $port ) { } - public function getPlayerControl(): PlayerControl - { - return $this->playerControl; - } - } diff --git a/server/src/Net/Protocol.php b/server/src/Net/Protocol.php index 1414bc6..e71f975 100644 --- a/server/src/Net/Protocol.php +++ b/server/src/Net/Protocol.php @@ -8,7 +8,7 @@ abstract class Protocol { - /** @var array [methodName => maxCallCountPerTick] */ + /** @var array [methodName => maxCallCountPerTick] */ public const playerControlMethods = [ 'attack' => 1, 'attack2' => 1, @@ -29,7 +29,7 @@ abstract class Protocol 'walk' => 1, ]; - /** @var array [methodName => paramCount] */ + /** @var array [methodName => paramCount] */ public const playerControlMethodParamCount = [ 'attack' => 0, 'attack2' => 0, @@ -58,7 +58,7 @@ abstract class Protocol ], ]; - /** @var array [methodName => methodNumber] */ + /** @var array [methodName => methodNumber] */ public const playerMethodByName = [ 'attack' => 0, 'attack2' => 1, @@ -79,7 +79,7 @@ abstract class Protocol 'walk' => 18, ]; - /** @var array [methodNumber => methodName] */ + /** @var array [methodNumber => methodName] */ public const playerMethodByNumber = [ 0 => 'attack', 1 => 'attack2', diff --git a/server/src/Net/Server.php b/server/src/Net/Server.php index 73b8dad..678509d 100644 --- a/server/src/Net/Server.php +++ b/server/src/Net/Server.php @@ -246,7 +246,7 @@ private function playerCreate(int $playerId, bool $attackerSide): PlayerControl private function gameTick(int $tickId): ?GameOverEvent { foreach ($this->tickCommands as $playerId => $callback) { - call_user_func($callback, $this->clients[$playerId]->getPlayerControl()); + call_user_func($callback, $this->clients[$playerId]->playerControl); } $this->tickCommands = []; return $this->game->tick($tickId); diff --git a/server/src/Net/ServerSetting.php b/server/src/Net/ServerSetting.php index 594b231..6a56a8f 100644 --- a/server/src/Net/ServerSetting.php +++ b/server/src/Net/ServerSetting.php @@ -17,7 +17,7 @@ public function __construct( public readonly int $warmupWaitSec = 60, ) { - Util::$TICK_RATE = ($tickMs > 0 ? $tickMs : Util::$TICK_RATE); + Util::$TICK_RATE = ($tickMs > 0 ? $tickMs : Util::$TICK_RATE); // side effect $this->warmupWaitSecRemains = $this->warmupWaitSec; } diff --git a/test/og/Unit/HitBoxTest.php b/test/og/Unit/HitBoxTest.php index eb7cacc..b36f61a 100644 --- a/test/og/Unit/HitBoxTest.php +++ b/test/og/Unit/HitBoxTest.php @@ -56,19 +56,14 @@ public function testSphereHitBoxInvalidRadius(): void new SphereHitBox(new Point(), 0); $this->fail('Should throw'); } catch (GameException $ex) { + $this->assertStringContainsStringIgnoringCase('bigger than zero', $ex->getMessage()); } try { new SphereHitBox(new Point(), -2); $this->fail('Should throw'); } catch (GameException $ex) { + $this->assertStringContainsStringIgnoringCase('bigger than zero', $ex->getMessage()); } - - // Just grinding code coverage... - $point = new Point2D(1, 1); - $hit = new SphereHitBox(new Point($point->clone()->setY(-1)->addY(1)->setX(0)->x, 0), 2); - $point->setFrom(new Point2D()); - $this->assertTrue($hit->getRelativeCenter()->to2D('xz')->equals($point)); - $this->assertTrue($hit->getRelativeCenter()->to2D('xy')->equals($point)); } public function testSphereWorldPointCenter(): void diff --git a/www/assets/js/Game.js b/www/assets/js/Game.js index f3e90df..dba2208 100644 --- a/www/assets/js/Game.js +++ b/www/assets/js/Game.js @@ -375,7 +375,14 @@ export class Game { const range = this.#volumetrics[smokeId]['range'] const mesh = this.#volumetrics[smokeId]['mesh'] - this.#roundIntervalIds.push(setInterval(() => mesh.geometry.setDrawRange(0, mesh.geometry.drawRange.count - range), 50)) + const intervalId = setInterval(function() { + const newRange = mesh.geometry.drawRange.count - range + if (newRange <= 0) { + clearInterval(intervalId) + } + mesh.geometry.setDrawRange(0, newRange) + }, 50) + this.#roundIntervalIds.push(intervalId) } bombPlanted(timeMs, position) { diff --git a/www/assets/js/Setting.js b/www/assets/js/Setting.js index a6c1e54..9bf1cde 100644 --- a/www/assets/js/Setting.js +++ b/www/assets/js/Setting.js @@ -54,6 +54,7 @@ export class Setting { 'KeyB': Action.BUY_MENU, 'Tab': Action.SCORE_BOARD, 'Backquote': Action.GAME_MENU, + 'IntlBackslash': Action.GAME_MENU, 'Enter': Action.CLEAR_DECALS, 'CapsLock': Action.CLEAR_DECALS, 'ArrowLeft': `buy ${BuyMenuItem.RIFLE_AK},${BuyMenuItem.RIFLE_M4A4}`, diff --git a/www/playerGenerator.php b/www/playerGenerator.php index a43b35e..478d1b5 100644 --- a/www/playerGenerator.php +++ b/www/playerGenerator.php @@ -192,11 +192,16 @@ function animate() { const slots = JSON.parse(slotsJson); const belt = player.getObjectByName('belt') belt.children.forEach(function (slot) { - slot.add(modelRepository.getModelForItem(slots[slot.name.replace('slot-', '')])) + let item = slots[slot.name.replace('slot-', '')] + if (item) { + slot.add(modelRepository.getModelForItem(item)) + } }) - //let handItem = modelRepository.getModelForItem(slots[value ?>]) let handItem = modelRepository.getModelForItem(slots[]) + if (false) { + handItem = modelRepository.getModelForItem(slots[value ?>]) + } player.getObjectByName('hand').add(handItem)