summaryrefslogtreecommitdiff
path: root/src/map/script.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/script.c')
-rw-r--r--src/map/script.c298
1 files changed, 208 insertions, 90 deletions
diff --git a/src/map/script.c b/src/map/script.c
index 9adf6b44d..1e635b622 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -2258,7 +2258,7 @@ static void script_set_constant(const char *name, int value, bool is_parameter,
{
int n = script->add_str(name);
- if( script->str_data[n].type == C_NOP ) {// new
+ if (script->str_data[n].type == C_NOP) {
script->str_data[n].type = is_parameter ? C_PARAM : C_INT;
script->str_data[n].val = value;
script->str_data[n].deprecated = is_deprecated ? 1 : 0;
@@ -2302,7 +2302,7 @@ static void script_set_constant2(const char *name, int value, bool is_parameter,
/**
* Loads the constants database from constants.conf
*/
-static void read_constdb(void)
+static void read_constdb(bool reload)
{
struct config_t constants_conf;
char filepath[256];
@@ -2321,7 +2321,6 @@ static void read_constdb(void)
}
while ((t = libconfig->setting_get_elem(cdb, i++))) {
- bool is_parameter = false;
bool is_deprecated = false;
int value = 0;
const char *name = config_setting_name(t);
@@ -2352,10 +2351,6 @@ static void read_constdb(void)
continue;
}
value = i32;
- if (libconfig->setting_lookup_bool(t, "Parameter", &i32)) {
- if (i32 != 0)
- is_parameter = true;
- }
if (libconfig->setting_lookup_bool(t, "Deprecated", &i32)) {
if (i32 != 0)
is_deprecated = true;
@@ -2363,9 +2358,13 @@ static void read_constdb(void)
} else {
value = libconfig->setting_get_int(t);
}
- if (is_parameter)
- ShowWarning("read_constdb: Defining parameters in the constants configuration is deprecated and will no longer be possible in a future version. Parameters should be defined in source. (parameter = '%s')\n", name);
- script->set_constant(name, value, is_parameter, is_deprecated);
+
+ if (reload) {
+ int n = script->add_str(name);
+ script->str_data[n].type = C_NOP; // ensures it will be overwritten
+ }
+
+ script->set_constant(name, value, false, is_deprecated);
}
script->constdb_comment(NULL);
libconfig->destroy(&constants_conf);
@@ -5593,7 +5592,7 @@ static void do_init_script(bool minimal)
VECTOR_INIT(script->hqi);
script->parse_builtin();
- script->read_constdb();
+ script->read_constdb(false);
script->load_parameters();
script->hardcoded_constants();
@@ -5645,12 +5644,11 @@ static int script_reload(void)
script->parse_cleanup_timer_id = INVALID_TIMER;
}
- mapreg->reload();
-
+ script->read_constdb(true);
itemdb->name_constants();
-
clan->set_constants();
+ mapreg->reload();
sysinfo->vcsrevision_reload();
return 0;
@@ -7701,10 +7699,10 @@ static BUILDIN(countitem2)
iden = script_getnum(st,3);
ref = script_getnum(st,4);
attr = script_getnum(st,5);
- c1 = (short)script_getnum(st,6);
- c2 = (short)script_getnum(st,7);
- c3 = (short)script_getnum(st,8);
- c4 = (short)script_getnum(st,9);
+ c1 = script_getnum(st,6);
+ c2 = script_getnum(st,7);
+ c3 = script_getnum(st,8);
+ c4 = script_getnum(st,9);
for(i = 0; i < MAX_INVENTORY; i++)
if (sd->status.inventory[i].nameid > 0 && sd->inventory_data[i] != NULL &&
@@ -8037,10 +8035,10 @@ static BUILDIN(getitem2)
iden=script_getnum(st,4);
ref=script_getnum(st,5);
attr=script_getnum(st,6);
- c1=(short)script_getnum(st,7);
- c2=(short)script_getnum(st,8);
- c3=(short)script_getnum(st,9);
- c4=(short)script_getnum(st,10);
+ c1 = script_getnum(st,7);
+ c2 = script_getnum(st,8);
+ c3 = script_getnum(st,9);
+ c4 = script_getnum(st,10);
if (bound && (itemdb_type(nameid) == IT_PETEGG || itemdb_type(nameid) == IT_PETARMOR)) {
ShowError("script_getitembound2: can't bind a pet egg/armor! Type=%d\n",bound);
@@ -8079,10 +8077,10 @@ static BUILDIN(getitem2)
item_tmp.refine=ref;
item_tmp.attribute=attr;
item_tmp.bound=(unsigned char)bound;
- item_tmp.card[0]=(short)c1;
- item_tmp.card[1]=(short)c2;
- item_tmp.card[2]=(short)c3;
- item_tmp.card[3]=(short)c4;
+ item_tmp.card[0] = c1;
+ item_tmp.card[1] = c2;
+ item_tmp.card[2] = c3;
+ item_tmp.card[3] = c4;
//Check if it's stackable.
if (!itemdb->isstackable(nameid))
@@ -8371,10 +8369,10 @@ static BUILDIN(makeitem2)
item_tmp.identify = script_getnum(st, 4);
item_tmp.refine = cap_value(script_getnum(st, 5), 0, MAX_REFINE);
item_tmp.attribute = script_getnum(st, 6);
- item_tmp.card[0] = (short)script_getnum(st, 7);
- item_tmp.card[1] = (short)script_getnum(st, 8);
- item_tmp.card[2] = (short)script_getnum(st, 9);
- item_tmp.card[3] = (short)script_getnum(st, 10);
+ item_tmp.card[0] = script_getnum(st, 7);
+ item_tmp.card[1] = script_getnum(st, 8);
+ item_tmp.card[2] = script_getnum(st, 9);
+ item_tmp.card[3] = script_getnum(st, 10);
map->addflooritem(NULL, &item_tmp, amount, m, x, y, 0, 0, 0, 0, false);
@@ -8619,10 +8617,10 @@ static BUILDIN(delitem2)
it.identify=script_getnum(st,4);
it.refine=script_getnum(st,5);
it.attribute=script_getnum(st,6);
- it.card[0]=(short)script_getnum(st,7);
- it.card[1]=(short)script_getnum(st,8);
- it.card[2]=(short)script_getnum(st,9);
- it.card[3]=(short)script_getnum(st,10);
+ it.card[0] = script_getnum(st, 7);
+ it.card[1] = script_getnum(st, 8);
+ it.card[2] = script_getnum(st, 9);
+ it.card[3] = script_getnum(st, 10);
if( it.amount <= 0 )
return true;// nothing to do
@@ -9247,6 +9245,8 @@ static BUILDIN(getbrokenid)
num=script_getnum(st,2);
for(i=0; i<MAX_INVENTORY; i++) {
+ if (sd->status.inventory[i].card[0] == CARD0_PET)
+ continue;
if ((sd->status.inventory[i].attribute & ATTR_BROKEN) != 0) {
brokencounter++;
if(num==brokencounter) {
@@ -9272,6 +9272,8 @@ static BUILDIN(getbrokencount)
return true;
for (i = 0; i < MAX_INVENTORY; i++) {
+ if (sd->status.inventory[i].card[0] == CARD0_PET)
+ continue;
if ((sd->status.inventory[i].attribute & ATTR_BROKEN) != 0)
counter++;
}
@@ -9294,6 +9296,8 @@ static BUILDIN(repair)
num=script_getnum(st,2);
for(i=0; i<MAX_INVENTORY; i++) {
+ if (sd->status.inventory[i].card[0] == CARD0_PET)
+ continue;
if ((sd->status.inventory[i].attribute & ATTR_BROKEN) != 0) {
repaircounter++;
if(num==repaircounter) {
@@ -9322,6 +9326,8 @@ static BUILDIN(repairall)
for(i = 0; i < MAX_INVENTORY; i++)
{
+ if (sd->status.inventory[i].card[0] == CARD0_PET)
+ continue;
if (sd->status.inventory[i].nameid && (sd->status.inventory[i].attribute & ATTR_BROKEN) != 0)
{
sd->status.inventory[i].attribute |= ATTR_BROKEN;
@@ -10728,7 +10734,7 @@ static BUILDIN(makepet)
sd->catch_target_class = pet->db[pet_id].class_;
intif->create_pet(sd->status.account_id, sd->status.char_id,
(short)pet->db[pet_id].class_, (short)mob->db(pet->db[pet_id].class_)->lv,
- (short)pet->db[pet_id].EggID, 0, (short)pet->db[pet_id].intimate,
+ pet->db[pet_id].EggID, 0, (short)pet->db[pet_id].intimate,
100, 0, 1, pet->db[pet_id].jname);
}
@@ -16457,7 +16463,7 @@ static BUILDIN(equip)
nameid=script_getnum(st,2);
if((item_data = itemdb->exists(nameid)) == NULL)
{
- ShowError("wrong item ID : equipitem(%i)\n",nameid);
+ ShowError("wrong item ID : equipitem(%d)\n",nameid);
return false;
}
ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == nameid && sd->status.inventory[i].equip == 0 );
@@ -16513,12 +16519,12 @@ static BUILDIN(equip2)
return false;
}
- ref = script_getnum(st,3);
- attr = script_getnum(st,4);
- c0 = (short)script_getnum(st,5);
- c1 = (short)script_getnum(st,6);
- c2 = (short)script_getnum(st,7);
- c3 = (short)script_getnum(st,8);
+ ref = script_getnum(st, 3);
+ attr = script_getnum(st, 4);
+ c0 = script_getnum(st, 5);
+ c1 = script_getnum(st, 6);
+ c2 = script_getnum(st, 7);
+ c3 = script_getnum(st, 8);
ARR_FIND( 0, MAX_INVENTORY, i,( sd->status.inventory[i].equip == 0 &&
sd->status.inventory[i].nameid == nameid &&
@@ -20915,63 +20921,177 @@ static BUILDIN(readbook)
static BUILDIN(questinfo)
{
struct npc_data *nd = map->id2nd(st->oid);
- int quest_id, icon;
- struct questinfo qi;
+ struct questinfo qi = { 0 };
+ int icon = script_getnum(st, 2);
- if( nd == NULL || nd->bl.m == -1 )
+ if (nd == NULL)
return true;
- quest_id = script_getnum(st, 2);
- icon = script_getnum(st, 3);
-
-#if PACKETVER >= 20170315
- if (icon < 0 || (icon > 10 && icon != 9999))
- icon = 9999;
-#elif PACKETVER >= 20120410
- if (icon < 0 || (icon > 8 && icon != 9999) || icon == 7)
- icon = 9999; // Default to nothing if icon id is invalid.
-#else
- if (icon < 0 || icon > 7)
- icon = 0;
- else
- icon = icon + 1;
-#endif
+ if (nd->bl.m == -1) {
+ ShowWarning("buildin_questinfo: questinfo cannot be set for an npc with no valid map.\n");
+ return false;
+ }
- qi.quest_id = quest_id;
- qi.icon = (unsigned char)icon;
qi.nd = nd;
-
- if (script_hasdata(st, 4)) {
- int color = script_getnum(st, 4);
+ qi.icon = quest->questinfo_validate_icon(icon);
+ if (script_hasdata(st, 3)) {
+ int color = script_getnum(st, 3);
if (color < 0 || color > 3) {
- ShowWarning("buildin_questinfo: invalid color '%d', changing to 0\n",color);
+ ShowWarning("buildin_questinfo: invalid color '%d', defaulting to 0.\n", color);
script->reportfunc(st);
color = 0;
}
qi.color = (unsigned char)color;
}
- qi.hasJob = false;
+ map->add_questinfo(nd->bl.m, &qi);
+ return true;
+}
- if (script_hasdata(st, 5)) {
- int job = script_getnum(st, 5);
+static BUILDIN(setquestinfo)
+{
+ struct npc_data *nd = map->id2nd(st->oid);
+ struct questinfo *qi = NULL;
+ uint32 type = script_getnum(st, 2);
- if (!pc->db_checkid(job)) {
- ShowError("buildin_questinfo: Nonexistant Job Class.\n");
- } else {
- qi.hasJob = true;
- qi.job = (unsigned short)job;
+ if (nd == NULL)
+ return true;
+
+ if (nd->bl.m == -1) {
+ ShowWarning("buildin_setquestinfo: questinfo cannot be set for an npc with no valid map.\n");
+ return false;
+ }
+
+ qi = &VECTOR_LAST(map->list[nd->bl.m].qi_data);
+ if (qi == NULL) {
+ ShowWarning("buildin_setquestinfo: no valide questinfo data has been found for this npc.\n");
+ return false;
+ }
+ if (qi->nd != nd) {
+ ShowWarning("buildin_setquestinfo: invalid usage, setquestinfo must be used only after questinfo.\n");
+ return false;
+ }
+ switch (type) {
+ case QINFO_JOB:
+ {
+ int jobid = script_getnum(st, 3);
+ if (!pc->db_checkid(jobid)) {
+ ShowWarning("buildin_setquestinfo: invalid job id given (%d).\n", jobid);
+ return false;
+ }
+ qi->hasJob = true;
+ qi->job = jobid;
+ break;
+ }
+ case QINFO_SEX:
+ {
+ int sex = script_getnum(st, 3);
+ if (sex != SEX_MALE && sex != SEX_FEMALE) {
+ ShowWarning("buildin_setquestinfo: unsupported sex has been given (%d).\n", sex);
+ return false;
+ }
+ qi->sex_enabled = true;
+ qi->sex = sex;
+ break;
+ }
+ case QINFO_BASE_LEVEL:
+ {
+ int min = script_getnum(st, 3);
+ int max = script_getnum(st, 4);
+ if (min > max) {
+ ShowWarning("buildin_setquestinfo: minimal level (%d) is bigger than the maximal level (%d).\n", min, max);
+ return false;
}
+ qi->base_level.min = min;
+ qi->base_level.max = max;
+ break;
}
+ case QINFO_JOB_LEVEL:
+ {
+ int min = script_getnum(st, 3);
+ int max = script_getnum(st, 4);
+ if (min > max) {
+ ShowWarning("buildin_setquestinfo: minimal level (%d) is bigger than the maximal level (%d).\n", min, max);
+ return false;
+ }
+ qi->job_level.min = min;
+ qi->job_level.max = max;
+ break;
+ }
+ case QINFO_ITEM:
+ {
+ struct item item = { 0 };
- map->add_questinfo(nd->bl.m,&qi);
+ item.nameid = script_getnum(st, 3);
+ item.amount = script_getnum(st, 4);
+ if (itemdb->exists(item.nameid) == NULL) {
+ ShowWarning("buildin_setquestinfo: non existing item (%d) have been given.\n", item.nameid);
+ return false;
+ }
+ if (item.amount <= 0 || item.amount > MAX_AMOUNT) {
+ ShowWarning("buildin_setquestinfo: given amount (%d) must be bigger than 0 and smaller than %d.\n", item.amount, MAX_AMOUNT + 1);
+ return false;
+ }
+ if (VECTOR_LENGTH(qi->items) == 0)
+ VECTOR_INIT(qi->items);
+ VECTOR_ENSURE(qi->items, 1, 1);
+ VECTOR_PUSH(qi->items, item);
+ break;
+ }
+ case QINFO_HOMUN_LEVEL:
+ {
+ int min = script_getnum(st, 3);
+ if (min > battle_config.hom_max_level && min > battle_config.hom_S_max_level) {
+ ShowWarning("buildin_setquestinfo: minimum homunculus level given (%d) is bigger than the max possible level.\n", min);
+ return false;
+ }
+ qi->homunculus.level = min;
+ break;
+ }
+ case QINFO_HOMUN_TYPE:
+ {
+ int hom_type = script_getnum(st, 3);
+ if (hom_type < HT_REG || hom_type > HT_S) {
+ ShowWarning("buildin_setquestinfo: invalid homunculus type (%d).\n", hom_type);
+ return false;
+ }
+ qi->homunculus_type = hom_type;
+ break;
+ }
+ case QINFO_QUEST:
+ {
+ struct questinfo_qreq quest_req = { 0 };
+ struct quest_db *quest_data = NULL;
+
+ quest_req.id = script_getnum(st, 3);
+ quest_req.state = script_getnum(st, 4);
+
+ quest_data = quest->db(quest_req.id);
+ if (quest_data == &quest->dummy) {
+ ShowWarning("buildin_setquestinfo: invalid quest given (%d).\n", quest_req.id);
+ return false;
+ }
+ if (quest_req.state < Q_INACTIVE || quest_req.state > Q_COMPLETE) {
+ ShowWarning("buildin_setquestinfo: invalid quest state given (%d).\n", quest_req.state);
+ return false;
+ }
+
+ if (VECTOR_LENGTH(qi->quest_requirement) == 0)
+ VECTOR_INIT(qi->quest_requirement);
+ VECTOR_ENSURE(qi->quest_requirement, 1, 1);
+ VECTOR_PUSH(qi->quest_requirement, quest_req);
+ break;
+ }
+ default:
+ ShowWarning("buildin_setquestinfo: invalid type given (%u).\n", type);
+ return false;
+ }
return true;
}
static BUILDIN(setquest)
{
- unsigned short i;
int quest_id;
unsigned int time_limit;
struct map_session_data *sd = script->rid2sd(st);
@@ -20983,19 +21103,6 @@ static BUILDIN(setquest)
time_limit = script_hasdata(st, 3) ? script_getnum(st, 3) : 0;
quest->add(sd, quest_id, time_limit);
-
- // If questinfo is set, remove quest bubble once quest is set.
- for (i = 0; i < map->list[sd->bl.m].qi_count; i++) {
- struct questinfo *qi = &map->list[sd->bl.m].qi_data[i];
- if (qi->quest_id == quest_id) {
-#if PACKETVER >= 20120410
- clif->quest_show_event(sd, &qi->nd->bl, 9999, 0);
-#else
- clif->quest_show_event(sd, &qi->nd->bl, 0, 0);
-#endif
- }
- }
-
return true;
}
@@ -25097,7 +25204,8 @@ static void script_parse_builtin(void)
BUILDIN_DEF(checkbound, "i???????"),
//Quest Log System [Inkfish]
- BUILDIN_DEF(questinfo, "ii??"),
+ BUILDIN_DEF(questinfo, "i?"),
+ BUILDIN_DEF(setquestinfo, "i??"),
BUILDIN_DEF(setquest, "i?"),
BUILDIN_DEF(erasequest, "i?"),
BUILDIN_DEF(completequest, "i?"),
@@ -25558,6 +25666,16 @@ static void script_hardcoded_constants(void)
script->set_constant("P_AIRSHIP_ITEM_NOT_ENOUGH", P_AIRSHIP_ITEM_NOT_ENOUGH, false, false);
script->set_constant("P_AIRSHIP_ITEM_INVALID", P_AIRSHIP_ITEM_INVALID, false, false);
+ script->constdb_comment("questinfo types");
+ script->set_constant("QINFO_JOB", QINFO_JOB, false, false);
+ script->set_constant("QINFO_SEX", QINFO_SEX, false, false);
+ script->set_constant("QINFO_BASE_LEVEL", QINFO_BASE_LEVEL, false, false);
+ script->set_constant("QINFO_JOB_LEVEL", QINFO_JOB_LEVEL, false, false);
+ script->set_constant("QINFO_ITEM", QINFO_ITEM, false, false);
+ script->set_constant("QINFO_HOMUN_LEVEL", QINFO_HOMUN_LEVEL, false, false);
+ script->set_constant("QINFO_HOMUN_TYPE", QINFO_HOMUN_TYPE, false, false);
+ script->set_constant("QINFO_QUEST", QINFO_QUEST, false, false);
+
script->constdb_comment("Renewal");
#ifdef RENEWAL
script->set_constant("RENEWAL", 1, false, false);