public function getIndex() { // Get the list $list = Session::get('list', []); foreach ($list as $k => &$l) { // $l starts as the amount integer and we're transforming it to an array $l = ['amount' => $l, 'item' => Item::with(array('recipe' => function ($query) { $query->limit(1); }, 'name'))->find($k)]; if (count($l['item']->recipe) == 0) { unset($list[$k]); } } unset($l); $saved_link = []; if ($list) { foreach ($list as $id => $info) { $saved_link[] = $id . ',' . $info['amount']; } } $saved_link = implode(':', $saved_link); $job_list = ClassJob::get_name_abbr_list(); $active = 'list'; return view('pages.list', compact('active', 'list', 'saved_link', 'job_list')); }
public function getSearch(Request $request) { $input = $request->all(); $name = $input['name']; $min = $input['min'] ?: 1; $max = $input['max'] ?: 90; $class = $input['class'] ?: 'all'; $per_page = isset($input['per_page']) ? $input['per_page'] : 10; $sorting = $input['sorting'] ?: 'name_asc'; if (!in_array($per_page, array(10, 25, 50))) { $per_page = 10; } if (!is_numeric($min)) { $min = 1; } if (!is_numeric($max)) { $max = 90; } if ($min > $max) { list($max, $min) = [$min, $max]; } $job_list = ClassJob::get_name_abbr_list(); if ($class && $class != 'all') { $classjob = ClassJob::get_by_abbr($class); } $sorting = explode('_', $sorting); $order_by = 'name'; $sort = 'asc'; if (count($sorting) == 2) { // Only overwrite if need-be (i.e. don't test for "name" or "asc") if ($sorting[0] == 'level') { $order_by = $sorting[0]; } if ($sorting[1] == 'desc') { $sort = $sorting[1]; } } $query = Recipes::with('item', 'item.name')->select('*', 'recipes.id AS recipe_id', 'recipes.level AS level')->join('items AS i', 'i.id', '=', 'recipes.item_id')->join('translations AS t', 't.id', '=', 'i.name_' . Config::get('language')); $query->orderBy($order_by == 'name' ? 't.term' : 'recipes.' . $order_by, $sort); if ($name) { $query->whereHas('item', function ($query) use($name) { $query->whereHas('name', function ($query) use($name) { $query->where('term', 'like', '%' . $name . '%'); }); }); } if ($min && $max) { $query->whereBetween('recipes.level', [$min, $max]); } if (isset($classjob)) { $query->where('recipes.classjob_id', $classjob->id); } $list = $query->paginate($per_page); $crafting_list_ids = array_keys(Session::get('list', [])); view()->share(compact('list', 'per_page', 'crafting_list_ids')); $output = ['tbody' => view('recipes.results')->render(), 'tfoot' => view('recipes.results_footer')->render()]; return $output; }
public function getProfile($job = 'ALC', $start_level = 1) { $options = array_diff(explode(',', \Request::get('options', '')), ['']); $gear = Gear::profile($job, $start_level, 5, $options); $classjob = ClassJob::get_by_abbr($job); $stat_focus = Stat::gear_focus($job); $stat_focus_ids = Stat::get_ids($stat_focus, true); return view('gear.profile', compact('gear', 'classjob', 'stat_focus', 'stat_focus_ids', 'start_level', 'options')); }
public function getIndex() { $account = Session::get('account'); if (empty($account)) { return redirect('/account/login'); } $job_ids = Config::get('site.job_ids'); $crafting_job_list = ClassJob::with('name', 'en_abbr', 'en_name')->whereIn('id', $job_ids['crafting'])->get(); $gathering_job_list = ClassJob::with('name', 'en_abbr', 'en_name')->whereIn('id', $job_ids['gathering'])->get(); $melee_job_list = ClassJob::with('name', 'en_abbr', 'en_name')->whereIn('id', $job_ids['basic_melee'])->get(); $magic_job_list = ClassJob::with('name', 'en_abbr', 'en_name')->whereIn('id', $job_ids['basic_magic'])->get(); return view('account.index', compact('crafting_job_list', 'gathering_job_list', 'melee_job_list', 'magic_job_list')); }
/** * Gear Profile, An overview of all gear based on the parameters * @param string/integer $job A string or integer is accepted * @param integer $starting_level [description] * @param integer $level_range [description] * @param array $options [description] * @return array $equipment_list an array of equipment slots */ public static function profile($job = '', $starting_level = 1, $level_range = 1, $options = []) { // Get the job, depending on string or id $job = is_numeric($job) ? ClassJob::with('en_abbr')->find($job_id) : ClassJob::get_by_abbr($job); $job_abbr = $job->en_abbr->term; // Slot data $slots = Config::get('site.defined_slots'); // Stat data $stat_ids_to_focus = Stat::get_ids(Stat::gear_focus($job_abbr)); // Get all items $items = self::items($job->id, $starting_level - 10, $starting_level + $level_range, array_keys($slots), $stat_ids_to_focus, $options); // Sort those items into the appropriate buckets $equipment_list = self::organize($items, $job_abbr, $starting_level, $stat_ids_to_focus, $options); return $equipment_list; }
public function getIndex() { // All Quests $quest_records = QuestItem::with('classjob', 'classjob.en_abbr', 'item', 'item.name', 'item.recipe')->orderBy('classjob_id')->orderBy('level')->orderBy('item_id')->get(); $quests = array(); foreach ($quest_records as $quest) { if (!isset($quests[$quest->classjob->en_abbr->term])) { $quests[$quest->classjob->en_abbr->term] = array(); } if (empty($quest->item->recipe)) { var_dump($quest); exit; } foreach ($quest->item->recipe as $r) { if ($r->classjob_id == $quest->classjob_id) { $quest->recipe = $r; } } $quests[$quest->classjob->en_abbr->term][] = $quest; } $job_ids = array_merge(Config::get('site.job_ids.crafting'), Config::get('site.job_ids.gathering')); $job_list = ClassJob::with('name', 'en_abbr')->whereIn('id', $job_ids)->get(); return view('pages.quests', compact('quests', 'job_ids', 'job_list')); }
public function getList() { // All Jobs $job_list = ClassJob::get_name_abbr_list(); view()->share('job_list', $job_list); $include_quests = TRUE; if (!\Request::all()) { return redirect()->back(); } // Get Options $options = explode(':', array_keys(\Request::except('_token'))[0]); // Parse Options // Defaults $desired_job = isset($options[0]) ? $options[0] : 'CRP'; $start = isset($options[1]) ? $options[1] : 1; $end = isset($options[2]) ? $options[2] : 5; $self_sufficient = isset($options[3]) ? $options[3] : 1; $misc_items = isset($options[4]) ? $options[4] : 0; $component_items = isset($options[5]) ? $options[5] : 0; $special = isset($options[6]) ? $options[6] : 0; $item_ids = $item_amounts = array(); $top_level = TRUE; if ($desired_job == 'List') { $start = $end = null; $include_quests = FALSE; // Get the list $item_amounts = Session::get('list', array()); $item_ids = array_keys($item_amounts); if (empty($item_ids)) { return redirect('/list'); } view()->share(compact('item_ids', 'item_amounts')); $top_level = $item_amounts; } if ($desired_job == 'Item') { $item_id = $special; $start = $end = null; $include_quests = FALSE; // Get the list $item_amounts = array($item_id => 1); $item_ids = array_keys($item_amounts); if (empty($item_ids)) { return redirect('/list'); } $item_special = true; view()->share(compact('item_ids', 'item_amounts', 'item_special')); $top_level = $item_amounts; } if (!$item_ids) { // Jobs are capital $desired_job = strtoupper($desired_job); // Make sure it's a real job, jobs might be multiple $job = []; foreach (explode(',', $desired_job) as $ds) { $job[] = ClassJob::get_by_abbr($ds); } // If the job isn't real, error out if (!isset($job[0])) { // Check for DOL quests $quests = array(); foreach (array('MIN', 'BTN', 'FSH') as $job) { $job = ClassJob::get_by_abbr($job); $quests[$job] = QuestItem::where('classjob_id', $job->id)->orderBy('level')->with('item')->get(); } $error = true; return view('crafting', compact('error', 'quests')); } $job_ids = []; foreach ($job as $j) { $job_ids[] = $j->id; } $full_name_desired_job = false; if (count($job) == 1) { $job = $job[0]; $full_name_desired_job = $job->name->term; } // Starting maximum of 1 if ($start < 0) { $start = 1; } if ($start > $end) { $end = $start; } if ($end - $start > 9) { $end = $start + 9; } // Check for quests $quest_items = QuestItem::with('classjob', 'classjob.abbr')->whereBetween('level', array($start, $end))->whereIn('classjob_id', $job_ids)->orderBy('level')->with('item')->get(); view()->share(compact('job', 'start', 'end', 'quest_items', 'desired_job', 'full_name_desired_job')); } // Gather Recipes and Reagents $query = Recipes::with('name', 'classjob', 'classjob.name', 'classjob.abbr', 'item', 'item.name', 'item.quest', 'item.leve', 'item.vendors', 'item.beasts', 'item.clusters', 'item.clusters.classjob', 'item.clusters.classjob.abbr', 'reagents', 'reagents.vendors', 'reagents.beasts', 'reagents.clusters', 'reagents.clusters.classjob', 'reagents.clusters.classjob.abbr', 'reagents.recipe', 'reagents.recipe.name', 'reagents.recipe.item', 'reagents.recipe.item.name', 'reagents.recipe.item.vendors', 'reagents.recipe.item.beasts', 'reagents.recipe.item.clusters', 'reagents.recipe.item.clusters.classjob', 'reagents.recipe.item.clusters.classjob.abbr', 'reagents.recipe.classjob', 'reagents.recipe.classjob.abbr')->groupBy('recipes.item_id')->orderBy('rank'); if ($item_ids) { $query->whereIn('recipes.item_id', $item_ids); } else { $query->whereHas('classjob', function ($query) use($job_ids) { $query->whereIn('classjob.id', $job_ids); })->whereBetween('level', array($start, $end)); } $recipes = $query->get(); // Do we not want miscellaneous items? if ($misc_items == 0 && $desired_job != 'List') { foreach ($recipes as $key => $recipe) { // Remove any Furnishings, Dyes and "Other" // ItemCategory 14 == 'Furnishing', 15 == 'Dye', 16 == 'Miscellany' // Miscellany is special, we want to keep any Miscellany if it's in a range of UI // ItemUICategory 12 to 32 are Tools (Primary/Secondary), keep those // Technically this only solves a Secondary tool issue. Primary tools aren't part of 16/Miscellany if (in_array($recipe->item->itemcategory_id, [14, 15]) || $recipe->item->itemcategory_id == 16 && !in_array($recipe->item->itemuicategory_id, range(12, 32))) { unset($recipes[$key]); } } } // Do we not want component items? if ($component_items == 0 && $desired_job != 'List') { foreach ($recipes as $key => $recipe) { // Remove any Miscellany // ItemUICategory of 63, as that's "Other" if ($recipe->item->itemuicategory_id == 63) { unset($recipes[$key]); } } } // Fix the amount of the top level to be evenly divisible by the amount the recipe yields if (is_array($top_level)) { foreach ($recipes as $recipe) { $tl_item =& $top_level[$recipe->item_id]; // If they're not evently divisible if ($tl_item % $recipe->yields != 0) { // Make it so $tl_item = ceil($tl_item / $recipe->yields) * $recipe->yields; } } unset($tl_item); view()->share('item_amounts', $top_level); } $reagent_list = $this->_reagents($recipes, $self_sufficient, 1, $include_quests, $top_level); // Look through the list. Is there something we're already crafting? // Subtract what's being made from needed reagents. // Example, culinary 11 to 15, you need olive oil for Parsnip Salad (lvl 13) // But you make 3 olive oil at level 11. We don't want them crafting another olive oil. foreach ($recipes as $recipe) { if (!isset($reagent_list[$recipe->item_id])) { continue; } $reagent_list[$recipe->item_id]['both_list_warning'] = TRUE; $reagent_list[$recipe->item_id]['make_this_many'] += 1; } // Look through the reagent list, make sure the reagents are evently divisible by what they yield foreach ($reagent_list as &$reagent) { // If they're not evently divisible if ($reagent['make_this_many'] % $reagent['yields'] != 0) { // Make it so $reagent['make_this_many'] = ceil($reagent['make_this_many'] / $reagent['yields']) * $reagent['yields']; } } unset($reagent); // Let's sort them further, group them by.. // Gathered, Then by Level // Other (likely mob drops) // Crafted, Then by level // Bought, by price $sorted_reagent_list = ['Gathered' => [], 'Bought' => [], 'Other' => [], 'Pre-Requisite Crafting' => [], 'Crafting List' => []]; $gathering_class_abbreviations = ClassJob::get_abbr_list(Config::get('site.job_ids.gathering')); foreach ($reagent_list as $reagent) { $section = 'Other'; $level = 0; // Section if (in_array($reagent['self_sufficient'], $gathering_class_abbreviations)) { $section = 'Gathered'; $level = $reagent['item']->level; } elseif ($reagent['self_sufficient']) { $section = 'Pre-Requisite Crafting'; if (!isset($reagent['item']->recipe[0])) { dd($reagent['item']); } $level = $reagent['item']->recipe[0]->level; } elseif (count($reagent['item']->vendors)) { $section = 'Bought'; $level = $reagent['item']->min_price; } if (!isset($sorted_reagent_list[$section][$level])) { $sorted_reagent_list[$section][$level] = array(); } $sorted_reagent_list[$section][$level][$reagent['item']->id] = $reagent; ksort($sorted_reagent_list[$section][$level]); } foreach ($sorted_reagent_list as $section => $list) { ksort($sorted_reagent_list[$section]); } // Sort the pre-requisite crafting by rank // We don't need to sort them by level, just make sure it's in the proper structure // The keys don't matter either $prc =& $sorted_reagent_list['Pre-Requisite Crafting']; $new_prc = array('1' => array()); foreach ($prc as $vals) { foreach ($vals as $v) { $new_prc['1'][] = $v; } } // Sort them by rank first usort($new_prc['1'], function ($a, $b) { return $a['item']->rank - $b['item']->rank; }); // Then by classjob usort($new_prc['1'], function ($a, $b) { return $a['item']->recipe[0]->classjob_id - $b['item']->recipe[0]->classjob_id; }); $prc = $new_prc; $reagent_list = $sorted_reagent_list; return view('crafting.list', compact('recipes', 'reagent_list', 'self_sufficient', 'misc_items', 'component_items', 'include_quests')); }
public function getGathering($my_class = '', $supported_classes = '', $min_level = 0, $max_level = 0) { $supported_classes = explode(',', $supported_classes); $show_quests = in_array($my_class, $supported_classes); if (empty($supported_classes)) { exit('No supported class selected... Todo: real error'); } // TODO $all_classes = ClassJob::get_id_abbr_list(); foreach ($supported_classes as $k => $v) { if (in_array($v, array_keys($all_classes))) { $supported_classes[$k] = $all_classes[$v]; } else { unset($supported_classes[$k]); } } if (empty($supported_classes)) { exit('No supported class recognized...'); } // TODO $jobs = ClassJob::with('name')->whereIn('id', $supported_classes)->get(); foreach ($jobs as $k => $v) { $jobs[$k] = $v->name->term; } if ($my_class != 'BTL') { $job = ClassJob::get_by_abbr($my_class); } else { $job = $my_class; } if (empty($job)) { exit('No primary class recognized...'); } // TODO $top_query = $inner_query = $join = $where = $union = $having = ''; $parameters = []; \DB::statement('SET SESSION group_concat_max_len=16384'); if (in_array($my_class, array('MIN', 'BTN'))) { // Add Nodes $top_query .= "\n\t\t\t\t\t(\n\t\t\t\t\t\tSELECT\n\t\t\t\t\t\t\tCOUNT(*)\n\t\t\t\t\t\tFROM `cluster_items` AS `ci`\n\t\t\t\t\t\tJOIN `clusters` AS `c` ON `c`.`id` = `ci`.`cluster_id`\n\t\t\t\t\t\tWHERE `c`.`classjob_id` = ? AND `ci`.`item_id` = `x`.`item_id`\n\t\t\t\t\t) AS nodes,\n\t\t\t"; $parameters[] = $job->id; $having = "HAVING nodes > 0"; } else { // Battling or Fishing $join = "LEFT JOIN `cluster_items` AS `ci` ON `ci`.`item_id` = `i`.`id` " . 'LEFT JOIN `item_ui_category` AS `iuc` ON `iuc`.`id` = `i`.`itemuicategory_id` ' . 'LEFT JOIN `translations` AS `iuct` ON `iuct`.`id` = `iuc`.`name_en`'; // FSH where the item is "seafood" // BTL where the item is not "seafood" $where = "AND `iuct`.`term` " . ($my_class == 'BTL' ? '!' : '') . "= 'Seafood'"; $where .= " AND `ci`.`id` IS NULL"; } $parameters[] = $min_level; $parameters[] = $max_level; $parameters = array_merge($parameters, $supported_classes); if ($my_class != 'BTL') { $union = "\n\t\t\t\t\tUNION\n\n\t\t\t\t\tSELECT\n\t\t\t\t\t\t`i`.`id`, t.term AS name, `i`.level, `i`.`min_price`, qi.amount AS amount, \n\t\t\t\t\t\tqi.level AS quest_level, qi.quality AS quest_quality\n\t\t\t\t\tFROM quest_items AS qi\n\t\t\t\t\tJOIN items AS i ON i.id = qi.item_id\n\t\t\t\t\tJOIN classjob AS j ON j.id = qi.classjob_id\n\t\t\t\t\tJOIN translations AS t ON t.id = i.name_" . Config::get('language') . "\n\t\t\t\t\tWHERE j.id = ?\n\t\t\t\t\t\tAND qi.level BETWEEN ? AND ?\n\t\t\t"; $parameters[] = $job->id; $parameters[] = $min_level; $parameters[] = $max_level; } // TODO Caching $items = \DB::select("\n\t\t\tSELECT x.*,\n\t\t\t\t" . $top_query . "\n\t\t\t\t(\n\t\t\t\t\tSELECT COUNT(*)\n\t\t\t\t\tFROM `items_npcs_shops` AS `ins`\n\t\t\t\t\tWHERE `ins`.`item_id` = `x`.`item_id`\n\t\t\t\t) AS vendors, \n\t\t\t\t(\n\t\t\t\t\tSELECT COUNT(*)\n\t\t\t\t\tFROM `npcs_items` AS `ni`\n\t\t\t\t\tWHERE `ni`.`item_id` = `x`.`item_id`\n\t\t\t\t) AS beasts\n\t\t\tFROM (\n\t\t\t\tSELECT \n\t\t\t\t\t`i`.`id` AS `item_id`, t.term AS name, `i`.level, `i`.`min_price`, SUM(cj.amount) AS amount,\n\t\t\t\t\tNULL AS quest_level, NULL AS quest_quality\n\t\t\t\tFROM `careers` AS `c`\n\t\t\t\tJOIN `items` AS `i` ON `i`.`id` = `c`.`identifier`\n\t\t\t\tJOIN `career_classjob` AS `cj` ON `cj`.`career_id` = `c`.`id`\n\t\t\t\tJOIN translations AS t ON t.id = i.name_" . Config::get('language') . "\n\t\t\t\t" . $join . "\n\t\t\t\tWHERE\n\t\t\t\t\t`c`.`type` = 'item'\n\t\t\t\t\tAND `c`.`level` BETWEEN ? AND ?\n\t\t\t\t\tAND `cj`.`classjob_id` in (" . str_pad('', count($supported_classes) * 2 - 1, '?,') . ")\n\t\t\t\t\t" . $where . "\n\t\t\t\tGROUP BY `c`.`identifier`\n\n\t\t\t\t" . $union . "\n\t\t\t\t\n\t\t\t\tORDER BY `item_id` ASC\n\t\t\t) AS x\n\t\t\t" . $having, $parameters); if ($my_class != 'BTL') { $quest_items = []; // Rip out Quest Entries foreach ($items as $k => $result) { if ($result->quest_level != NULL) { $quest_items[] = $result; unset($items[$k]); } } // Put them back in, either merge or insert if ($show_quests) { foreach ($quest_items as $quest_item) { foreach ($items as $k => $result) { if ($quest_item->item_id == $result->item_id) { // Merge $original_amount = $result->amount; $quest_amount = $quest_item->amount; $items[$k] = $quest_item; $items[$k]->amount = $original_amount; $items[$k]->quest_amount = $quest_amount; continue 2; } } // If a match was found it would have continued // This means at this point we add it in straight up $quest_item->quest_amount = $quest_item->amount; $items[] = $quest_item; } } // Fishing doesn't have an ilvl... if ($my_class != 'FSH') { $sortable_items = []; foreach ($items as $row) { $sortable_items[$row->level][] = $row; } ksort($sortable_items); $items = []; foreach ($sortable_items as $rows) { foreach ($rows as $row) { $items[] = $row; } } unset($sortable_results); } } return view('career.items', compact('items', 'show_quests', 'jobs', 'job', 'min_level', 'max_level')); }
/** * The advanced form requests data via Ajax here * @param Request * @return View */ public function getPopulateAdvanced(Request $request) { $input = $request->all(); // Parse the Job IDs $selected_classes = $input['classes']; foreach (ClassJob::get_id_abbr_list(true) as $abbr => $id) { if (in_array($abbr, $selected_classes)) { $job_ids[] = $id; } } if (empty($job_ids)) { $job_ids[] = 1; } // All Leves $query = Leve::with(array('classjob', 'item', 'item.name', 'item.recipe', 'item.vendors'))->where('item_id', '>', 0)->orderBy('classjob_id')->orderBy('level')->orderBy('xp')->orderBy('gil'); // Job IDs $query->whereIn('classjob_id', $job_ids); // Level Range $min = $input['min_level']; $max = $input['max_level']; // Invert if needed if ($min > $max) { list($max, $min) = array($min, $max); } $query->whereBetween('level', array($min, $max)); // Triple Only if ($input['triple_only'] == 'true') { $query->where('triple', 1); } // Types $query->whereIn('type', $input['types']); // Text Searches if ($input['leve_name']) { $query->where('name', 'like', '%' . $input['leve_name'] . '%'); } $leves = $query->get(); $location_search = strtolower($input['leve_location']); $item_search = strtolower($input['leve_item']); $rewards = LeveReward::with('item')->whereBetween('level', array($min, $max))->whereIn('classjob_id', $job_ids)->get(); $leve_rewards = []; foreach ($leves as $k => $row) { if ($item_search && !preg_match('/' . $item_search . '/', strtolower($row->item->name->term))) { unset($leves[$k]); continue; } // TODO this can be moved into the query itself now, most likely if ($location_search) { if (!preg_match('/' . $location_search . '/', strtolower($row->location)) && !preg_match('/' . $location_search . '/', strtolower($row->major_location)) && !preg_match('/' . $location_search . '/', strtolower($row->minor_location))) { unset($leves[$k]); continue; } } foreach ($rewards as $reward) { if ($reward->classjob_id == $row->classjob_id && $reward->level == $row->level) { $leve_rewards[$row->id][] = $reward; } } } return view('levequests.rows', compact('leves', 'leve_rewards', 'input')); }
public function postLoad(Request $request) { $inputs = $request->all(); $job = $request['job']; $level = $request['level']; $craftable_only = $request['craftable_only']; $rewardable_too = $request['rewardable_too']; // All Jobs $job_list = ClassJob::get_name_abbr_list(); // Jobs are capital $desired_job = strtoupper($job); $job = ClassJob::get_by_abbr($desired_job); // What stats do the class like? $stat_ids_to_focus = Stat::get_ids(Stat::focus($job->abbr->term)); view()->share(compact('job_list', 'job', 'stat_ids_to_focus', 'level')); $equipment = Item::calculate($job->id, $level, 0, $craftable_only, $rewardable_too); return $this->getOutput($equipment); }