diff options
Diffstat (limited to 'npc/functions')
-rw-r--r-- | npc/functions/marriage.txt | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/npc/functions/marriage.txt b/npc/functions/marriage.txt new file mode 100644 index 00000000..d6d76aaf --- /dev/null +++ b/npc/functions/marriage.txt @@ -0,0 +1,232 @@ +// 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 |