예제 #1
0
dumb_ptr<invocation> spell_instantiate(effect_set_t *effect_set, dumb_ptr<env_t> env)
{
    dumb_ptr<invocation> retval;
    retval.new_();
    dumb_ptr<block_list> caster;

    retval->env = env;

    retval->caster = env->VAR(VAR_CASTER).v.v_int;
    retval->spell = env->VAR(VAR_SPELL).v.v_spell;
    retval->stack_size = 0;
    retval->current_effect = effect_set->effect;
    retval->trigger_effect = effect_set->at_trigger;
    retval->end_effect = effect_set->at_end;

    caster = map_id2bl(retval->caster);    // must still exist
    retval->bl_id = map_addobject(retval);
    retval->bl_type = BL::SPELL;
    retval->bl_m = caster->bl_m;
    retval->bl_x = caster->bl_x;
    retval->bl_y = caster->bl_y;

    map_addblock(retval);
    set_env_invocation(VAR_INVOCATION, retval);

    return retval;
}
예제 #2
0
static
int spellguard_can_satisfy(spellguard_check_t *check, dumb_ptr<map_session_data> caster,
        dumb_ptr<env_t> env, int *near_miss)
{
    tick_t tick = gettick();

    int retval = check_prerequisites(caster, check->catalysts);

    if (retval && near_miss)
        *near_miss = 1;         // close enough!

    retval = retval && caster->cast_tick <= tick    /* Hasn't cast a spell too recently */
        && check->mana <= caster->status.sp
        && check_prerequisites(caster, check->components);

    if (retval)
    {
        interval_t casttime = check->casttime;

        if (env->VAR(VAR_MIN_CASTTIME).ty == TYPE::INT)
            casttime = max(casttime, static_cast<interval_t>(env->VAR(VAR_MIN_CASTTIME).v.v_int));

        caster->cast_tick = tick + casttime;    /* Make sure not to cast too frequently */

        consume_components(caster, check->components);
        pc_heal(caster, 0, -check->mana);
    }

    return retval;
}
예제 #3
0
int skill_power_bl(dumb_ptr<block_list> bl, SkillID skill)
{
    if (bl->bl_type == BL::PC)
        return skill_power(bl->is_player(), skill);
    else
        return 0;
}
예제 #4
0
void magic_free_env(dumb_ptr<env_t> env)
{
    for (int i = 0; i < env->base_env->varv.size(); i++)
        magic_clear_var(&env->varu[i]);
    // handled by std::unique_ptr now. Was a memory leak before.
    // delete[] env->vars;
    env.delete_();
}
예제 #5
0
파일: magic-stmt.cpp 프로젝트: qiuhw/tmwa
static
int op_status_change(dumb_ptr<env_t> env, const_array<val_t> args)
{
    dumb_ptr<block_list> subject = ARGENTITY(0);
    int invocation_id = env->VAR(VAR_INVOCATION).ty == TYPE::INVOCATION
        ? env->VAR(VAR_INVOCATION).v.v_int : 0;
    dumb_ptr<invocation> invocation_ = map_id_as_spell(invocation_id);

    assert (!ARGINT(3));
    assert (!ARGINT(4));
    assert (!ARGINT(5));
    skill_status_effect(subject, static_cast<StatusChange>(ARGINT(1)),
            ARGINT(2),
            static_cast<interval_t>(ARGINT(6)), invocation_id);

    if (invocation_ && subject->bl_type == BL::PC)
        record_status_change(invocation_, subject->bl_id, StatusChange(ARGINT(1)));

    return 0;
}
예제 #6
0
파일: magic-stmt.cpp 프로젝트: qiuhw/tmwa
static
int op_instaheal(dumb_ptr<env_t> env, const_array<val_t> args)
{
    dumb_ptr<block_list> caster = (env->VAR(VAR_CASTER).ty == TYPE::ENTITY)
        ? map_id2bl(env->VAR(VAR_CASTER).v.v_int) : NULL;
    dumb_ptr<block_list> subject = ARGENTITY(0);
    if (!caster)
        caster = subject;

    if (caster->bl_type == BL::PC && subject->bl_type == BL::PC)
    {
        dumb_ptr<map_session_data> caster_pc = caster->as_player();
        dumb_ptr<map_session_data> subject_pc = subject->as_player();
        MAP_LOG_PC(caster_pc, "SPELLHEAL-INSTA PC%d FOR %d",
                    subject_pc->status.char_id, ARGINT(1));
    }

    battle_heal(caster, subject, ARGINT(1), ARGINT(2), 0);
    return 0;
}
예제 #7
0
파일: party.cpp 프로젝트: JaduJagat/tmwa
// HP通知の必要性検査用(map_foreachinmoveareaから呼ばれる)
void party_send_hp_check(dumb_ptr<block_list> bl, int party_id, int *flag)
{
    dumb_ptr<map_session_data> sd;

    nullpo_retv(bl);
    sd = bl->is_player();

    if (sd->status.party_id == party_id)
    {
        *flag = 1;
        sd->party_hp = -1;
    }
}
예제 #8
0
파일: magic-stmt.cpp 프로젝트: qiuhw/tmwa
static
void entity_warp(dumb_ptr<block_list> target, map_local *destm, int destx, int desty)
{
    if (target->bl_type == BL::PC || target->bl_type == BL::MOB)
    {

        switch (target->bl_type)
        {
            case BL::PC:
            {
                dumb_ptr<map_session_data> character = target->as_player();
                clif_clearchar(character, BeingRemoveWhy::WARPED);
                map_delblock(character);
                character->bl_x = destx;
                character->bl_y = desty;
                character->bl_m = destm;

                pc_touch_all_relevant_npcs(character);

                // Note that touching NPCs may have triggered warping and thereby updated x and y:
                MapName map_name = character->bl_m->name_;

                // Warp part #1: update relevant data, interrupt trading etc.:
                pc_setpos(character, map_name, character->bl_x, character->bl_y, BeingRemoveWhy::GONE);
                // Warp part #2: now notify the client
                clif_changemap(character, map_name,
                        character->bl_x, character->bl_y);
                break;
            }
            case BL::MOB:
                target->bl_x = destx;
                target->bl_y = desty;
                target->bl_m = destm;
                clif_fixmobpos(target->as_mob());
                break;
        }
    }
}
예제 #9
0
static
FString show_entity(dumb_ptr<block_list> entity)
{
    switch (entity->bl_type)
    {
        case BL::PC:
            return entity->as_player()->status.name.to__actual();
        case BL::NPC:
            return entity->as_npc()->name;
        case BL::MOB:
            return entity->as_mob()->name;
        case BL::ITEM:
            assert (0 && "There is no way this code did what it was supposed to do!");
            /* Sorry about this one... */
            // WTF? item_data is a struct item, not a struct item_data
            // return ((struct item_data *) (&entity->as_item()->item_data))->name;
            abort();
        case BL::SPELL:
            return {"%invocation(ERROR:this-should-not-be-an-entity)"};
        default:
            return {"%unknown-entity"};
    }
}
예제 #10
0
static
void free_area(dumb_ptr<area_t> area)
{
    if (!area)
        return;

    switch (area->ty)
    {
        case AREA::UNION:
            free_area(area->a.a_union[0]);
            free_area(area->a.a_union[1]);
            break;
        default:
            break;
    }

    area.delete_();
}
예제 #11
0
파일: magic-stmt.cpp 프로젝트: qiuhw/tmwa
static
int op_override_attack(dumb_ptr<env_t> env, const_array<val_t> args)
{
    dumb_ptr<block_list> psubject = ARGENTITY(0);
    int charges = ARGINT(1);
    interval_t attack_delay = static_cast<interval_t>(ARGINT(2));
    int attack_range = ARGINT(3);
    StatusChange icon = StatusChange(ARGINT(4));
    int look = ARGINT(5);
    int stopattack = ARGINT(6);
    dumb_ptr<map_session_data> subject;

    if (psubject->bl_type != BL::PC)
        return 0;

    subject = psubject->as_player();

    if (subject->attack_spell_override)
    {
        dumb_ptr<invocation> old_invocation = map_id_as_spell(subject->attack_spell_override);
        if (old_invocation)
            spell_free_invocation(old_invocation);
    }

    subject->attack_spell_override =
        trigger_spell(subject->bl_id, env->VAR(VAR_INVOCATION).v.v_int);
    subject->attack_spell_charges = charges;

    if (subject->attack_spell_override)
    {
        dumb_ptr<invocation> attack_spell = map_id_as_spell(subject->attack_spell_override);
        if (attack_spell && stopattack)
            attack_spell->flags |= INVOCATION_FLAG::STOPATTACK;

        char_set_weapon_icon(subject, charges, icon, look);
        char_set_attack_info(subject, attack_delay, attack_range);
    }

    return 0;
}
예제 #12
0
파일: chrif.cpp 프로젝트: Rosalila/tswa
static
void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, ItemNameId source_id, ItemNameId dest_id)
{
#define IFIX(v) if (v == source_id) {v = dest_id; }
#define FIX(item) ladmin_itemfrob_fix_item(source_id, dest_id, &item)

    if (!bl)
        return;

    switch (bl->bl_type)
    {
        case BL::PC:
        {
            dumb_ptr<map_session_data> pc = bl->is_player();

            for (IOff0 j : IOff0::iter())
                IFIX(pc->status.inventory[j].nameid);
            // cart is no longer supported
            // IFIX(pc->status.weapon);
            IFIX(pc->status.shield);
            IFIX(pc->status.head_top);
            IFIX(pc->status.head_mid);
            IFIX(pc->status.head_bottom);

            Option<P<Storage>> stor_ = account2storage2(pc->status_key.account_id);
            if OPTION_IS_SOME(stor, stor_)
            {
                for (SOff0 j : SOff0::iter())
                    FIX(stor->storage_[j]);
            }

            for (IOff0 j : IOff0::iter())
            {
                P<struct item_data> item = TRY_UNWRAP(pc->inventory_data[j], continue);
                if (item->nameid == source_id)
                {
                    item->nameid = dest_id;
                    if (bool(item->equip))
                        pc_unequipitem(pc, j, CalcStatus::NOW);
                    item->nameid = dest_id;
                }
            }

            break;
        }

        case BL::MOB:
        {
            dumb_ptr<mob_data> mob = bl->is_mob();
            for (Item& itm : mob->lootitemv)
                FIX(itm);
            break;
        }

        case BL::ITEM:
        {
            dumb_ptr<flooritem_data> item = bl->is_item();
            FIX(item->item_data);
            break;
        }
    }
#undef FIX
#undef IFIX
}
예제 #13
0
파일: magic-stmt.cpp 프로젝트: qiuhw/tmwa
static
void find_entities_in_area_c(dumb_ptr<block_list> target,
        std::vector<int> *entities_vp,
        FOREACH_FILTER filter)
{
    switch (target->bl_type)
    {

        case BL::PC:
            if (filter == FOREACH_FILTER::PC
                || filter == FOREACH_FILTER::ENTITY
                || (filter == FOREACH_FILTER::TARGET
                    && target->bl_m->flag.pvp))
                break;
            else if (filter == FOREACH_FILTER::SPELL)
            {                   /* Check all spells bound to the caster */
                dumb_ptr<invocation> invoc = target->as_player()->active_spells;
                /* Add all spells locked onto thie PC */

                while (invoc)
                {
                    entities_vp->push_back(invoc->bl_id);
                    invoc = invoc->next_invocation;
                }
            }
            return;

        case BL::MOB:
            if (filter == FOREACH_FILTER::MOB
                || filter == FOREACH_FILTER::ENTITY
                || filter == FOREACH_FILTER::TARGET)
                break;
            else
                return;

        case BL::SPELL:
            if (filter == FOREACH_FILTER::SPELL)
            {
                dumb_ptr<invocation> invocation = target->as_spell();

                /* Check whether the spell is `bound'-- if so, we'll consider it iff we see the caster(case BL::PC). */
                if (bool(invocation->flags & INVOCATION_FLAG::BOUND))
                    return;
                else
                    break;      /* Add the spell */
            }
            else
                return;

        case BL::NPC:
            if (filter == FOREACH_FILTER::NPC)
                break;
            else
                return;

        default:
            return;
    }

    entities_vp->push_back(target->bl_id);
}