예제 #1
0
 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;
 }
예제 #2
0
 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;
 }
예제 #3
0
 /**
  * @covers Character::setSlot
  */
 public function testSetSlot()
 {
     $expected = '03bf60bad9e50d4a7b064860084746d2055de6a7';
     $this->character->setSlot(EVisualSlot::ARMS_SLOT, 1, 1);
     $this->assertEquals($expected, $this->character->getHash());
 }
예제 #4
0
 /**
  * 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;
 }