mirror of
https://github.com/HerculesWS/Hercules
synced 2026-08-15 12:23:13 -04:00
1202 lines
50 KiB
PHP
1202 lines
50 KiB
PHP
<?php
|
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* _ _ _
|
|
* | | | | | |
|
|
* | |_| | ___ _ __ ___ _ _| | ___ ___
|
|
* | _ |/ _ \ '__/ __| | | | |/ _ \/ __|
|
|
* | | | | __/ | | (__| |_| | | __/\__ \
|
|
* \_| |_/\___|_| \___|\__,_|_|\___||___/
|
|
*
|
|
* * * * * * * * * * * * * * License * * * * * * * * * * * * * * * * * * * * * *
|
|
* This file is part of Hercules.
|
|
* http://herc.ws - http://github.com/HerculesWS/Hercules
|
|
*
|
|
* Copyright (C) 2016-2026 Hercules Dev Team
|
|
* Copyright (C) 2016 Smokexyz
|
|
*
|
|
* Hercules is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* Credits : Smokexyz */
|
|
|
|
// Credits before anything else.
|
|
printcredits();
|
|
|
|
if(!isset($argv[1]))
|
|
gethelp();
|
|
|
|
function issetarg($arg) {
|
|
global $argv;
|
|
for($i=1; $i<sizeof($argv); $i++) {
|
|
if(strncmp($argv[$i],$arg,strlen($arg)) == 0)
|
|
return $i;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
$renewal = (issetarg("-re") || issetarg("--renewal"));
|
|
$prere = (issetarg("-pre-re") || issetarg("--pre-renewal"));
|
|
$constants = (!issetarg("-itid") && !issetarg("--use-itemid"));
|
|
$help = (issetarg("-h") || issetarg("--help"));
|
|
$directory = function() use($argv) {
|
|
$arg = issetarg("--directory")?issetarg("--directory"):(issetarg("-dir")?issetarg("-dir"):0);
|
|
if ($arg) {
|
|
$part = explode("=", $argv[$arg]);
|
|
if(!isset($part[1])) {
|
|
die("A directory path was not provided!\n");
|
|
} else if(!is_dir($part[1])) {
|
|
die("The given directory ".$part[1]." doesn't exist.\n");
|
|
} else {
|
|
return $part[1];
|
|
}
|
|
}
|
|
};
|
|
|
|
$dir = $directory();
|
|
|
|
if ($dir) {
|
|
print "Read/Write Directory has been set to '".$dir."'\n";
|
|
print "Please ensure all skill_db TXT files are placed in this path.\n";
|
|
print "Please also provide the correct version of the database (re/pre-re).\n";
|
|
define('DIRPATH', $dir);
|
|
}
|
|
|
|
$debug = (issetarg("-dbg") || issetarg("--with-debug"));
|
|
|
|
if ($debug) {
|
|
print "\033[0mDebug Mode Enabled.\n";
|
|
$t_init = microtime_float();
|
|
}
|
|
|
|
if($help || (!$renewal && !$prere) || ($renewal && $prere)) {
|
|
gethelp();
|
|
}
|
|
|
|
if ($renewal) {
|
|
print "Renewal enabled.\n";
|
|
print "skill_db.txt and associated files (cast, nocastdex, require & unit) will be converted.\n";
|
|
if(!defined('DIRPATH'))
|
|
define('DIRPATH', '../db/re/');
|
|
define('RENEWAL', true);
|
|
} else if ($prere) {
|
|
print "Pre-Renewal enabled.\n";
|
|
print "skill_db.txt and associated files (cast, nocastdex, require & unit) will be converted.\n";
|
|
if(!defined('DIRPATH'))
|
|
define('DIRPATH', '../db/pre-re/');
|
|
}
|
|
|
|
// check for existence of files.
|
|
|
|
$file_check = [
|
|
DIRPATH."skill_require_db.txt",
|
|
DIRPATH."skill_cast_db.txt",
|
|
DIRPATH."skill_castnodex_db.txt",
|
|
DIRPATH."skill_unit_db.txt",
|
|
DIRPATH."skill_db.txt"
|
|
];
|
|
|
|
if($constants) array_push($file_check, DIRPATH."item_db.conf");
|
|
|
|
foreach($file_check as $file) {
|
|
if(file_exists($file))
|
|
print $file." - Found\n";
|
|
else
|
|
die($file." - Not Found!\n");
|
|
}
|
|
|
|
if ($constants) {
|
|
print "Using of Item Constants : enabled\n";
|
|
} else {
|
|
print "Using of Item Constants : disabled.\n";
|
|
}
|
|
|
|
/* Begin the Loading of Files */
|
|
|
|
$i=0;
|
|
$file="skill_require_db.txt";
|
|
$requiredb = fopen(DIRPATH.$file, "r") or die("Unable to open '".DIRPATH.$file."'.\n");
|
|
print "Reading '".DIRPATH.$file."' ...\n";
|
|
while(!feof($requiredb))
|
|
{
|
|
$line = fgets($requiredb);
|
|
if(substr($line, 0, 2) == "//" || strlen($line) < 10) continue;
|
|
$line = strstr(preg_replace('/\s+/','',$line), "//", true);
|
|
$arr = explode(",", $line);
|
|
if(!isset($arr[0])) continue;
|
|
$skreq['ID'][$i] = $arr[0];
|
|
$skreq['HPCost'][$i] = $arr[1];
|
|
$skreq['MaxHPTrigger'][$i] = $arr[2];
|
|
$skreq['SPCost'][$i] = $arr[3];
|
|
$skreq['HPRateCost'][$i] = $arr[4];
|
|
$skreq['SPRateCost'][$i] = $arr[5];
|
|
$skreq['ZenyCost'][$i] = $arr[6];
|
|
$skreq['Weapons'][$i] = $arr[7];
|
|
$skreq['AmmoTypes'][$i] = $arr[8];
|
|
$skreq['AmmoAmount'][$i] = $arr[9];
|
|
$skreq['State'][$i] = $arr[10];
|
|
$skreq['SpiritSphere'][$i] = $arr[11];
|
|
$k=0;
|
|
for($j=12; $j<=31; $j+=2) {
|
|
$skreqit['ItemId'][$i][$k] = isset($arr[$j])?$arr[$j]:0;
|
|
$skreqit['Amount'][$i][$k] = isset($arr[$j+1])?$arr[$j+1]:0;
|
|
$k++;
|
|
}
|
|
$i++;
|
|
}
|
|
if ($debug) {
|
|
print "[Debug] Read require_db Memory: ".print_mem()."\n";
|
|
}
|
|
fclose($requiredb);
|
|
|
|
$file="skill_cast_db.txt";
|
|
$skillcastdb = fopen(DIRPATH.$file, "r") or die("Unable to open '".DIRPATH.$file."'.\n");
|
|
print "Reading '".DIRPATH.$file."' ...\n";
|
|
$i=0;
|
|
while(!feof($skillcastdb))
|
|
{
|
|
$line = fgets($skillcastdb);
|
|
if (substr($line, 0, 2) == "//" || strlen($line) < 10) continue;
|
|
$arr = explode(",",$line);
|
|
if (!isset($arr[0])) continue;
|
|
$skcast["ID"][$i] = $arr[0]; // SkillCastDBId
|
|
$skcast["casttime"][$i] = $arr[1];
|
|
$skcast["actdelay"][$i] = $arr[2];
|
|
$skcast["walkdelay"][$i] = $arr[3];
|
|
$skcast["data1"][$i] = $arr[4];
|
|
$skcast["data2"][$i] = $arr[5];
|
|
$skcast["cooldown"][$i] = $arr[6];
|
|
if(defined('RENEWAL')) $skcast["fixedcast"][$i] = $arr[7];
|
|
|
|
$i++;
|
|
}
|
|
if($debug) {
|
|
print "[Debug] Read cast_db Memory: ".print_mem()."\n";
|
|
}
|
|
fclose($skillcastdb);
|
|
|
|
$file="skill_castnodex_db.txt";
|
|
$castnodex = fopen(DIRPATH.$file, "r") or die("Unable to open '".DIRPATH.$file."'.\n");
|
|
print "Reading '".DIRPATH.$file."' ...\n";
|
|
$i=0;
|
|
while(!feof($castnodex))
|
|
{
|
|
$line = fgets($castnodex);
|
|
if(substr($line, 0, 2) == "//" || strlen($line) <= 2) continue;
|
|
$line = strstr(preg_replace('/\s+/','',$line), "//", true);
|
|
$arr = explode(",",$line);
|
|
$sknodex["ID"][$i] = $arr[0];
|
|
$sknodex["cast"][$i] = isset($arr[1])?$arr[1]:0;
|
|
$sknodex["delay"][$i] = isset($arr[2])?$arr[2]:0;
|
|
$i++;
|
|
}
|
|
if($debug) {
|
|
print "[Debug] Read cast_nodex Memory: ".print_mem()."\n";
|
|
}
|
|
fclose($castnodex);
|
|
|
|
/***
|
|
* Read item_db.conf to gather aegis item name informations.
|
|
*/
|
|
if ($constants) {
|
|
$itemdb[] = array();
|
|
|
|
$file = "item_db.conf";
|
|
if(file_exists(DIRPATH.$file)) {
|
|
$itemconf = fopen(DIRPATH.$file, "r") or die ("Unable to open '".DIRPATH.$file."'.\n");
|
|
print "Reading '".DIRPATH.$file."' ...\n";
|
|
|
|
$started = false;
|
|
$i=0;
|
|
while(!feof($itemconf)) {
|
|
$line = fgets($itemconf);
|
|
$line = trim($line);
|
|
if(strcmp($line,"{\n"))
|
|
$started = true;
|
|
else if (strcmp($line,"},\n"))
|
|
$started = false;
|
|
//echo str_replace(" ","",$line)."\n";
|
|
|
|
if($started == true) {
|
|
$p = explode(":", $line);
|
|
if(isset($p[0])) {
|
|
if($p[0] == "Id") {
|
|
//echo $p[0]." ".(isset($p[1])?$p[1]:NULL)."\n";
|
|
$itemdb['ID'][$i] = intval($p[1]);
|
|
}
|
|
if($p[0] == "AegisName") {
|
|
//echo $p[0]." ".(isset($p[1])?str_replace("\"","",$p[1]):NULL)."\n";
|
|
$itemdb['name'][$i] = str_replace("\"","",$p[1]);
|
|
$i++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if($debug) {
|
|
print "[Debug] Read item_db Memory: ".print_mem()."\n";
|
|
}
|
|
fclose($itemconf);
|
|
} else {
|
|
print "Unable to open '".DIRPATH.$file."'... defaulting to using Item ID's instead of Constants.\n";
|
|
$constants = false;
|
|
}
|
|
}
|
|
|
|
/* * *
|
|
* Bring forth the contents of skill_unit_db.txt and store them.
|
|
*/
|
|
$i=0;
|
|
$file="skill_unit_db.txt";
|
|
$unitdb = fopen(DIRPATH.$file, "r") or die("Unable to open '".DIRPATH.$file."'.\n");
|
|
print "Reading '".DIRPATH.$file."' ...\n";
|
|
while(!feof($unitdb)) {
|
|
$line = fgets($unitdb);
|
|
if(substr($line, 0, 2) == "//" || strlen($line) < 10) continue;
|
|
$line = strstr(preg_replace('/\s+/','',$line), "//", true);
|
|
$arr = explode(",",$line);
|
|
$skunit['ID'][$i] = $arr[0];
|
|
$skunit['UnitID'][$i] = $arr[1];
|
|
$skunit['UnitID2'][$i] = $arr[2];
|
|
$skunit['Layout'][$i] = $arr[3];
|
|
$skunit['Range'][$i] = $arr[4];
|
|
$skunit['Interval'][$i] = $arr[5];
|
|
$skunit['Target'][$i] = $arr[6];
|
|
$skunit['Flag'][$i] = hexdec($arr[7]);
|
|
$i++;
|
|
}
|
|
if($debug) {
|
|
print "[Debug] Read unit_db Memory: ".print_mem()."\n";
|
|
}
|
|
fclose($unitdb);
|
|
|
|
$putsk = ""; // initialize variable for file_put_contents.
|
|
// Publish all comments
|
|
$putsk .= getcomments((defined('RENEWAL')?true:false));
|
|
|
|
$putsk .= "skill_db: (\n";
|
|
// Get Main Skilldb File
|
|
$file="skill_db.txt";
|
|
$skmain = fopen(DIRPATH.$file, "r") or die("Unable to open '".DIRPATH.$file."'.\n");
|
|
print "Reading '".DIRPATH.$file."' ...\n";
|
|
$linecount = 0;
|
|
|
|
// Get Number of entries
|
|
while(!feof($skmain)) {
|
|
$line = fgets($skmain);
|
|
if(substr($line, 0, 2) == "//" || strlen($line) < 10) continue;
|
|
$linecount++;
|
|
}
|
|
if($debug) {
|
|
print "[Debug] Read skill_db Memory: ".print_mem()."\n";
|
|
}
|
|
fclose($skmain);
|
|
print $linecount." entries found in skill_db.txt.\n";
|
|
|
|
$i=0;
|
|
$skmain = fopen(DIRPATH.$file, "r") or die("Unable to open '".DIRPATH.$file."'.\n");
|
|
// Begin converting process.
|
|
$max_level = 10;
|
|
$max_items = 10;
|
|
while(!feof($skmain)) {
|
|
$line = fgets($skmain);
|
|
if(substr($line, 0, 2) == "//" || strlen($line) < 10) continue;
|
|
$arr = explode(",", $line);
|
|
// id,range,hit,inf,element,nk,splash,max,list_num,castcancel,cast_defence_rate,inf2,maxcount,skill_type,blow_count,name,description
|
|
$id = $arr[0];
|
|
$range = $arr[1];
|
|
$hit = $arr[2];
|
|
$inf = $arr[3];
|
|
$element = $arr[4];
|
|
$nk = $arr[5];
|
|
$splash = $arr[6];
|
|
$max = $arr[7];
|
|
$max = ($max < 1) ? 1 : $max;
|
|
$list_num = $arr[8];
|
|
$castcancel = $arr[9];
|
|
$cast_defence_rate = $arr[10];
|
|
$inf2 = $arr[11];
|
|
$maxcount = $arr[12];
|
|
$skill_type = $arr[13];
|
|
$blow_count = $arr[14];
|
|
$name = $arr[15];
|
|
if(strlen(substr($arr[16], 0, strpos($arr[16], "//"))))
|
|
$description = substr($arr[16], 0, strpos($arr[16], "//"));
|
|
else
|
|
$description = $arr[16];
|
|
|
|
$putsk .= "{\n".
|
|
"\tId: ".$id."\n".
|
|
"\tName: \"".trim($name)."\"\n".
|
|
"\tDescription: \"".trim($description)."\"\n".
|
|
"\tMaxLevel: ".$max."\n";
|
|
if($range) $putsk .= "\tRange: ".leveled_guessfill($range, $max_level, $id)."\n";
|
|
if($hit==8) $putsk .= "\tHit: \"BDT_MULTIHIT\"\n";
|
|
else if($hit==6) $putsk .= "\tHit: \"BDT_SKILL\"\n";
|
|
if($inf) $putsk .= "\tSkillType: ".getinf($inf)."\n";
|
|
if($inf2) $putsk .= "\tSkillInfo: ".getinf2($inf2)."\n";
|
|
if($skill_type != "none") $putsk .= "\tAttackType: \"".ucfirst($skill_type)."\"\n";
|
|
if($element) $putsk .= "\tElement: ".leveled_ele($element, $max_level, $id)."\n";
|
|
if($nk && $nk != "0x0") $putsk .= "\tDamageType: ".getnk($nk)."\n";
|
|
if($splash) $putsk .= "\tSplashRange: ".leveled_guessfill($splash, $max_level, $id)."\n";
|
|
if($list_num != "1") $putsk .= "\tNumberOfHits: ".leveled_guessfill($list_num, $max_level, $id)."\n";
|
|
if($castcancel == "yes") $putsk .= "\tInterruptCast: true\n";
|
|
if($cast_defence_rate) $putsk .= "\tCastDefRate: ".$cast_defence_rate."\n";
|
|
if($maxcount) $putsk .= "\tSkillInstances: ".leveled_guessfill($maxcount, $max_level, $id)."\n";
|
|
if($blow_count) $putsk .= "\tKnockBackTiles: ".leveled_guessfill($blow_count, $max_level, $id)."\n";
|
|
// Cast Db
|
|
$key = array_search($id, $skcast['ID']);
|
|
if($key !== FALSE) {
|
|
if($skcast['casttime'][$key]) $putsk .= "\tCastTime: ".leveled_guessfill($skcast['casttime'][$key], $max_level, $id)."\n";
|
|
if($skcast['actdelay'][$key]) $putsk .= "\tAfterCastActDelay: ".leveled_guessfill($skcast['actdelay'][$key], $max_level, $id)."\n";
|
|
if($skcast['walkdelay'][$key] !== '0') $putsk .= "\tAfterCastWalkDelay: ".leveled_guessfill($skcast['walkdelay'][$key], $max_level, $id)."\n";
|
|
if($skcast['data1'][$key] !== '0') $putsk .= "\tSkillData1: ".leveled_guessfill($skcast['data1'][$key], $max_level, $id)."\n";
|
|
if($skcast['data2'][$key] !== '0') $putsk .= "\tSkillData2: ".leveled_guessfill($skcast['data2'][$key], $max_level, $id)."\n";
|
|
if($skcast['cooldown'][$key] !== '0') $putsk .= "\tCoolDown: ".leveled_guessfill($skcast['cooldown'][$key], $max_level, $id)."\n";
|
|
if(defined('RENEWAL') && strlen($skcast['fixedcast'][$key]) > 1 && $skcast['fixedcast'][$key] !== '0')
|
|
$putsk .= "\tFixedCastTime: ".leveled_guessfill($skcast['fixedcast'][$key], $max_level, $id)."\n";
|
|
}
|
|
// Cast NoDex
|
|
unset($key);
|
|
$key = array_search($id, $sknodex['ID']);
|
|
if($key !== FALSE) {
|
|
if (isset($sknodex["cast"][$key]) && $sknodex["cast"][$key] != 0) $putsk .= "\tCastTimeOptions: ".getnocast($sknodex["cast"][$key], $id)."\n";
|
|
if (isset($sknodex["delay"][$key]) && $sknodex["delay"][$key] != 0) $putsk .= "\tSkillDelayOptions: ".getnocast($sknodex["delay"][$key], $id)."\n";
|
|
unset($sknodex["ID"][$key]);
|
|
unset($sknodex["cast"][$key]);
|
|
unset($sknodex["delay"][$key]);
|
|
}
|
|
|
|
// require DB
|
|
unset($key);
|
|
$key = array_search($id, $skreq['ID']);
|
|
if($key !== FALSE) {
|
|
$putsk .= "\tRequirements: {\n";
|
|
if ($skreq['HPCost'][$key]) $putsk .= "\t\tHPCost: ".leveled_guessfill($skreq['HPCost'][$key], $max_level, $id, 1)."\n";
|
|
if ($skreq['SPCost'][$key]) $putsk .= "\t\tSPCost: ".leveled_guessfill($skreq['SPCost'][$key], $max_level, $id, 1)."\n";
|
|
if ($skreq['HPRateCost'][$key]) $putsk .= "\t\tHPRateCost: ".leveled_guessfill($skreq['HPRateCost'][$key], $max_level, $id, 1)."\n";
|
|
if ($skreq['SPRateCost'][$key]) $putsk .= "\t\tSPRateCost: ".leveled_guessfill($skreq['SPRateCost'][$key], $max_level, $id, 1)."\n";
|
|
if ($skreq['ZenyCost'][$key]) $putsk .= "\t\tZenyCost: ".leveled_guessfill($skreq['ZenyCost'][$key], $max_level, $id, 1)."\n";
|
|
if ($skreq['Weapons'][$key] != 99) $putsk .= "\t\tWeaponTypes: ".getweapontypes($skreq['Weapons'][$key], $id)."\n";
|
|
if ($skreq['AmmoTypes'][$key] == 99) $putsk .= "\t\tAmmoTypes: \"All\"\n";
|
|
else if ($skreq['AmmoTypes'][$key]) $putsk .= "\t\tAmmoTypes: ".getammotypes($skreq['AmmoTypes'][$key], $id)."\n";
|
|
if ($skreq['AmmoAmount'][$key]) $putsk .= "\t\tAmmoAmount: ".leveled_guessfill($skreq['AmmoAmount'][$key], $max_level, $id, 1)."\n";
|
|
if ($skreq['State'][$key] != "none" && $skreq['State'][$key]) $putsk .= "\t\tState: \"".getstate($skreq['State'][$key],$id)."\"\n";
|
|
if ($skreq['SpiritSphere'][$key]) $putsk .= "\t\tSpiritSphereCost: ".leveled_guessfill($skreq['SpiritSphere'][$key], $max_level, $id, 1)."\n";
|
|
if ($skreqit['ItemId'][$key][0] > 0) {
|
|
$putsk .= "\t\tItems: {\n";
|
|
for ($index=0; $index<sizeof($skreqit['ItemId'][$key]); $index++) {
|
|
$itemID = $skreqit['ItemId'][$key][$index]; // Required Item
|
|
$itemamt = $skreqit['Amount'][$key][$index]; // Required Amount
|
|
|
|
if (strpos($itemID, ':') == true) {
|
|
$items = explode(":", $itemID);
|
|
$it = 0;
|
|
while (isset($items) && isset($items[$it])) {
|
|
if ($constants && $itemID) {
|
|
$itkey = array_search($items[$it], $itemdb['ID']);
|
|
if($itkey === FALSE)
|
|
$itemname = "ID".$items[$it];
|
|
else
|
|
$itemname = $itemdb['name'][$itkey];
|
|
$putsk .= "\t\t\t".trim($itemname).": ".leveled($itemamt, $max_level, $id, 2)."\n";
|
|
} else if (intval($itemID)) {
|
|
$putsk .= "\t\t\tID".$items[$it].": ".leveled($itemamt, $max_level, $id, 2)."\n";
|
|
}
|
|
$it++;
|
|
}
|
|
} else {
|
|
if ($constants && $itemID) {
|
|
$itkey = array_search($skreqit['ItemId'][$key][$index], $itemdb['ID']);
|
|
if($itkey === FALSE)
|
|
$itemname = "ID".$itemID;
|
|
else
|
|
$itemname = $itemdb['name'][$itkey];
|
|
$putsk .= "\t\t\t".trim($itemname).": ".leveled($itemamt, $max_items, $id, 2)."\n";
|
|
} else if ($itemID) {
|
|
$putsk .= "\t\t\tID".$itemID.": ".leveled($itemamt, $max_items, $id, 2)."\n";
|
|
}
|
|
}
|
|
}
|
|
$putsk .= "\t\t}\n";
|
|
}
|
|
$putsk .= "\t}\n";
|
|
}
|
|
|
|
unset($key);
|
|
$key = array_search($id, $skunit['ID']);
|
|
if($key !== FALSE) {
|
|
$putsk .= "\tUnit: {\n";
|
|
if(isset($skunit['UnitID'][$key])) {
|
|
if(isset($skunit['UnitID2'][$key]) && strlen($skunit['UnitID2'][$key])) {
|
|
$putsk .= "\t\tId: [ ".$skunit['UnitID'][$key].", ".$skunit['UnitID2'][$key]." ]\n";
|
|
} else $putsk .= "\t\tId: ".$skunit['UnitID'][$key]."\n";
|
|
}
|
|
if(isset($skunit['Layout'][$key]) && $skunit['Layout'][$key] != 0) $putsk .= "\t\tLayout: ".leveled_guessfill($skunit['Layout'][$key], $max_level, $id, 1)."\n";
|
|
if(isset($skunit['Range'][$key]) && $skunit['Range'][$key] != 0) $putsk .= "\t\tRange: ".leveled_guessfill($skunit['Range'][$key], $max_level, $id, 1)."\n";
|
|
# if(isset($skunit['Interval'][$key])) $putsk .= "\t\tInterval: ".leveled_guessfill($skunit['Interval'][$key], $max_level, $id, 1)."\n";
|
|
# in memory present space only for one interval, but in old db intervals present for each level
|
|
if(isset($skunit['Interval'][$key])) $putsk .= "\t\tInterval: ".intval($skunit['Interval'][$key])."\n";
|
|
if(isset($skunit['Target'][$key]) && $skunit['Target'][$key] != "noone") $putsk .= "\t\tTarget: \"".trim(ucfirst($skunit['Target'][$key]))."\"\n";
|
|
if(isset($skunit['Flag'][$key]) && $skunit['Flag'][$key] != "") {
|
|
$putsk .= "\t\tFlag: ".getunitflag($skunit['Flag'][$key], $id)."\n";
|
|
}
|
|
$putsk .= "\t}\n";
|
|
}
|
|
// close skill
|
|
$putsk .= "},\n";
|
|
// Display progress bar
|
|
show_status($i++, $linecount);
|
|
}
|
|
show_status($linecount, $linecount);
|
|
/**
|
|
* Print final messages and exit the script, conversion has completed.
|
|
*/
|
|
print "\n";
|
|
print "The skill database has been successfully converted to Hercules' libconfig\n";
|
|
print "format and has been saved as '".DIRPATH."skill_db.conf'.\n";
|
|
print "The following files are now deprecated and can be deleted -\n";
|
|
print DIRPATH."skill_db.txt\n";
|
|
print DIRPATH."skill_cast_db.txt\n";
|
|
print DIRPATH."skill_castnodex_db.txt\n";
|
|
print DIRPATH."skill_require_db.txt\n";
|
|
print DIRPATH."skill_unit_db.txt\n";
|
|
$putsk .= ")";
|
|
$skconf = "skill_db.conf";
|
|
file_put_contents(DIRPATH.$skconf, $putsk);
|
|
if($debug) {
|
|
print "[Debug] Memory after converting: ".print_mem()."\n";
|
|
print "[Debug] Execution Time : ".(microtime_float()-$t_init)."s\n";
|
|
}
|
|
fclose($skmain);
|
|
|
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
/* Functions
|
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
function microtime_float()
|
|
{
|
|
list($usec, $sec) = explode(" ", microtime());
|
|
return ((float)$usec + (float)$sec);
|
|
}
|
|
|
|
function show_status($done, $total) {
|
|
$perc = floor(($done / $total) * 100);
|
|
$perc = floor($perc/2);
|
|
$left = 50-$perc;
|
|
$finalperc = $perc * 2;
|
|
$write = sprintf("[%'={$perc}s>%-{$left}s] - $finalperc%% - $done/$total\r", "", "");
|
|
fwrite(STDERR, $write);
|
|
}
|
|
function get_element($ele,$id)
|
|
{
|
|
switch($ele)
|
|
{
|
|
case -1: return "Ele_Weapon";
|
|
case -2: return "Ele_Endowed";
|
|
case -3: return "Ele_Random";
|
|
case 0: return "Ele_Neutral";
|
|
case 1: return "Ele_Water";
|
|
case 2: return "Ele_Earth";
|
|
case 3: return "Ele_Fire";
|
|
case 4: return "Ele_Wind";
|
|
case 5: return "Ele_Poison";
|
|
case 6: return "Ele_Holy";
|
|
case 7: return "Ele_Dark";
|
|
case 8: return "Ele_Ghost";
|
|
case 9: return "Ele_Undead";
|
|
default: print "\rWarningUnknown Element ".$ele." provided for skill Id ".$id."\n";
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
function leveled_ele($str, $max, $skill_id)
|
|
{
|
|
if(strpos($str, ':') == true)
|
|
{
|
|
$lvs = explode(":", $str);
|
|
$retval = "{\n";
|
|
for($i = 0; $i < $max && isset($lvs[$i]); $i++) {
|
|
$retval .= "\t\tLv".($i+1).": \"".get_element($lvs[$i],$skill_id)."\"\n";
|
|
}
|
|
$retval .= "\t}";
|
|
} else {
|
|
$retval = "\"".get_element($str,$skill_id)."\"";
|
|
}
|
|
|
|
return $retval;
|
|
}
|
|
|
|
function leveled($str, $max, $id, $tab=0)
|
|
{
|
|
switch($tab) {
|
|
case 1:
|
|
$ittab = "\t\t\t";
|
|
$endtab = "\t\t";
|
|
break;
|
|
case 2:
|
|
$ittab = "\t\t\t\t";
|
|
$endtab = "\t\t\t";
|
|
break;
|
|
default:
|
|
$ittab = "\t\t";
|
|
$endtab = "\t";
|
|
break;
|
|
}
|
|
|
|
$retval = "";
|
|
if(strpos($str, ':') == true) {
|
|
$lvs = explode(":", trim($str));
|
|
$retval = "{\n";
|
|
for ($i = 0; $i < $max && isset($lvs[$i]); $i++) {
|
|
$retval .= $ittab."Lv".($i+1).": ".$lvs[$i]."\n";
|
|
}
|
|
$retval .= $endtab."}";
|
|
} else {
|
|
$retval = intval($str);
|
|
}
|
|
|
|
return $retval;
|
|
}
|
|
|
|
function leveled_guessfill($str, $max, $id, $tab=0)
|
|
{
|
|
switch($tab) {
|
|
case 1:
|
|
$ittab = "\t\t\t";
|
|
$endtab = "\t\t";
|
|
break;
|
|
case 2:
|
|
$ittab = "\t\t\t\t";
|
|
$endtab = "\t\t\t";
|
|
break;
|
|
default:
|
|
$ittab = "\t\t";
|
|
$endtab = "\t";
|
|
break;
|
|
}
|
|
|
|
$retval = "";
|
|
if(strpos($str, ':') == true) {
|
|
$lvs = explode(":", trim($str));
|
|
$retval = "{\n";
|
|
for ($i = 0; $i < $max && isset($lvs[$i]); $i++) {
|
|
$retval .= $ittab."Lv".($i+1).": ".$lvs[$i]."\n";
|
|
}
|
|
if ($i < $max) {
|
|
/* Algorithm borrowed from skill_split_atoi(), as used by the old parser */
|
|
for ($step = 1; $step <= $i/2; $step++) {
|
|
$diff = $lvs[$i - 1] - $lvs[$i - $step - 1];
|
|
for ($j = $i - 1; $j >= $step; $j--)
|
|
if ($lvs[$j] - $lvs[$j - $step] != $diff)
|
|
break;
|
|
|
|
if ($j >= $step) //No match, try next step.
|
|
continue;
|
|
|
|
for(; $i < $max; $i++) { //Apply linear increase
|
|
$lvs[$i] = $lvs[$i - $step] + $diff;
|
|
if ($lvs[$i] < 1 && $lvs[$i - 1] >= 0) {
|
|
//Check if we have switched from + to -, cap the decrease to 0 in said cases.
|
|
$lvs[$i] = 1;
|
|
$diff = 0;
|
|
$step = 1;
|
|
}
|
|
$retval .= $ittab."Lv".($i+1).": ".$lvs[$i]."\n";
|
|
}
|
|
$retval .= $endtab."}";
|
|
return $retval;
|
|
}
|
|
//Okay.. we can't figure this one out, just fill out the stuff with the previous value.
|
|
for (; $i < $max; $i++) {
|
|
$lvs[$i] = $lvs[$i - 1];
|
|
$retval .= $ittab."Lv".($i+1).": ".$lvs[$i]."\n";
|
|
}
|
|
}
|
|
$retval .= $endtab."}";
|
|
} else {
|
|
$retval = intval($str);
|
|
}
|
|
|
|
return $retval;
|
|
}
|
|
|
|
function getstate($state,$id)
|
|
{
|
|
if( strcmp($state,"hiding") == 0 ) return "Hiding";
|
|
else if( strcmp($state,"cloaking") == 0 ) return "Cloaking";
|
|
else if( strcmp($state,"hidden") == 0 ) return "Hidden";
|
|
else if( strcmp($state,"riding") == 0 ) return "Riding";
|
|
else if( strcmp($state,"falcon") == 0 ) return "Falcon";
|
|
else if( strcmp($state,"cart") == 0 ) return "Cart";
|
|
else if( strcmp($state,"shield") == 0 ) return "Shield";
|
|
else if( strcmp($state,"sight") == 0 ) return "Sight";
|
|
else if( strcmp($state,"explosionspirits") == 0 ) return "ExplosionSpirits";
|
|
else if( strcmp($state,"cartboost") == 0 ) return "CartBoost";
|
|
else if( strcmp($state,"recover_weight_rate") == 0 ) return "NotOverWeight";
|
|
else if( strcmp($state,"move_enable") == 0 ) return "Moveable";
|
|
else if( strcmp($state,"water") == 0 ) return "InWater";
|
|
else if( strcmp($state,"dragon") == 0 ) return "Dragon";
|
|
else if( strcmp($state,"warg") == 0 ) return "Warg";
|
|
else if( strcmp($state,"ridingwarg") == 0 ) return "RidingWarg";
|
|
else if( strcmp($state,"mado") == 0 ) return "MadoGear";
|
|
else if( strcmp($state,"elementalspirit") == 0 ) return "ElementalSpirit";
|
|
else if( strcmp($state,"poisonweapon") == 0 ) return "PoisonWeapon";
|
|
else if( strcmp($state,"rollingcutter") == 0 ) return "RollingCutter";
|
|
else if( strcmp($state,"mh_fighting") == 0 ) return "MH_Fighting";
|
|
else if( strcmp($state,"mh_grappling") == 0 ) return "MH_Grappling";
|
|
else if( strcmp($state,"peco") == 0 ) return "Peco";
|
|
else print "\rWarning - Invalid State ".$state." provided for Skill ID ".$id.", please correct this manually.\n";
|
|
}
|
|
|
|
function getinf($inf)
|
|
{
|
|
$bitmask = array(
|
|
"Passive" => 0,
|
|
"Enemy" => 1,
|
|
"Place" => 2,
|
|
"Self" => 4,
|
|
"Friend" => 16,
|
|
"Trap" => 32,
|
|
);
|
|
|
|
$retval = "{\n";
|
|
foreach ($bitmask as $key => $val)
|
|
{
|
|
if($inf&$val)
|
|
$retval .= "\t\t".$key.": true\n";
|
|
}
|
|
$retval .= "\t}";
|
|
|
|
return $retval;
|
|
}
|
|
|
|
function getinf2($inf2=0x0000)
|
|
{
|
|
$bitmask = array(
|
|
"Quest" => intval(0x0001), // = quest skill
|
|
"NPC" => intval(0x0002), // = npc skill
|
|
"Wedding" => intval(0x0004), // = wedding skill
|
|
"Spirit" => intval(0x0008), // = spirit skill
|
|
"Guild" => intval(0x0010), // = guild skill
|
|
"Song" => intval(0x0020), // = song/dance
|
|
"Ensemble" => intval(0x0040), // = ensemble skill
|
|
"Trap" => intval(0x0080), // = trap
|
|
"TargetSelf" => intval(0x0100), // = skill that damages/targets yourself
|
|
"NoCastSelf" => intval(0x0200), // = cannot be casted on self (if inf = 4, auto-select target skill)
|
|
"PartyOnly" => intval(0x0400), // = usable only on party-members (and enemies if skill is offensive)
|
|
"GuildOnly" => intval(0x0800), // = usable only on guild-mates (and enemies if skill is offensive)
|
|
"NoEnemy" => intval(0x1000), // = disable usage on enemies (for non-offensive skills).
|
|
"IgnoreLandProtector" => intval(0x2000), // = skill ignores land protector (e.g. arrow shower)
|
|
"Chorus" => intval(0x4000) // = chorus skill
|
|
);
|
|
|
|
$inf2 = intval(substr($inf2, 2),16);
|
|
|
|
$retval = "{\n";
|
|
foreach($bitmask as $key => $val) {
|
|
if($inf2&$val) {
|
|
$retval .= "\t\t".$key.": true\n";
|
|
}
|
|
}
|
|
$retval .= "\t}";
|
|
|
|
return $retval;
|
|
}
|
|
|
|
function getnk($nk)
|
|
{
|
|
$bitmask = array(
|
|
"NoDamage" => intval(0x01), //- No damage skill
|
|
"SplashArea" => intval(0x02), //- Has splash area (requires source modification)
|
|
"SplitDamage" => intval(0x04), //- Damage should be split among targets (requires 0x02 in order to work)
|
|
"IgnoreCards" => intval(0x08), //- Skill ignores caster's % damage cards (misc type always ignores)
|
|
"IgnoreElement" => intval(0x10), //- Skill ignores elemental adjustments
|
|
"IgnoreDefense" => intval(0x20), //- Skill ignores target's defense (misc type always ignores)
|
|
"IgnoreFlee" => intval(0x40), //- Skill ignores target's flee (magic type always ignores)
|
|
"IgnoreDefCards" => intval(0x80) //- Skill ignores target's def cards
|
|
);
|
|
$nk = intval($nk,16);
|
|
$retval = "{\n";
|
|
foreach($bitmask as $key => $val) {
|
|
if($nk&$val) {
|
|
$retval .= "\t\t".$key.": true\n";
|
|
}
|
|
}
|
|
$retval .= "\t}";
|
|
|
|
return $retval;
|
|
}
|
|
|
|
function getnocast($opt, $id)
|
|
{
|
|
$bitmask = array(
|
|
'Default' => 0, //- everything affects the skill's cast time
|
|
'IgnoreDex' => 1, //- skill's cast time is not affected by dex
|
|
'IgnoreStatusEffect' => 2, //- skill's cast time is not affected by statuses (Suffragium, etc)
|
|
'IgnoreItemBonus' => 4 //- skill's cast time is not affected by item bonuses (equip, cards)
|
|
);
|
|
|
|
if($opt > array_sum($bitmask) || $opt < 0)
|
|
print "\rWarning - a bitmask for CastNoDex entry for skill ID ".$id." is higher than total of masks or lower than 0.";
|
|
|
|
$retval = "{\n";
|
|
foreach($bitmask as $key => $val) {
|
|
if($opt&$val) {
|
|
$retval .= "\t\t".$key.": true\n";
|
|
}
|
|
}
|
|
$retval .= "\t}";
|
|
|
|
return $retval;
|
|
}
|
|
|
|
function getweapontypes($list, $id)
|
|
{
|
|
$bitmask = array(
|
|
0 => "NoWeapon",
|
|
1 => "Daggers",
|
|
2 => "1HSwords",
|
|
3 => "2HSwords",
|
|
4 => "1HSpears",
|
|
5 => "2HSpears",
|
|
6 => "1HAxes",
|
|
7 => "2HAxes",
|
|
8 => "Maces",
|
|
9 => "2HMaces",
|
|
10 => "Staves",
|
|
11 => "Bows",
|
|
12 => "Knuckles",
|
|
13 => "Instruments",
|
|
14 => "Whips",
|
|
15 => "Books",
|
|
16 => "Katars",
|
|
17 => "Revolvers",
|
|
18 => "Rifles",
|
|
19 => "GatlingGuns",
|
|
20 => "Shotguns",
|
|
21 => "GrenadeLaunchers",
|
|
22 => "FuumaShurikens",
|
|
23 => "2HStaves",
|
|
24 => "MaxSingleWeaponType",
|
|
25 => "DWDaggers",
|
|
26 => "DWSwords",
|
|
27 => "DWAxes",
|
|
28 => "DWDaggerSword",
|
|
29 => "DWDaggerAxe",
|
|
30 => "DWSwordAxe",
|
|
);
|
|
if(strpos($list, ':') == true) {
|
|
$type = explode(":", $list);
|
|
$wmask = 0;
|
|
for($i=0; $i<sizeof($type); $i++) {
|
|
$wmask |= 1<<$type[$i];
|
|
if($type[$i] > 30 || $type[$i] < 0)
|
|
print "\rWarning - Invalid weapon type ".$i." for skill ID ".$id."\n";
|
|
}
|
|
$retval = "{\n";
|
|
for($j=0; $j<sizeof($type); $j++) {
|
|
if($wmask&1<<$type[$j])
|
|
$retval .= "\t\t\t".$bitmask[$type[$j]].": true\n";
|
|
}
|
|
$retval .= "\t\t}";
|
|
} else {
|
|
$retval = "{\n";
|
|
$retval .= "\t\t\t".$bitmask[$list].": true\n";
|
|
$retval .= "\t\t}";
|
|
}
|
|
|
|
return $retval;
|
|
}
|
|
|
|
function getammotypes($list, $id) {
|
|
$bitmask = array(
|
|
1 => "A_ARROW",
|
|
2 => "A_DAGGER",
|
|
3 => "A_BULLET",
|
|
4 => "A_SHELL",
|
|
5 => "A_GRENADE",
|
|
6 => "A_SHURIKEN",
|
|
7 => "A_KUNAI",
|
|
8 => "A_CANNONBALL",
|
|
9 => "A_THROWWEAPON"
|
|
);
|
|
|
|
if(strpos($list, ':') == true) {
|
|
$type = explode(":", $list);
|
|
$wmask = 0;
|
|
for($i=0; $i<sizeof($type); $i++) {
|
|
$wmask |= 1<<$type[$i];
|
|
if($type[$i] > 9 || $type[$i] < 1) {
|
|
print "\rWarning - Invalid weapon type ".$i." for skill ID ".$id."\n";
|
|
}
|
|
}
|
|
$retval = "{\n";
|
|
for($j=0; $j<sizeof($type); $j++) {
|
|
if($wmask&1<<$type[$j]) {
|
|
$retval .= "\t\t\t".$bitmask[$type[$j]].": true\n";
|
|
}
|
|
}
|
|
$retval .= "\t\t}";
|
|
} else {
|
|
$retval = "{\n";
|
|
$retval .= "\t\t\t".$bitmask[$list].": true\n";
|
|
$retval .= "\t\t}";
|
|
}
|
|
|
|
return $retval;
|
|
}
|
|
|
|
function getunitflag($flag, $id)
|
|
{
|
|
$bitmask = array(
|
|
'UF_DEFNOTENEMY' => intval(0x001), //0x001(UF_DEFNOTENEMY)If 'defunit_not_enemy' is set, the target is changed to 'friend'
|
|
'UF_NOREITERATION' => intval(0x002), //0x002(UF_NOREITERATION)Spell cannot be stacked
|
|
'UF_NOFOOTSET' => intval(0x004), //0x004(UF_NOFOOTSET)Spell cannot be cast near/on targets
|
|
'UF_NOOVERLAP' => intval(0x008), //0x008(UF_NOOVERLAP)Spell effects do not overlap
|
|
'UF_PATHCHECK' => intval(0x010), //0x010(UF_PATHCHECK)Only cells with a shootable path will be placed
|
|
'UF_NOPC' => intval(0x020), //0x020(UF_NOPC)Spell cannot affect players.
|
|
'UF_NOMOB' => intval(0x040), //0x040(UF_NOMOB)Spell cannot affect mobs.
|
|
'UF_SKILL' => intval(0x080), //0x080(UF_SKILL)Spell CAN affect skills.
|
|
'UF_DANCE' => intval(0x100), //0x100(UF_DANCE)Dance skill
|
|
'UF_ENSEMBLE' => intval(0x200), //0x200(UF_ENSEMBLE)Ensemble skill
|
|
'UF_SONG' => intval(0x400), //0x400(UF_SONG)Song skill
|
|
'UF_DUALMODE' => intval(0x800), //0x800(UF_DUALMODE)Spell has effects both at an interval and when you step in/out
|
|
'UF_RANGEDSINGLEUNIT' => intval(0x2000) //0x2000(UF_RANGEDSINGLEUNIT)Layout hack, use layout range propriety but only display center.
|
|
);
|
|
|
|
$count = 0;
|
|
if($flag <= 0) return 0;
|
|
|
|
$ret = "{\n";
|
|
foreach($bitmask as $key => $val) {
|
|
if($flag&$val) {
|
|
$ret .= "\t\t\t".$key.": true\n";
|
|
}
|
|
}
|
|
|
|
if($flag > array_sum($bitmask))
|
|
print "\rWarning - Invalid Unit Flag ".$flag." provided for skill Id ".$id."\n";
|
|
|
|
$ret .= "\t\t}";
|
|
|
|
return $ret;
|
|
}
|
|
|
|
function print_mem()
|
|
{
|
|
return convert(memory_get_usage(true));
|
|
}
|
|
|
|
function convert($size)
|
|
{
|
|
$unit=array('b','kb','mb','gb','tb','pb');
|
|
return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
|
|
}
|
|
|
|
function gethelp()
|
|
{
|
|
print "Usage: php skilldbconverter.php [option]\n";
|
|
print "Options:\n";
|
|
print "\t-re [--renewal] for renewal skill database conversion.\n";
|
|
print "\t-pre-re [--pre-renewal] for pre-renewal skill database conversion.\n";
|
|
print "\t-itid [--use-itemid] to use item IDs instead of constants.\n";
|
|
print "\t-dir [--directory] provide a custom directory.\n";
|
|
print "\t (Must include the correct -pre-re/-re option)\n";
|
|
print "\t-dbg [--with-debug] print debug information.\n";
|
|
print "\t-h [--help] to display this help text.\n\n";
|
|
print "----------------------- Additional Notes ----------------------\n";
|
|
print "Important!\n";
|
|
print "* Please be advised that either and only one of the arguments -re/-pre-re\n";
|
|
print " must be specified on execution.\n";
|
|
print "* When using the -dir option, -re/-pre-re options must be specified. \n";
|
|
print "* This tool isn't designed to convert renewal data to pre-renewal.\n";
|
|
print "* This tool should ideally be used from the 'tools/' folder, which can be found\n";
|
|
print " in the root of your Hercules installation. This tool will not delete any files\n";
|
|
print " from any of the directories that it reads from or prints to.\n\n";
|
|
print "* Prior to using this tool, please ensure at least 30MB of free RAM.\n";
|
|
print "----------------------- Usage Example -------------------------\n";
|
|
print "- Renewal Conversion: php skilldbconverter.php --renewal\n";
|
|
print "- Pre-renewal Conversion: php skilldbconverter.php --pre-renewal\n";
|
|
print "----------------------------------------------------------------\n";
|
|
exit;
|
|
}
|
|
|
|
function printcredits()
|
|
{
|
|
print " _ _ _ \n";
|
|
print " | | | | | | \n";
|
|
print " | |_| | ___ _ __ ___ _ _| | ___ ___ \n";
|
|
print " | _ |/ _ \ '__/ __| | | | |/ _ \/ __|\n";
|
|
print " | | | | __/ | | (__| |_| | | __/\__ \ \n";
|
|
print " \_| |_/\___|_| \___|\__,_|_|\___||___/\n";
|
|
print "Hercules Skill Database TXT to Libconfig Converter by Smokexyz\n";
|
|
print "Copyright (C) 2016-2026 Hercules Dev Team\n";
|
|
print "-----------------------------------------------\n\n";
|
|
}
|
|
|
|
function getcomments($re)
|
|
{
|
|
return "//================= Hercules Database ==========================================
|
|
//= _ _ _
|
|
//= | | | | | |
|
|
//= | |_| | ___ _ __ ___ _ _| | ___ ___
|
|
//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __|
|
|
//= | | | | __/ | | (__| |_| | | __/\__ \
|
|
//= \_| |_/\___|_| \___|\__,_|_|\___||___/
|
|
//================= License ====================================================
|
|
//= This file is part of Hercules.
|
|
//= http://herc.ws - http://github.com/HerculesWS/Hercules
|
|
//=
|
|
//= Copyright (C) 2014-2026 Hercules Dev Team
|
|
//=
|
|
//= Hercules is free software: you can redistribute it and/or modify
|
|
//= it under the terms of the GNU General Public License as published by
|
|
//= the Free Software Foundation, either version 3 of the License, or
|
|
//= (at your option) any later version.
|
|
//=
|
|
//= This program is distributed in the hope that it will be useful,
|
|
//= but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
//= MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
//= GNU General Public License for more details.
|
|
//=
|
|
//= You should have received a copy of the GNU General Public License
|
|
//= along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//==============================================================================
|
|
//= ".($re?"Renewal":"Pre-Renewal")." Skill Database [Hercules]
|
|
//==============================================================================
|
|
//= @Format Notes:
|
|
//= - All string entries are case-sensitive and must be quoted.
|
|
//= - All setting names are case-sensitive and must be keyed accurately.
|
|
|
|
|
|
/******************************************************************************
|
|
********************************* Entry structure *****************************
|
|
*******************************************************************************
|
|
{
|
|
// ------------------------------ Mandatory Fields ----------------------------
|
|
Id: ID (int) (Required)
|
|
Name: \"Skill Name\" (string) (Required)
|
|
MaxLevel: Skill Level (int) (Required)
|
|
// ------------------------------ Optional Fields -----------------------------
|
|
Description: \"Skill Description\" (string) (optional but recommended)
|
|
Range: Skill Range (int) (optional, defaults to 0) (can be grouped by Levels)
|
|
Note: Range < 5 is considered Melee range.
|
|
Hit: Hit Type (int) (optional, default \"BDT_NORMAL\")
|
|
Types - \"BDT_SKILL\", \"BDT_MULTIHIT\" or \"BDT_NORMAL\"
|
|
SkillType: { (bool, defaults to \"Passive\")
|
|
Passive: true/false (boolean, defaults to false)
|
|
Enemy: true/false (boolean, defaults to false)
|
|
Place: true/false (boolean, defaults to false)
|
|
Self: true/false (boolean, defaults to false)
|
|
Friend: true/false (boolean, defaults to false)
|
|
Trap: true/false (boolean, defaults to false)
|
|
}
|
|
SkillInfo: { (bool, defaults to \"None\")
|
|
Quest: true/false (boolean, defaults to false)
|
|
NPC: true/false (boolean, defaults to false)
|
|
Wedding: true/false (boolean, defaults to false)
|
|
Spirit: true/false (boolean, defaults to false)
|
|
Guild: true/false (boolean, defaults to false)
|
|
Song: true/false (boolean, defaults to false)
|
|
Ensemble: true/false (boolean, defaults to false)
|
|
Trap: true/false (boolean, defaults to false)
|
|
TargetSelf: true/false (boolean, defaults to false)
|
|
NoCastSelf: true/false (boolean, defaults to false)
|
|
PartyOnly: true/false (boolean, defaults to false)
|
|
GuildOnly: true/false (boolean, defaults to false)
|
|
NoEnemy: true/false (boolean, defaults to false)
|
|
IgnoreLandProtector: true/false (boolean, defaults to false)
|
|
Chorus: true/false (boolean, defaults to false)
|
|
FreeCastReduced: true/false (boolean, defaults to false)
|
|
Works like skill SA_FREECAST, allow move and attack with reduced speed.
|
|
FreeCastNormal: true/false (boolean, defaults to false)
|
|
Works like FreeCastReduced, but not reduce speed.
|
|
}
|
|
AttackType: \"Attack Type\" (string, defaults to \"None\")
|
|
Types: \"None\", \"Weapon\", \"Magic\" or \"Misc\"
|
|
Element: \"Element Type\" (string) (Optional field - Default \"Ele_Neutral\")
|
|
(can be grouped by Levels)
|
|
Types: \"Ele_Neutral\", \"Ele_Water\", \"Ele_Earth\", \"Ele_Fire\", \"Ele_Wind\"
|
|
\"Ele_Poison\", \"Ele_Holy\", \"Ele_Dark\", \"Ele_Ghost\", \"Ele_Undead\"
|
|
\"Ele_Weapon\" - Uses weapon's element.
|
|
\"Ele_Endowed\" - Uses Endowed element.
|
|
\"Ele_Random\" - Uses random element.
|
|
DamageType: { (bool, default to \"NoDamage\")
|
|
NoDamage: true/false No damage skill
|
|
SplashArea: true/false Has splash area (requires source modification)
|
|
SplitDamage: true/false Damage should be split among targets (requires 'SplashArea' in order to work)
|
|
IgnoreCards: true/false Skill ignores caster's % damage cards (misc type always ignores)
|
|
IgnoreElement: true/false Skill ignores elemental adjustments
|
|
IgnoreDefense: true/false Skill ignores target's defense (misc type always ignores)
|
|
IgnoreFlee: true/false Skill ignores target's flee (magic type always ignores)
|
|
IgnoreDefCards: true/false Skill ignores target's def cards
|
|
}
|
|
SplashRange: Damage Splash Area (int, defaults to 0) (can be grouped by Levels)
|
|
Note: -1 for screen-wide.
|
|
NumberOfHits: Number of Hits (int, defaults to 1) (can be grouped by Levels)
|
|
Note: when positive, damage is increased by hits,
|
|
negative values just show number of hits without
|
|
increasing total damage.
|
|
InterruptCast: Cast Interruption (bool, defaults to false)
|
|
CastDefRate: Cast Defense Reduction (int, defaults to 0)
|
|
SkillInstances: Skill instances (int, defaults to 0) (can be grouped by Levels)
|
|
Notes: max amount of skill instances to place on the ground when
|
|
player_land_skill_limit/monster_land_skill_limit is enabled. For skills
|
|
that attack using a path, this is the path length to be used.
|
|
KnockBackTiles: Knock-back by 'n' Tiles (int, defaults to 0) (can be grouped by Levels)
|
|
CastTime: Skill cast Time (in ms) (int, defaults to 0) (can be grouped by Levels)
|
|
AfterCastActDelay: Skill Delay (in ms) (int, defaults to 0) (can be grouped by Levels)
|
|
AfterCastWalkDelay: Walk Delay (in ms) (int, defaults to 0) (can be grouped by Levels)
|
|
SkillData1: Skill Data/Duration (in ms) (int, defaults to 0) (can be grouped by Levels)
|
|
SkillData2: Skill Data/Duration (in ms) (int, defaults to 0) (can be grouped by Levels)
|
|
CoolDown: Skill Cooldown (in ms) (int, defaults to 0) (can be grouped by Levels)
|
|
".($re?
|
|
"FixedCastTime: Fixed Cast Time (in ms) (int, defaults to 0) (can be grouped by Levels)
|
|
Note: when 0, uses 20% of cast time and less than
|
|
0 means no fixed cast time.":"")."
|
|
CastTimeOptions: {
|
|
IgnoreDex: true/false (boolean, defaults to false)
|
|
IgnoreStatusEffect: true/false (boolean, defaults to false)
|
|
IgnoreItemBonus: true/false (boolean, defaults to false)
|
|
Note: Delay setting 'IgnoreDex' only makes sense when
|
|
delay_dependon_dex is enabled.
|
|
}
|
|
SkillDelayOptions: {
|
|
IgnoreDex: true/false (boolean, defaults to false)
|
|
IgnoreStatusEffect: true/false (boolean, defaults to false)
|
|
IgnoreItemBonus: true/false (boolean, defaults to false)
|
|
Note: Delay setting 'IgnoreDex' only makes sense when
|
|
delay_dependon_dex is enabled.
|
|
}
|
|
Requirements: {
|
|
HPCost: HP Cost (int, defaults to 0) (can be grouped by Levels)
|
|
SPCost: SP Cost (int, defaults to 0) (can be grouped by Levels)
|
|
HPRateCost: HP % Cost (int, defaults to 0) (can be grouped by Levels)
|
|
Note: If positive, it is a percent of your current hp,
|
|
otherwise it is a percent of your max hp.
|
|
SPRateCost: SP % Cost (int, defaults to 0) (can be grouped by Levels)
|
|
Note: If positive, it is a percent of your current sp,
|
|
otherwise it is a percent of your max sp.
|
|
ZenyCost: Zeny Cost (int, defaults to 0) (can be grouped by Levels)
|
|
WeaponTypes: { (bool or string, defaults to \"All\")
|
|
NoWeapon: true/false (boolean, defaults to false)
|
|
Daggers: true/false (boolean, defaults to false)
|
|
1HSwords: true/false (boolean, defaults to false)
|
|
2HSwords: true/false (boolean, defaults to false)
|
|
1HSpears: true/false (boolean, defaults to false)
|
|
2HSpears: true/false (boolean, defaults to false)
|
|
1HAxes: true/false (boolean, defaults to false)
|
|
2HAxes: true/false (boolean, defaults to false)
|
|
Maces: true/false (boolean, defaults to false)
|
|
2HMaces: true/false (boolean, defaults to false)
|
|
Staves: true/false (boolean, defaults to false)
|
|
Bows: true/false (boolean, defaults to false)
|
|
Knuckles: true/false (boolean, defaults to false)
|
|
Instruments: true/false (boolean, defaults to false)
|
|
Whips: true/false (boolean, defaults to false)
|
|
Books: true/false (boolean, defaults to false)
|
|
Katars: true/false (boolean, defaults to false)
|
|
Revolvers: true/false (boolean, defaults to false)
|
|
Rifles: true/false (boolean, defaults to false)
|
|
GatlingGuns: true/false (boolean, defaults to false)
|
|
Shotguns: true/false (boolean, defaults to false)
|
|
GrenadeLaunchers: true/false (boolean, defaults to false)
|
|
FuumaShurikens: true/false (boolean, defaults to false)
|
|
2HStaves: true/false (boolean, defaults to false)
|
|
MaxSingleWeaponType: true/false (boolean, defaults to false)
|
|
DWDaggers: true/false (boolean, defaults to false)
|
|
DWSwords: true/false (boolean, defaults to false)
|
|
DWAxes: true/false (boolean, defaults to false)
|
|
DWDaggerSword: true/false (boolean, defaults to false)
|
|
DWDaggerAxe: true/false (boolean, defaults to false)
|
|
DWSwordAxe: true/false (boolean, defaults to false)
|
|
}
|
|
AmmoTypes: { (for all types use string \"All\")
|
|
A_ARROW: true/false (boolean, defaults to false)
|
|
A_DAGGER: true/false (boolean, defaults to false)
|
|
A_BULLET: true/false (boolean, defaults to false)
|
|
A_SHELL: true/false (boolean, defaults to false)
|
|
A_GRENADE: true/false (boolean, defaults to false)
|
|
A_SHURIKEN: true/false (boolean, defaults to false)
|
|
A_KUNAI: true/false (boolean, defaults to false)
|
|
A_CANNONBALL: true/false (boolean, defaults to false)
|
|
A_THROWWEAPON: true/false (boolean, defaults to false)
|
|
}
|
|
AmmoAmount: Ammunition Amount (int, defaults to 0) (can be grouped by Levels)
|
|
State: \"Required State\" (string, defaults to \"None\") (can be grouped by Levels)
|
|
Types : 'None' = Nothing special
|
|
'Moveable' = Requires to be able to move
|
|
'NotOverWeight' = Requires to be less than 50% weight
|
|
'InWater' = Requires to be standing on a water cell
|
|
'Cart' = Requires a Pushcart
|
|
'Riding' = Requires to ride either a peco or a dragon
|
|
'Falcon' = Requires a Falcon
|
|
'Sight' = Requires Sight skill activated
|
|
'Hiding' = Requires Hiding skill activated
|
|
'Cloaking' = Requires Cloaking skill activated
|
|
'ExplosionSpirits' = Requires Fury skill activated
|
|
'CartBoost' = Requires a Pushcart and Cart Boost skill activated
|
|
'Shield' = Requires a 0,shield equipped
|
|
'Warg' = Requires a Warg
|
|
'Dragon' = Requires to ride a Dragon
|
|
'RidingWarg' = Requires to ride a Warg
|
|
'Mado' = Requires to have an active mado
|
|
'PoisonWeapon' = Requires to be under Poisoning Weapon.
|
|
'RollingCutter' = Requires at least one Rotation Counter from Rolling Cutter.
|
|
'ElementalSpirit' = Requires to have an Elemental Spirit summoned.
|
|
'MH_Fighting' = Requires Eleanor fighthing mode
|
|
'MH_Grappling' = Requires Eleanor grappling mode
|
|
'Peco' = Requires riding a peco
|
|
SpiritSphereCost: Spirit Sphere Cost (int, defaults to 0) (can be grouped by Levels)
|
|
Items: {
|
|
ItemID or Aegis_Name : Amount (int, defaults to 0) (can be grouped by Levels)
|
|
Item example: \"ID717\" or \"Blue_Gemstone\".
|
|
Notes: Items with amount 0 will not be consumed.
|
|
Amount can also be grouped by levels.
|
|
}
|
|
}
|
|
Unit: {
|
|
Id: [ UnitID, UnitID2 ] (int, defaults to 0) (can be grouped by Levels)
|
|
Layout: Unit Layout (int, defaults to 0) (can be grouped by Levels)
|
|
Range: Unit Range (int, defaults to 0) (can be grouped by Levels)
|
|
Interval: Unit Interval (int, defaults to 0) (can be grouped by Levels)
|
|
Target: \"Unit Target\" (string, defaults to \"None\")
|
|
Types:
|
|
All - affects everyone
|
|
NotEnemy - affects anyone who isn't an enemy
|
|
Friend - affects party, guildmates and neutral players
|
|
Party - affects party only
|
|
Guild - affects guild only
|
|
Ally - affects party and guildmates only
|
|
Sameguild - affects guild but not allies
|
|
Enemy - affects enemies only
|
|
None - affects nobody
|
|
Flag: {
|
|
UF_DEFNOTENEMY: true/false (boolean, defaults to false)
|
|
UF_NOREITERATION: true/false (boolean, defaults to false)
|
|
UF_NOFOOTSET: true/false (boolean, defaults to false)
|
|
UF_NOOVERLAP: true/false (boolean, defaults to false)
|
|
UF_PATHCHECK: true/false (boolean, defaults to false)
|
|
UF_NOPC: true/false (boolean, defaults to false)
|
|
UF_NOMOB: true/false (boolean, defaults to false)
|
|
UF_SKILL: true/false (boolean, defaults to false)
|
|
UF_DANCE: true/false (boolean, defaults to false)
|
|
UF_ENSEMBLE: true/false (boolean, defaults to false)
|
|
UF_SONG: true/false (boolean, defaults to false)
|
|
UF_DUALMODE: true/false (boolean, defaults to false)
|
|
UF_RANGEDSINGLEUNI: true/false (boolean, defaults to false)
|
|
}
|
|
}
|
|
}
|
|
* This file has been generated by Smokexyz's skilldbconverter.php tool.
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n";
|
|
}
|