diff options
author | Jesusaves <cpntb1@ymail.com> | 2021-04-10 17:52:46 -0300 |
---|---|---|
committer | Jesusaves <cpntb1@ymail.com> | 2021-04-10 17:52:46 -0300 |
commit | c2db4a2100de4c92ecd1201df505bc42f5b3b15a (patch) | |
tree | 4415c08faaf3b9ee4d6071bdfc250b82e4258f20 | |
parent | b8774f1d734300fe1746d254cdf5d672fabf653b (diff) | |
download | evol-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.c | 6 | ||||
-rw-r--r-- | src/emap/script_buildins.c | 188 | ||||
-rw-r--r-- | src/emap/script_buildins.h | 6 |
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); |