summaryrefslogtreecommitdiff
path: root/npc/functions
diff options
context:
space:
mode:
Diffstat (limited to 'npc/functions')
-rw-r--r--npc/functions/marriage.txt232
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