summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesusaves <cpntb1@ymail.com>2021-04-10 17:52:46 -0300
committerJesusaves <cpntb1@ymail.com>2021-04-10 17:52:46 -0300
commitc2db4a2100de4c92ecd1201df505bc42f5b3b15a (patch)
tree4415c08faaf3b9ee4d6071bdfc250b82e4258f20
parentb8774f1d734300fe1746d254cdf5d672fabf653b (diff)
downloadevol-hercules-c2db4a2100de4c92ecd1201df505bc42f5b3b15a.tar.gz
evol-hercules-c2db4a2100de4c92ecd1201df505bc42f5b3b15a.tar.bz2
evol-hercules-c2db4a2100de4c92ecd1201df505bc42f5b3b15a.tar.xz
evol-hercules-c2db4a2100de4c92ecd1201df505bc42f5b3b15a.zip
Include the functions which scripts will need: aggravate, calcdmg and harm
-rw-r--r--src/emap/init.c6
-rw-r--r--src/emap/script_buildins.c188
-rw-r--r--src/emap/script_buildins.h6
3 files changed, 200 insertions, 0 deletions
diff --git a/src/emap/init.c b/src/emap/init.c
index 158b82b..8cad8aa 100644
--- a/src/emap/init.c
+++ b/src/emap/init.c
@@ -222,6 +222,12 @@ HPExport void plugin_init (void)
addScriptCommand("getnpcsubtype", "?", getNpcSubtype);
addScriptCommand("kick", "v?", kick);
addScriptCommand("getskillname", "i", getskillname);
+
+ // From Moubootaur Legends
+ addScriptCommand("aggravate", "i", aggravate);
+ addScriptCommand("calcdmg", "iii", calcdmg);
+ addScriptCommand("harm", "ii??", harm);
+
// Overrides
addScriptCommand("debugmes","v*",debugmes);
diff --git a/src/emap/script_buildins.c b/src/emap/script_buildins.c
index a86b0ea..c534de6 100644
--- a/src/emap/script_buildins.c
+++ b/src/emap/script_buildins.c
@@ -2707,3 +2707,191 @@ BUILDIN(debugmes)
return true;
}
+// Advanced monster data overrider
+// aggravate(guid)
+BUILDIN(aggravate)
+{
+ struct block_list *bl;
+ struct map_session_data *sd = NULL;
+
+ bl = map->id2bl(script_getnum(st, 2));
+
+ // We only work with mobs
+ if (bl == NULL) {
+ ShowWarning("buildin_aggravate: Error in finding object with given GID %d!\n", script_getnum(st, 2));
+ script_pushint(st, -1);
+ return false;
+ }
+
+ if (bl->type != BL_MOB) {
+ ShowWarning("buildin_aggravate: GID %d is not a monster!\n", script_getnum(st, 2));
+ script_pushint(st, -1);
+ return false;
+ }
+
+ // Player must be attached
+ sd = script->rid2sd(st);
+ if (sd == NULL) {
+ ShowWarning("buildin_aggravate: Ran without player attached!");
+ return true;
+ }
+
+ // Create monster structure
+ struct mob_data *md = BL_UCAST(BL_MOB, bl);
+
+ // Override the provoke flag
+ md->state.provoke_flag = sd->status.account_id;
+ // We could use mob->target()
+ // But I want aggravate to apply without any checks
+ // Skipping chase checks
+ md->target_id = sd->status.account_id;
+ return true;
+}
+
+// Returns the estimated damage (ATK or MATK)
+// Advantage over getunitdata is: Takes crit and etc. in account
+// types: 1- physical; 2- magic.
+// calcdmg(source, target, type)
+BUILDIN(calcdmg)
+{
+ struct block_list *src;
+ struct block_list *bl;
+ int attack_type, range, damage;
+ struct map_session_data *sd;
+
+ // Fill data from scripts
+ src = map->id2bl(script_getnum(st, 2));
+ bl = map->id2bl(script_getnum(st, 3));
+ attack_type = script_getnum(st,4);
+
+ // Nullity check for source
+ if (src == NULL) {
+ ShowWarning("buildin_calcdmg: Error in finding object with given GID %d!\n", script_getnum(st, 2));
+ script_pushint(st, 0);
+ return false;
+ }
+
+ // Maybe we don't want a target?
+ if (script_getnum(st, 3) <= 0) {
+ sd = BL_CAST(BL_PC, src);
+ switch(attack_type) {
+ case BF_WEAPON:
+ range = sd->battle_status.rhw.atk2-sd->battle_status.rhw.atk;
+ if (range <= 1)
+ damage = sd->battle_status.rhw.atk;
+ else
+ damage = rnd()%range + sd->battle_status.rhw.atk;
+ damage = damage + rnd()%sd->battle_status.batk;
+ script_pushint(st, damage);
+ break;
+ case BF_MAGIC:
+ range = sd->battle_status.matk_max-sd->battle_status.matk_min;
+ if (range <= 1)
+ script_pushint(st, sd->battle_status.matk_min);
+ else
+ script_pushint(st, rnd()%range + sd->battle_status.matk_min);
+ break;
+ default:
+ ShowWarning("buildin_calcdmg: Invalid attack type %d!\n", attack_type);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ return true;
+ }
+
+ // Nullity check for target
+ if (bl == NULL) {
+ ShowWarning("buildin_calcdmg: Error in finding object with given GID %d!\n", script_getnum(st, 3));
+ script_pushint(st, 0);
+ return false;
+ }
+
+ // Get ATK or MATK
+ struct Damage d;
+ switch(attack_type) {
+ case BF_WEAPON: d = battle->calc_weapon_attack(src, bl, 0,0,0); break;
+ case BF_MAGIC: d = battle->calc_magic_attack(src, bl, 0,0,0); break;
+ default:
+ ShowWarning("buildin_calcdmg: Invalid attack type %d!\n", attack_type);
+ script_pushint(st, 0);
+ return false;
+ break;
+ }
+
+ script_pushint(st, d.damage);
+ return true;
+}
+
+// Like heal() but works against anything (casts battle funcs)
+// types: 1- physical; 2- magic.
+// Any other number: misc (no calculation)
+// harm(guid, raw_damage, {type{, element}})
+BUILDIN(harm)
+{
+ struct block_list *src;
+ struct block_list *bl;
+ struct status_data *tstatus;
+ struct map_session_data *sd = NULL;
+ int attack_type = BF_MISC;
+ short elemental = ELE_NEUTRAL;
+
+ // Fill data from scripts
+ bl = map->id2bl(script_getnum(st, 2));
+ int dmg = script_getnum(st, 3);
+ // Attack Type
+ if (script_hasdata(st,4)) {
+ attack_type = script_getnum(st,4);
+ }
+ // Attack Element
+ if (script_hasdata(st,5)) {
+ elemental = script_getnum(st,5);
+ }
+
+ // Nullity checks
+ if (bl == NULL) {
+ ShowWarning("buildin_harm: Error in finding object with given GID %d!\n", script_getnum(st, 2));
+ script_pushint(st, 0);
+ return false;
+ }
+
+ // Overflow checks
+ if( dmg == INT_MIN ) dmg++;
+ if( dmg == INT_MAX ) dmg--;
+
+ // Source (sd), might be null
+ if(st->rid != 0 && map->id2sd(st->rid) != NULL)
+ sd = script->rid2sd(st);
+
+ // Default source to self if needed
+ if (sd == NULL) {
+ src = bl;
+ } else {
+ src = &sd->bl;
+ }
+
+ // Calculate defese (unaffected if not BF_WEAPON nor BF_MAGIC)
+ switch(attack_type) {
+ case BF_WEAPON: dmg = battle->calc_defense(BF_WEAPON, src, bl, 0, 0, dmg, 0, 0); break;
+ case BF_MAGIC: dmg = battle->calc_defense(BF_MAGIC, src, bl, 0, 0, dmg, 0, 0); break;
+ }
+
+ // Elemental fix
+ tstatus = status->get_status_data(bl);
+ dmg=battle->attr_fix(src, bl, dmg, elemental, tstatus->def_ele, tstatus->ele_lv);
+
+ // Apply the damage, skip any other checks or whatelse
+ if ( dmg ) {
+ if (dmg < 0)
+ status->heal(bl, -dmg, 0, STATUS_HEAL_DEFAULT);
+ else {
+ // status_damage(*src, *target, in_hp, in_sp, walkdelay, flag)
+ status->damage(src, bl, dmg, 0, 0, 0);
+ clif->damage(src, bl, 0, 0, dmg, 0, BDT_ENDURE, 0);
+ }
+ }
+
+ script_pushint(st, dmg);
+ return true;
+}
+
diff --git a/src/emap/script_buildins.h b/src/emap/script_buildins.h
index 1b1c2df..bdc79d2 100644
--- a/src/emap/script_buildins.h
+++ b/src/emap/script_buildins.h
@@ -107,6 +107,12 @@ BUILDIN(getNpcSubtype);
BUILDIN(kick);
BUILDIN(getCraftRecipe);
BUILDIN(getskillname);
+
+// Imported from Moubootaur Legends
+BUILDIN(aggravate);
+BUILDIN(calcdmg);
+BUILDIN(harm);
+
// Overrides
BUILDIN(debugmes);