summaryrefslogblamecommitdiff
path: root/npc/functions/marriage.txt
blob: d6d76aafcee278ef0eb7834df5dc44fd6c48db6a (plain) (tree)







































































































































































































































                                                                                                                              
// marriage npc
// allows to marry other players
// * must be duplicated

-	script	marriage	NPC_NO_SPRITE,{
    end;

    function toPlayer {
        // send a message to the player
        .previous = playerattached();
        // attachrid is required because we want to use l() on another player
        attachrid(getarg(1, getcharid(CHAR_ID_ACCOUNT)));
        dispbottom(b(l(getarg(0))));
        attachrid(.previous);
        return;
    }

    function _officiator {
        // make the wedding officiator say a message
        if (getarg(1, 0)) {
            // only send to the target player
            unittalk(.officiator, l(getarg(0)), true, SELF, getarg(1, getcharid(CHAR_ID_ACCOUNT)));
        } else {
            // regular npctalk
            unittalk(.officiator, getarg(0), true);
        }
        return;
    }

    function officiator {
        if (.officiator) {
            return _officiator(getarg(0));
        } else {
            toPlayer(getarg(0));

            if (getarg(1, 0)) {
                toPlayer(getarg(0), getarg(1));
            }
            return;
        }
    }

    function explain {
        // send an explanation message
        if (.officiator) {
            return _officiator(getarg(0), playerattached());
        } else {
            return toPlayer(getarg(0));
        }
    }

    function do_marriage {
        if (.officiator) {
            // let the officiator handle it
            @marriage$ = getarg(0);
            doevent(.officiator$ + "::OnDoMarriage");
        } else {
            // no officiator
            marriage(getarg(0));
            announce(sprintf("%s and %s are now married!", strcharinfo(PC_NAME), getarg(0)), bc_all);
        }
        return;
    }

OnCheckWord:
    .@verb$ = strtolower($@p1$);
    if (.@verb$ != "marry" && .@verb$ != l("marry")) {
        end; // ignore
    }

    // get the location of the invoking character
    getmapxy(.@map$, .@x, .@y, UNITTYPE_PC);


    if (.@map$ != .map$ || .@x < .x1 || .@x > .x2 || .@y < .y1 || .@y > .y2) {
        explain("You must stand in the designated area");
        end;
    }

    // check if the target character exists and is online
    .@target$ = $@p2$;
    .@target = getcharid(CHAR_ID_ACCOUNT, .@target$);

    if (.@target == 0) {
        explain(sprintf("Player %s doesn't exist or is offline", .@target$));
        end;
    }

    if (.@target == playerattached()) {
        explain("You cannot marry yourself");
        end;
    }

    // get the location of the target character
    getmapxy(.@map$, .@x, .@y, UNITTYPE_PC, .@target);

    if (.@map$ != .map$ || .@x < .x1 || .@x > .x2 || .@y < .y1 || .@y > .y2) {
        explain("Your partner must stand in the designated area");
        end;
    }

    if (BaseLevel < WEDDING_MIN_LEVEL || readparam(BaseLevel, .@target) < WEDDING_MIN_LEVEL) {
        explain(sprintf("You and your partner must be at least level %i to marry", WEDDING_MIN_LEVEL));
        end;
    }

    // XXX: do we want to check for wedding rings?
    if (!isequipped(WeddingRing)) {
        explain("You must be wearing a %s to marry.", getitemname(WeddingRing));
        end;
    }

    if (getpartnerid()) {
        if (getpartnerid() == getcharid(CHAR_ID_CHAR, .@target$)) {
            explain("You are already married to this person.");
        } else {
            explain("You are already married to someone else.");
        }
        end;
    }

    if (getvariableofpc(@marriage, .@target, 0) == getcharid(CHAR_ID_CHAR)) {
        // the target already requested to marry us

        if (getvariableofpc(@marriage[1], .@target, 0) > now()) {
            // You must be wearing a wedding ring at all times
            if (!isequipped(WeddingRing)) {
                explain("You must be wearing a %s to marry.", getitemname(WeddingRing));
                end;
            }
            // marriage request has not expired: procceed to marry
            do_marriage(.@target$);
            end;
        } else {
            // marriage request expired
            explain("This marriage proposal has expired. Please try again");

            // refresh our own expiration
            @marriage = getcharid(CHAR_ID_CHAR, .@target$);
            @marriage[1] = time_from_minutes(+15); // expiration
        }
    } else if (@marriage && @marriage[1] > now()) {
        // we already initiated a marriage request

        if (@marriage == getcharid(CHAR_ID_CHAR, .@target$)) {
            explain("You are already marrying this person.");
            @marriage[1] = time_from_minutes(+15); // refresh expiration
        } else {
            // already marrying someone else?
            explain("You are already in the process of marrying someone else.");
            explain(sprintf("Are you sure you wish to marry %s?", .@target$));
            explain(sprintf("To confirm, type the same message again: %s %s", $@p1$, $@p2$));
            @marriage = 0; // clear the current target
        }
    } else {
        // initiate a new marriage request
        @marriage = getcharid(CHAR_ID_CHAR, .@target$);
        @marriage[1] = time_from_minutes(+15); // expiration

        announce(sprintf("%s is asking %s for marriage!", strcharinfo(PC_NAME), .@target$), bc_all);
        officiator(sprintf("%s, to accept this marriage proposal, say: marry %s", .@target$, strcharinfo(PC_NAME)), .@target);
    }
    end;

OnInit:
    if (strnpcinfo(NPC_MAP) == "") {
        // this is not a duplicate
        end;
    }

    explode(.@hidden$, strnpcinfo(NPC_NAME_HIDDEN), "#");
    explode(.@area$, .@hidden$[getarraysize(.@hidden$) - 1], ",");

    switch (getarraysize(.@area$)) {
    case 1:
        if (.@area$[0] == "") {
            .@d = 3;
        } else {
            .@d = atoi(.@area$[0]);
        }
        .x1 = .x - .@d; .x2 = .x + .@d;
        .y1 = .y - .@d; .y2 = .y + .@d;
        break;
    case 2:
        .@dx = atoi(.@area$[0]); .@dy = atoi(.@area$[1]);
        .x1 = .x - .@dx; .x2 = .x + .@dx;
        .y1 = .y - .@dy; .y2 = .y + .@dy;
        break;
    case 4:
        .x1 = atoi(.@area$[0]); .x2 = atoi(.@area$[2]);
        .y1 = atoi(.@area$[1]); .y2 = atoi(.@area$[3]);
        break;
    default:
        consolemes(CONSOLEMES_ERROR, "unexpected number of arguments for the marriage duplicate");
        break;
    }

    // now find the wedding officiator (if any)
    .@count = getunits(BL_NPC, .@units, false, strnpcinfo(NPC_MAP));

    freeloop(true);
    for (.@i = 0; .@i < .@count; ++.@i) {
        .@name$ = strtolower(strnpcinfo(NPC_NAME_HIDDEN, "", .@units[.@i]));
        .@full$ = strnpcinfo(NPC_NAME, "", .@units[.@i]);

        if (getnpcsubtype(.@units[.@i]) != NPCSUBTYPE_SCRIPT) {
            // getunits() doesn't filter npc subtypes
            continue;
        }

        if (endswith(.@name$, "officiator") ||
            endswith(.@name$, "marriage") ||
            endswith(.@name$, "wedding") ||
            getvariableofnpc(.officiator, .@full$) ||
            getvariableofnpc(.marriage, .@full$) ||
            getvariableofnpc(.wedding, .@full$)) {
            .officiator = .@units[.@i];
            .officiator$ = .@full$;
            break;
        }
    }
    freeloop(false);

    defpattern(.id, "^.+ : (?:##[0-9aBb])?([A-Za-z]+) (.{4,23})$", "OnCheckWord");
    activatepset(.id);
    .distance = 14;
    end;
}

// to use, create a duplicate:
//001-1,30,31,0	duplicate(marriage)	name#x1,y1,x2,y2	NPCID
//001-1,30,31,0	duplicate(marriage)	name#range	NPCID