private function doFaceShot(Character $char, $img) { if (!$char->isCropFaceShot()) { // nothing do to, image already in correct format return $img; } $png = imagecreatefromstring($img); $w = imagesx($png); $h = imagesy($png); // create new WxW image for face $out = imagecreatetruecolor($w, $w); $bg = imagecolorallocatealpha($out, 0, 0, 0, 127); imagefill($out, 0, 0, $bg); imagesavealpha($out, true); $top = max(0, $h / 2 - $w / 2); imagecopyresampled($out, $png, 0, 0, 0, $top, $w, $w, $w, $w); ob_start(); imagepng($out, null, 9); $result = ob_get_clean(); imagedestroy($png); imagedestroy($out); return $result; }
private function doFaceShot(Character $char, $img) { switch ($char->getRace()) { case TPeople::FYROS: $crop = [0 => [143, 157], 1 => [149, 180]]; break; case TPeople::TRYKER: $crop = [0 => [143, 191], 1 => [148, 207]]; break; case TPeople::MATIS: $crop = [0 => [144, 138], 1 => [148, 170]]; break; case TPeople::ZORAI: $crop = [0 => [143, 109], 1 => [149, 122]]; break; default: // should not reach here return $img; } $gender = $char->getGender(); list($cx, $cy) = $crop[$gender]; $x = $cx - 50; $y = $cy - 50; $w = 100; $h = 100; if ($char->isCropFaceShot()) { // WxW box $out = imagecreatetruecolor($this->width, $this->width); $dstw = $this->width; $dsth = $this->width; } else { // portrait $out = imagecreatetruecolor($this->width, $this->height); $dstw = $this->width; $dsth = $this->height; $y -= $h / 2; $h += $h; } $bg = imagecolorallocatealpha($out, 0, 0, 0, 127); imagefill($out, 0, 0, $bg); imagesavealpha($out, true); imagecopyresampled($out, $img, 0, 0, $x, $y, $dstw, $dsth, $w, $h); imagedestroy($img); return $out; }
/** * @covers Character::setSlot */ public function testSetSlot() { $expected = '03bf60bad9e50d4a7b064860084746d2055de6a7'; $this->character->setSlot(EVisualSlot::ARMS_SLOT, 1, 1); $this->assertEquals($expected, $this->character->getHash()); }
/** * Parse input for character data * * @param array $args * * @return \Rrs\Character */ public function create(array $args) { if (empty($this->raceStats)) { // automatically load from Resources directory if needed $this->loadResources(__DIR__ . '/Resources'); } if (isset($args['vpa']) && isset($args['vpb']) && isset($args['vpc'])) { // decode vpx values into $args $args = $this->decodeVisualProps($args); } $args = array_merge(['race' => 'fy', 'gender' => 'f', 'age' => 0, 'dir' => 0, 'zoom' => 'body', 'tattoo' => 0, 'eyes' => 0, 'morph' => '3,3,3,3,3', 'gabarit' => '7,7,7,7,7'], $args); $char = new Character(); $race = $this->normalizeRace($args['race']); $char->setRace($race); $age = max(0, min(2, $args['age'])); $char->setAge($age); // allow character rotation on 45degree increments $dir = (int) $args['dir']; $char->setDirection(floor($dir / 45) * 45); $char->setAngle(0); $isPortrait = $args['zoom'] === 'portrait'; $isHeadShot = $args['zoom'] === 'face' || $isPortrait; $char->setFaceShot($isHeadShot, !$isPortrait); // FIXME: allow to set background? //$bgColor = isset($args['bg']) ? $args['bg'] : false; $char->setBackground(0, 0, 0, 0); $gender = EGender::fromValue($args['gender']); if ($gender === false) { $gender = EGender::FEMALE; } $char->setGender($gender); // setup race default armor / haircut $defaults = $this->raceStats->getRaceItems($race, $gender); foreach ($defaults as $slot => $sheetid) { $index = ryzom_vs_index($slot, $sheetid); $char->setSlot($slot, $index); } $tattoo = (int) $args['tattoo']; $eyes = (int) $args['eyes']; $char->setSlot(EVisualSlot::FACE_SLOT, $tattoo, $eyes); $morph = explode(',', $args['morph']); $char->setMorph($morph); $gabarit = explode(',', $args['gabarit']); $char->setGabarit($gabarit); // armor, process haircut first, so that helmet can override it $keys = array('hair' => EVisualSlot::HEAD_SLOT, 'arms' => EVisualSlot::ARMS_SLOT, 'legs' => EVisualSlot::LEGS_SLOT, 'hands' => EVisualSlot::HANDS_SLOT, 'feet' => EVisualSlot::FEET_SLOT, 'chest' => EVisualSlot::CHEST_SLOT, 'head' => EVisualSlot::HEAD_SLOT, 'handr' => EVisualSlot::RIGHT_HAND_SLOT, 'handl' => EVisualSlot::LEFT_HAND_SLOT); foreach ($keys as $k => $slot) { if (!isset($args[$k])) { continue; } // <sheet>/<color> $pairs = explode('/', $args[$k]); if (!isset($pairs[1])) { // FIXME: 1 == beige ? $pairs[1] = 1; } else { $pairs[1] = (int) $pairs[1]; } if ($k == 'hair') { $index = $this->verifyHaircutSlotIndex($race, $gender, $pairs[0]); } else { $index = $this->lookupItemSlotIndex($slot, $pairs[0]); } if ($index !== false) { // item lookup was success $char->setSlot($slot, $index, $pairs[1]); } } return $char; }