public function spawnStaticEntities() { $count = 0; foreach ($this->map->staticEntities as $tid => $kindName) { $kind = Types::getKindFromString($kindName); $pos = $this->map->titleIndexToGridPosition($tid); if (Types::isNpc($kind)) { $this->addNpc($kind, $pos['x'] + 1, $pos['y']); } if (Types::isMob($kind)) { $mob = new Mob('7' . $kind . $count++, $kind, $pos['x'] + 1, $pos['y']); $self = $this; $mob->onRespawn(function () use($mob, $self) { $mob->isDead = false; $self->addMob($mob); if (!empty($mob->area) && $mob->area instanceof ChestArea) { $mob->area->addToArea($mob); } }); // @todo bind $mob->onMove(array($self, 'onMobMoveCallback')); $this->addMob($mob); $this->tryAddingMobToChestArea($mob); } if (Types::isItem($kind)) { $this->addStaticItem($this->createItem($kind, $pos['x'] + 1, $pos['y'])); } } }
public function onClientMessage($connection, $data) { $message = json_decode($data, true); $action = $message[0]; if (!$this->hasEnteredGame && $action !== TYPES_MESSAGES_HELLO) { $this->connection->close("Invalid handshake message: " . $data); return; } $this->resetTimeout(); if ($action === TYPES_MESSAGES_HELLO) { $name = $message[1]; $this->name = $name === "" ? "lorem ipsum" : $name; $this->kind = TYPES_ENTITIES_WARRIOR; $this->equipArmor($message[2]); $this->equipWeapon($message[3]); $this->orientation = Utils::randomOrientation(); $this->updateHitPoints(); $this->updatePosition(); $this->server->addPlayer($this); call_user_func($this->server->enterCallback, $this); $this->connection->send(json_encode(array(TYPES_MESSAGES_WELCOME, $this->id, $this->name, $this->x, $this->y, $this->hitPoints))); $this->hasEnteredGame = true; $this->isDead = false; } elseif ($action == TYPES_MESSAGES_WHO) { array_shift($message); $this->server->pushSpawnsToPlayer($this, $message); } else { if ($action === TYPES_MESSAGES_ZONE) { call_user_func($this->zoneCallback); } else { if ($action == TYPES_MESSAGES_CHAT) { $msg = trim($message[1]); // Sanitized messages may become empty. No need to broadcast empty chat messages. if ($msg) { $this->broadcastToZone(new Messages\Chat($this, $msg), false); } } else { if ($action == TYPES_MESSAGES_MOVE) { if ($this->moveCallback) { $x = $message[1]; $y = $message[2]; if ($this->server->isValidPosition($x, $y)) { $this->setPosition($x, $y); $this->clearTarget(); $this->broadcast(new Messages\Move($this)); call_user_func($this->moveCallback, $this->x, $this->y); } } } else { if ($action == TYPES_MESSAGES_LOOTMOVE) { if ($this->lootmoveCallback) { $this->setPosition($message[1], $message[2]); $item = $this->server->getEntityById($message[3]); if ($item) { $this->clearTarget(); $this->broadcast(new Messages\LootMove($this, $item)); call_user_func($this->lootmoveCallback, $this->x, $this->y); } } } else { if ($action == TYPES_MESSAGES_AGGRO) { if ($this->moveCallback) { $this->server->handleMobHate($message[1], $this->id, 5); } } else { if ($action == TYPES_MESSAGES_ATTACK) { $mob = $this->server->getEntityById($message[1]); if ($mob) { $this->setTarget($mob); $this->server->broadcastAttacker($this); } } else { if ($action == TYPES_MESSAGES_HIT) { $mob = $this->server->getEntityById($message[1]); if ($mob) { $dmg = Formulas::dmg($this->weaponLevel, $mob->armorLevel); if ($dmg > 0 && is_callable(array($mob, 'receiveDamage'))) { $mob->receiveDamage($dmg, $this->id); $this->server->handleMobHate($mob->id, $this->id, $dmg); $this->server->handleHurtEntity($mob, $this, $dmg); } } } else { if ($action == TYPES_MESSAGES_HURT) { $mob = $this->server->getEntityById($message[1]); if ($mob && $this->hitPoints > 0) { $this->hitPoints -= Formulas::dmg($mob->weaponLevel, $this->armorLevel); $this->server->handleHurtEntity($this); if ($this->hitPoints <= 0) { $this->isDead = true; if (!empty($this->firepotionTimeout)) { Timer::del($this->firepotionTimeout); $this->firepotionTimeout = 0; } } } } else { if ($action == TYPES_MESSAGES_LOOT) { $item = $this->server->getEntityById($message[1]); if ($item) { $kind = $item->kind; if (Types::isItem($kind)) { $this->broadcast($item->despawn()); $this->server->removeEntity($item); if ($kind == TYPES_ENTITIES_FIREPOTION) { $this->updateHitPoints(); $this->broadcast($this->equip(TYPES_ENTITIES_FIREFOX)); $this->firepotionTimeout = Timer::add(15, array($this, 'firepotionTimeoutCallback'), array(), false); $hitpoints = new Messages\HitPoints($this->maxHitPoints); $data = $hitpoints->serialize(); $this->connection->send(json_encode($data)); } else { if (Types::isHealingItem($kind)) { $amount = 0; switch ($kind) { case TYPES_ENTITIES_FLASK: $amount = 40; break; case TYPES_ENTITIES_BURGER: $amount = 100; break; } if (!$this->hasFullHealth()) { $this->regenHealthBy($amount); $this->server->pushToPlayer($this, $this->health()); } } else { if (Types::isArmor($kind) || Types::isWeapon($kind)) { $this->equipItem($item); $this->broadcast($this->equip($kind)); } } } } } } else { if ($action == TYPES_MESSAGES_TELEPORT) { $x = $message[1]; $y = $message[2]; if ($this->server->isValidPosition($x, $y)) { $this->setPosition($x, $y); $this->clearTarget(); $this->broadcast(new Messages\Teleport($this)); $this->server->handlePlayerVanish($this); $this->server->pushRelevantEntityListTo($this); } } else { if ($action == TYPES_MESSAGES_OPEN) { $chest = $this->server->getEntityById($message[1]); if ($chest && $chest instanceof Chest) { $this->server->handleOpenedChest($chest, $this); } } else { if ($action == TYPES_MESSAGES_CHECK) { $checkpoint = $this->server->map->getCheckpoint($message[1]); if ($checkpoint) { $this->lastCheckpoint = $checkpoint; } } else { if (isset($this->messageCallback)) { call_user_func($this->messageCallback, $message); } } } } } } } } } } } } } } }