From c80e4d95db756c941ccc8d0ea3813971cc0672ca Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Sat, 16 Mar 2019 00:43:52 -0300 Subject: Add several stuff and several bugfixes (specially hidden errors). Most importantly, apartment system, a branch from Real Estate System. --- npc/009-6/doorbell.txt | 10 +- npc/009-7/doorbell.txt | 10 +- npc/012-8/doorbell.txt | 10 +- npc/017-1/guild.txt | 8 +- npc/017-7/doorbell.txt | 10 +- npc/017-8/doorbell.txt | 10 +- npc/024-13/_import.txt | 1 + npc/024-13/manager.txt | 123 ++++++++++++++++++ npc/024-14/_import.txt | 2 + npc/024-14/doorbell.txt | 323 ++++++++++++++++++++++++++++++++++++++++++++++++ npc/024-14/utils.txt | 147 ++++++++++++++++++++++ npc/functions/timer.txt | 7 ++ 12 files changed, 632 insertions(+), 29 deletions(-) create mode 100644 npc/024-13/manager.txt create mode 100644 npc/024-14/doorbell.txt create mode 100644 npc/024-14/utils.txt (limited to 'npc') diff --git a/npc/009-6/doorbell.txt b/npc/009-6/doorbell.txt index 2b461e8de..ddcf1021a 100644 --- a/npc/009-6/doorbell.txt +++ b/npc/009-6/doorbell.txt @@ -27,7 +27,7 @@ 009-6,32,34,0 script Doorbell#RES_0096 NPC_NO_SPRITE,{ // Name, Layer, Price, ID, x1, y1, x2, y2, function create_object { - array_push(.name$, getarg(0)); + array_push(.nams$, getarg(0)); array_push(.layer, getarg(1)); array_push(.price, getarg(2)); array_push(.objid, getarg(3)); @@ -165,7 +165,7 @@ L_ContinuousLoop: // Create a second array (@valid_ids) with the ID of objects within @re_col group for (.@i=0; .@i < getarraysize(.layer); .@i++) { - //debugmes "Found object ID %d named %s on layer %s coords (%d,%d) - Looking for layer %d", .@i, .name$[.@i], .layer[.@i], .x1[.@i], .y1[.@i], @re_col; + //debugmes "Found object ID %d named %s on layer %s coords (%d,%d) - Looking for layer %d", .@i, .nams$[.@i], .layer[.@i], .x1[.@i], .y1[.@i], @re_col; if (.layer[.@i] == @re_col) array_push(@valid_ids, .@i); } @@ -176,9 +176,9 @@ L_ContinuousLoop: for (.@j=0; .@j < getarraysize(@valid_ids); .@j++) { .@i=@valid_ids[.@j]; if (realestate_hasmobilia(.id, .layer[.@i], .objid[.@i])) - @menuentries$+=l("Sell ")+.name$[.@i]+l(" for ") + format_number( realestate_sellprice(.id,.price[.@i]) ) +":"; + @menuentries$+=l("Sell ")+.nams$[.@i]+l(" for ") + format_number( realestate_sellprice(.id,.price[.@i]) ) +":"; else - @menuentries$+=l("Purchase ")+.name$[.@i]+(" for ") + format_number( .price[.@i] )+":"; + @menuentries$+=l("Purchase ")+.nams$[.@i]+(" for ") + format_number( .price[.@i] )+":"; } select (@menuentries$); mes ""; @@ -232,7 +232,7 @@ OnInit: // Arrays // We go element by element on the array building the menu - .name$=""; + .nams$=""; .layer=0; .price=0; .objid=0; diff --git a/npc/009-7/doorbell.txt b/npc/009-7/doorbell.txt index 6060d49bd..330375bf7 100644 --- a/npc/009-7/doorbell.txt +++ b/npc/009-7/doorbell.txt @@ -27,7 +27,7 @@ 009-7,32,34,0 script Doorbell#RES_0097 NPC_NO_SPRITE,{ // Name, Layer, Price, ID, x1, y1, x2, y2, function create_object { - array_push(.name$, getarg(0)); + array_push(.nams$, getarg(0)); array_push(.layer, getarg(1)); array_push(.price, getarg(2)); array_push(.objid, getarg(3)); @@ -165,7 +165,7 @@ L_ContinuousLoop: // Create a second array (@valid_ids) with the ID of objects within @re_col group for (.@i=0; .@i < getarraysize(.layer); .@i++) { - //debugmes "Found object ID %d named %s on layer %s coords (%d,%d) - Looking for layer %d", .@i, .name$[.@i], .layer[.@i], .x1[.@i], .y1[.@i], @re_col; + //debugmes "Found object ID %d named %s on layer %s coords (%d,%d) - Looking for layer %d", .@i, .nams$[.@i], .layer[.@i], .x1[.@i], .y1[.@i], @re_col; if (.layer[.@i] == @re_col) array_push(@valid_ids, .@i); } @@ -176,9 +176,9 @@ L_ContinuousLoop: for (.@j=0; .@j < getarraysize(@valid_ids); .@j++) { .@i=@valid_ids[.@j]; if (realestate_hasmobilia(.id, .layer[.@i], .objid[.@i])) - @menuentries$+=l("Sell ")+.name$[.@i]+l(" for ") + format_number( realestate_sellprice(.id,.price[.@i]) ) +":"; + @menuentries$+=l("Sell ")+.nams$[.@i]+l(" for ") + format_number( realestate_sellprice(.id,.price[.@i]) ) +":"; else - @menuentries$+=l("Purchase ")+.name$[.@i]+(" for ") + format_number( .price[.@i] )+":"; + @menuentries$+=l("Purchase ")+.nams$[.@i]+(" for ") + format_number( .price[.@i] )+":"; } select (@menuentries$); mes ""; @@ -232,7 +232,7 @@ OnInit: // Arrays // We go element by element on the array building the menu - .name$=""; + .nams$=""; .layer=0; .price=0; .objid=0; diff --git a/npc/012-8/doorbell.txt b/npc/012-8/doorbell.txt index f910556e7..9c0ac250e 100644 --- a/npc/012-8/doorbell.txt +++ b/npc/012-8/doorbell.txt @@ -27,7 +27,7 @@ 012-8,32,34,0 script Doorbell#RES_0128 NPC_NO_SPRITE,{ // Name, Layer, Price, ID, x1, y1, x2, y2, function create_object { - array_push(.name$, getarg(0)); + array_push(.nams$, getarg(0)); array_push(.layer, getarg(1)); array_push(.price, getarg(2)); array_push(.objid, getarg(3)); @@ -165,7 +165,7 @@ L_ContinuousLoop: // Create a second array (@valid_ids) with the ID of objects within @re_col group for (.@i=0; .@i < getarraysize(.layer); .@i++) { - //debugmes "Found object ID %d named %s on layer %s coords (%d,%d) - Looking for layer %d", .@i, .name$[.@i], .layer[.@i], .x1[.@i], .y1[.@i], @re_col; + //debugmes "Found object ID %d named %s on layer %s coords (%d,%d) - Looking for layer %d", .@i, .nams$[.@i], .layer[.@i], .x1[.@i], .y1[.@i], @re_col; if (.layer[.@i] == @re_col) array_push(@valid_ids, .@i); } @@ -176,9 +176,9 @@ L_ContinuousLoop: for (.@j=0; .@j < getarraysize(@valid_ids); .@j++) { .@i=@valid_ids[.@j]; if (realestate_hasmobilia(.id, .layer[.@i], .objid[.@i])) - @menuentries$+=l("Sell ")+.name$[.@i]+l(" for ") + format_number( realestate_sellprice(.id,.price[.@i]) ) +":"; + @menuentries$+=l("Sell ")+.nams$[.@i]+l(" for ") + format_number( realestate_sellprice(.id,.price[.@i]) ) +":"; else - @menuentries$+=l("Purchase ")+.name$[.@i]+(" for ") + format_number( .price[.@i] )+":"; + @menuentries$+=l("Purchase ")+.nams$[.@i]+(" for ") + format_number( .price[.@i] )+":"; } select (@menuentries$); mes ""; @@ -232,7 +232,7 @@ OnInit: // Arrays // We go element by element on the array building the menu - .name$=""; + .nams$=""; .layer=0; .price=0; .objid=0; diff --git a/npc/017-1/guild.txt b/npc/017-1/guild.txt index f674f3037..f187adaac 100644 --- a/npc/017-1/guild.txt +++ b/npc/017-1/guild.txt @@ -20,15 +20,15 @@ OnTouch: @MAP_NAME$="guild@"+str(.@ID); // Max 4 chars for map name .@INSTID = instance_create("guilds@a"+(.@ID), getcharid(2), IOT_GUILD); - .@instanceMapName$ = instance_attachmap("guilds", .@INSTID, 0, @MAP_NAME$); - // Instance already exists, or something went wrong - // Let's assume it exists - if (.@instanceMapName$ == "") { + // Instance already exists - .@INSTID returns "-4" + if (.@INSTID == -4) { warp @MAP_NAME$, any(34,35), 48; end; } + .@instanceMapName$ = instance_attachmap("guilds", .@INSTID, 0, @MAP_NAME$); + // It'll be self-destroyed eventually... instance_set_timeout(1000000, 1000000, .@INSTID); instance_init(.@INSTID); diff --git a/npc/017-7/doorbell.txt b/npc/017-7/doorbell.txt index c343ef1dc..f04a8cd2e 100644 --- a/npc/017-7/doorbell.txt +++ b/npc/017-7/doorbell.txt @@ -27,7 +27,7 @@ 017-7,32,34,0 script Doorbell#RES_0177 NPC_NO_SPRITE,{ // Name, Layer, Price, ID, x1, y1, x2, y2, function create_object { - array_push(.name$, getarg(0)); + array_push(.nams$, getarg(0)); array_push(.layer, getarg(1)); array_push(.price, getarg(2)); array_push(.objid, getarg(3)); @@ -165,7 +165,7 @@ L_ContinuousLoop: // Create a second array (@valid_ids) with the ID of objects within @re_col group for (.@i=0; .@i < getarraysize(.layer); .@i++) { - //debugmes "Found object ID %d named %s on layer %s coords (%d,%d) - Looking for layer %d", .@i, .name$[.@i], .layer[.@i], .x1[.@i], .y1[.@i], @re_col; + //debugmes "Found object ID %d named %s on layer %s coords (%d,%d) - Looking for layer %d", .@i, .nams$[.@i], .layer[.@i], .x1[.@i], .y1[.@i], @re_col; if (.layer[.@i] == @re_col) array_push(@valid_ids, .@i); } @@ -176,9 +176,9 @@ L_ContinuousLoop: for (.@j=0; .@j < getarraysize(@valid_ids); .@j++) { .@i=@valid_ids[.@j]; if (realestate_hasmobilia(.id, .layer[.@i], .objid[.@i])) - @menuentries$+=l("Sell ")+.name$[.@i]+l(" for ") + format_number( realestate_sellprice(.id,.price[.@i]) ) +":"; + @menuentries$+=l("Sell ")+.nams$[.@i]+l(" for ") + format_number( realestate_sellprice(.id,.price[.@i]) ) +":"; else - @menuentries$+=l("Purchase ")+.name$[.@i]+(" for ") + format_number( .price[.@i] )+":"; + @menuentries$+=l("Purchase ")+.nams$[.@i]+(" for ") + format_number( .price[.@i] )+":"; } select (@menuentries$); mes ""; @@ -232,7 +232,7 @@ OnInit: // Arrays // We go element by element on the array building the menu - .name$=""; + .nams$=""; .layer=0; .price=0; .objid=0; diff --git a/npc/017-8/doorbell.txt b/npc/017-8/doorbell.txt index 9b1095b38..b7b8f7dd4 100644 --- a/npc/017-8/doorbell.txt +++ b/npc/017-8/doorbell.txt @@ -27,7 +27,7 @@ 017-8,32,34,0 script Doorbell#RES_0178 NPC_NO_SPRITE,{ // Name, Layer, Price, ID, x1, y1, x2, y2, function create_object { - array_push(.name$, getarg(0)); + array_push(.nams$, getarg(0)); array_push(.layer, getarg(1)); array_push(.price, getarg(2)); array_push(.objid, getarg(3)); @@ -165,7 +165,7 @@ L_ContinuousLoop: // Create a second array (@valid_ids) with the ID of objects within @re_col group for (.@i=0; .@i < getarraysize(.layer); .@i++) { - //debugmes "Found object ID %d named %s on layer %s coords (%d,%d) - Looking for layer %d", .@i, .name$[.@i], .layer[.@i], .x1[.@i], .y1[.@i], @re_col; + //debugmes "Found object ID %d named %s on layer %s coords (%d,%d) - Looking for layer %d", .@i, .nams$[.@i], .layer[.@i], .x1[.@i], .y1[.@i], @re_col; if (.layer[.@i] == @re_col) array_push(@valid_ids, .@i); } @@ -176,9 +176,9 @@ L_ContinuousLoop: for (.@j=0; .@j < getarraysize(@valid_ids); .@j++) { .@i=@valid_ids[.@j]; if (realestate_hasmobilia(.id, .layer[.@i], .objid[.@i])) - @menuentries$+=l("Sell ")+.name$[.@i]+l(" for ") + format_number( realestate_sellprice(.id,.price[.@i]) ) +":"; + @menuentries$+=l("Sell ")+.nams$[.@i]+l(" for ") + format_number( realestate_sellprice(.id,.price[.@i]) ) +":"; else - @menuentries$+=l("Purchase ")+.name$[.@i]+(" for ") + format_number( .price[.@i] )+":"; + @menuentries$+=l("Purchase ")+.nams$[.@i]+(" for ") + format_number( .price[.@i] )+":"; } select (@menuentries$); mes ""; @@ -232,7 +232,7 @@ OnInit: // Arrays // We go element by element on the array building the menu - .name$=""; + .nams$=""; .layer=0; .price=0; .objid=0; diff --git a/npc/024-13/_import.txt b/npc/024-13/_import.txt index f2e92fbdc..b2645428e 100644 --- a/npc/024-13/_import.txt +++ b/npc/024-13/_import.txt @@ -1,3 +1,4 @@ // Map 024-13: Frostia Indoors // This file is generated automatically. All manually added changes will be removed when running the Converter. "npc/024-13/_warps.txt", +"npc/024-13/manager.txt", diff --git a/npc/024-13/manager.txt b/npc/024-13/manager.txt new file mode 100644 index 000000000..7c9df55e3 --- /dev/null +++ b/npc/024-13/manager.txt @@ -0,0 +1,123 @@ +// TMW2: Moubootaur Legends scripts. +// Author: +// Jesusalva +// Description: +// Real Estate System + +// ESTATE_ID → Instance ID of the Estate (required for NPCs, expire) +// ESTATE_RENTTIME → When the rent will expire +// ESTATE_MOBILIA_2 → Bitmask of mobilia currently purchased on Monster Collision (6) (Use on walls only) +// ESTATE_MOBILIA_4 → Bitmask of mobilia currently purchased on Air Collision (2) +// ESTATE_MOBILIA_8 → Bitmask of mobilia currently purchased on Water Collision (3) +// ESTATE_MOBILIA_32 → Bitmask of mobilia currently purchased on Yellow Collision (4) +// ESTATE_MOBILIA_64 → Bitmask of mobilia currently purchased on Normal Collision (1) +// ESTATE_MOBILIA_128 → Bitmask of mobilia currently purchased on Player Collision (5) + +// REAL_ESTATE_CREDITS → Credits equivalent to GP the player have. Will be used first. + +// The sign is the main controller +024-13,31,32,0 script Apartment Manager NPC_ELF,{ + if (ESTATE_RENTTIME < gettimetick(2)) + goto L_RentAvailable; + + mesn; + mesq l("Your rent is valid for @@.", FuzzyTime(ESTATE_RENTTIME)); + mesc l("Apartment rents cannot be renewed until they expire. Furniture won't be lost."); + close; + +L_RentAvailable: + do + { + mesc l("This Real Estate is available for rent for only @@ GP!", format_number(.price)); + .@gp=REAL_ESTATE_CREDITS+Zeny; + mesc l("You currently have: @@ GP and mobiliary credits", format_number(.@gp)); + next; + select + rif(.@gp > .price, l("Rent it! Make it mine!")), + l("Information"), + l("Don't rent it"); + + // You want to rent + if (@menu == 1) { + realestate_payment(.price); + + // Payment done, you can now acquire the house for a month + ESTATE_RENTTIME=gettimetick(2)+.time; + + mesc l("Rent successful for 30 days!"); + } else if (@menu == 2) { + mesc l("You can rent this house to make it yours.") + " " + l("The rent lasts 30 days."); + mesc l("Then you'll be able to buy furniture and utility."); + mesc l("This is an apartment. You cannot renew until it expire, and cannot invite guests."); + next; + mesc l("Both rent and furniture are bought using money, however, there are mobiliary credits."); + mesc l("Mobiliary Credits is a special currency which can only be used on real estate."); + mesc l("It's obtained with ADMINS or by selling furniture. It is sumed to money and used first."); + next; + } + } while (@menu == 2); + close; + +OnInit: + .sex = G_OTHER; + .distance = 3; + + .@npcId = getnpcid(.name$); + setunitdata(.@npcId, UDT_HEADTOP, BowlerHat); + setunitdata(.@npcId, UDT_HEADMIDDLE, CreasedShirt); + setunitdata(.@npcId, UDT_HEADBOTTOM, NPCEyes); + setunitdata(.@npcId, UDT_WEAPON, LeatherTrousers); + + .price=10000; // Monthly rent price. + .time=2592000; // Defaults to 30 days + end; + +} + +// Door entrance +024-13,29,28,0 script #RES_PPL NPC_HIDDEN,0,0,{ + end; +OnTouch: + if (ESTATE_RENTTIME < gettimetick(2)) + goto L_RentAvailable; + + // Warp you to your apartment if exists in memory already. + // Build the instance otherwise. + + // Well, "checking if instance exist by mapname" is an illusion. + // So we try to build and if we fail, we warp the player to the instance. + .@ID=getcharid(0); + @MAP_NAME$="ples@"+str(.@ID); // Max 4 chars for map name + + .@INSTID = instance_create("ples@a"+(.@ID), getcharid(3), IOT_CHAR); + + // Instance already exists - .@INSTID returns "-4" + if (.@INSTID == -4) { + warp @MAP_NAME$, 33, 33; + end; + } + + // Attach the map + .@instanceMapName$ = instance_attachmap("024-14", .@INSTID, 0, @MAP_NAME$); + + // Record important stuff & load furniture + ESTATE_ID=.@INSTID; + addtimer(20, "Doorbell#RES_PPL::OnReload"); + addtimer(70, "NPCs#RES_PPL::OnReload"); + + // It'll be self-destroyed eventually... + instance_set_timeout(1000000, 1000000, .@INSTID); + instance_init(.@INSTID); + warp @MAP_NAME$, 33, 33; + end; + +L_RentAvailable: + dispbottom l("You do not have booked an apartment here."); + close; + +OnInit: + .distance=1; + end; + +} + diff --git a/npc/024-14/_import.txt b/npc/024-14/_import.txt index 82d3bfc16..2c45a9c1f 100644 --- a/npc/024-14/_import.txt +++ b/npc/024-14/_import.txt @@ -1,3 +1,5 @@ // Map 024-14: Real Estate // This file is generated automatically. All manually added changes will be removed when running the Converter. "npc/024-14/_warps.txt", +"npc/024-14/doorbell.txt", +"npc/024-14/utils.txt", diff --git a/npc/024-14/doorbell.txt b/npc/024-14/doorbell.txt new file mode 100644 index 000000000..f60d9cea7 --- /dev/null +++ b/npc/024-14/doorbell.txt @@ -0,0 +1,323 @@ +// TMW2: Moubootaur Legends scripts. +// Author: +// Jesusalva +// Description: +// Real Estate System +// Doorbell allows you to purchase mobilia, besides loading it when server starts +// Each layer can have 32 different furniture pieces because bitmask limit. +// This file is custom to every room + +// ESTATE_ID → Instance ID of the Estate (required for NPCs, expire) +// ESTATE_RENTTIME → When the rent will expire +// ESTATE_MOBILIA_2 → Bitmask of mobilia currently purchased on Monster Collision (6) (Use on walls only) +// ESTATE_MOBILIA_4 → Bitmask of mobilia currently purchased on Air Collision (2) +// ESTATE_MOBILIA_8 → Bitmask of mobilia currently purchased on Water Collision (3) +// ESTATE_MOBILIA_32 → Bitmask of mobilia currently purchased on Yellow Collision (4) +// ESTATE_MOBILIA_64 → Bitmask of mobilia currently purchased on Normal Collision (1) +// ESTATE_MOBILIA_128 → Bitmask of mobilia currently purchased on Player Collision (5) + +// REAL_ESTATE_CREDITS → Credits equivalent to GP the player have. Will be used first. + +// The sign is the main controller +024-14,32,34,0 script Doorbell#RES_PPL NPC_NO_SPRITE,{ + // Name, Layer, Price, ID, x1, y1, x2, y2, + function create_object { + array_push(.nams$, getarg(0)); + array_push(.layer, getarg(1)); + array_push(.price, getarg(2)); + array_push(.objid, getarg(3)); + array_push(.x1, getarg(4)); + array_push(.y1, getarg(5)); + array_push(.x2, getarg(6)); + array_push(.y2, getarg(7)); + return; + } + function re2_sellprice; + function re2_togglemobilia; + function re2_hasmobilia; + + .id=getcharid(0); + goto L_Manage; +// Managment Menu +L_Manage: + mesc l("@@'s Apartment", strcharinfo(0)); + mesc ".:: "+ l("Managment Menu") + " ::."; + + .@gp=REAL_ESTATE_CREDITS+Zeny; + mesc l("Rent time available: @@", FuzzyTime(ESTATE_RENTTIME)); + mesc l("Total Credits and GP: @@", format_number(.@gp)); + mes ""; + + next; + select + l("Leave"), + l("Manage Furniture"); + + switch (@menu) { + case 1: + close; + break; + case 2: + goto L_Furniture; + break; + } + goto L_Manage; + +L_Furniture: + mesc l("@@'s Estate", strcharinfo(0)); + mesc ".:: "+ l("Furniture Menu") + " ::."; + + .@gp=REAL_ESTATE_CREDITS+Zeny; + mesc l("Total Credits and GP: @@", format_number(.@gp)); + + next; + select + l("Finish"), + l("Manage Beds"), + l("Manage Utilities"), + l("Manage Luxury furniture"), + l("Manage Decoration"), + l("Manage Chairs"), + l("Manage Paintings"); + mes ""; + + switch (@menu) { + case 1: + goto L_Manage; + break; + case 2: + mesc ".:: "+ l("Beds") + " ::.", 3; + @re_col=RES_OBJECTS; + break; + case 3: + mesc ".:: "+ l("Utilities") + " ::.", 3; + @re_col=RES_UTILITIES; + break; + case 4: + mesc ".:: "+ l("Luxury furniture") + " ::.", 3; + @re_col=RES_LUXURY; + break; + case 5: + mesc ".:: "+ l("Decoration") + " ::.", 3; + @re_col=RES_DECORATION; + break; + case 6: + mesc ".:: "+ l("Chairs") + " ::.", 3; + @re_col=RES_SITTABLE; + break; + case 7: + mesc ".:: "+ l("Paintings") + " ::.", 3; + @re_col=RES_WALLDECORATION; + break; + } + +// L_ContinuousLoop +// Requires the following variables: +// @re_col +// Target Collision ID +L_ContinuousLoop: + deletearray @valid_ids; + + // Create a second array (@valid_ids) with the ID of objects within @re_col group + for (.@i=0; .@i < getarraysize(.layer); .@i++) { + //debugmes "Found object ID %d named %s on layer %s coords (%d,%d) - Looking for layer %d", .@i, .nams$[.@i], .layer[.@i], .x1[.@i], .y1[.@i], @re_col; + if (.layer[.@i] == @re_col) + array_push(@valid_ids, .@i); + } + //debugmes "Found %d valid objects", getarraysize(@valid_ids); + + // Create the menu with @valid_ids - Check if you already have the item to decide if you're buying or selling + @menuentries$="Finish:"; + for (.@j=0; .@j < getarraysize(@valid_ids); .@j++) { + .@i=@valid_ids[.@j]; + if (re2_hasmobilia(.id, .layer[.@i], .objid[.@i])) + @menuentries$+=l("Sell ")+.nams$[.@i]+l(" for ") + format_number( re2_sellprice(.id,.price[.@i]) ) +":"; + else + @menuentries$+=l("Purchase ")+.nams$[.@i]+(" for ") + format_number( .price[.@i] )+":"; + } + select (@menuentries$); + mes ""; + + // First option to return to previous menu + if (@menu == 1) + goto L_Furniture; + + // Otherwise, we know then that (@menu-2) is the ID in @valid_ids + // So we save .@id with the correct ID in object arrays. + // We also calculate how much aggregated money you have. + .@id=@valid_ids[@menu-2]; + .@gp=REAL_ESTATE_CREDITS+Zeny; + + if (re2_hasmobilia(.id, .layer[.@id], .objid[.@id])) { + // If you have the mobilia, you're selling it for Mobiliary Credits + delcells realestate_cellname(.id, .@id); + re2_togglemobilia(.id, .layer[.@id], .objid[.@id]); + addtimer2(150, "NPCs#RES_PPL::OnReload"); + REAL_ESTATE_CREDITS+=re2_sellprice(.id,.price[.@i]); + mesc l("Sale successful!"); + next; + } else { + // Else, you're buying it, so we must check if you have the moolah first + .@price=.price[.@id]; + if (.@gp > .@price) { + realestate_payment(.@price); + setcells "ples@"+getcharid(0), .x1[.@id], .y1[.@id], .x2[.@id], .y2[.@id], .layer[.@id], realestate_cellname(.id, .@id); + areatimer("ples@"+getcharid(0), .x1[.@id], .y1[.@id], .x2[.@id], .y2[.@id], 10, "::OnSlide"); + re2_togglemobilia(.id, .layer[.@id], .objid[.@id]); + addtimer2(150, "NPCs#RES_PPL::OnReload"); + mesc l("Purchase successful!"); + next; + } else { + mesc l("Not enough funds!"); + next; + } + } + + // This loops forever + goto L_ContinuousLoop; + + +// When using setcells() a player could get trapped! +// This label will slide the player back to entrance, which should be a safe spot +OnSlide: + slide 33, 33; + end; + +OnInit: + .sex = G_OTHER; + .distance = 3; + + // Arrays + // We go element by element on the array building the menu + .nams$=""; + .layer=0; + .price=0; + .objid=0; + .x1=0; + .y1=0; + .x2=0; + .y2=0; + + // Furniture Settings + // Name, Collision Layer, Price, ID, x1, y1, x2, y2 + // For Collision Layer, see constants.conf ("Real Estate Collisions") + create_object("Placeholder" ,99,999999,99999, 99, 99, 99, 99); + + create_object("Red Bed" , 5, 5000, 1, 25, 29, 26, 32); + create_object("Blue Bed" , 5, 5000, 2, 27, 29, 28, 32); + + create_object("Wardrobe" , 1, 7000, 1, 25, 26, 26, 26); + create_object("Cauldron" , 1, 5000, 2, 28, 27, 29, 27); + create_object("Empty Shelf" , 1, 2000, 4, 34, 26, 34, 26); + create_object("Bookshelf" , 1, 2000, 8, 35, 26, 35, 26); + create_object("Bottle Shelf", 1, 2000, 16, 36, 26, 36, 26); + create_object("Beer Shelf" , 1, 2000, 32, 37, 26, 37, 26); + + create_object("Piano" , 3, 10000, 1, 31, 26, 33, 26); + + create_object("Right Desk" , 2, 5000, 2, 36, 30, 38, 32); + + create_object("Right Chair" , 4, 2000, 2, 37, 29, 37, 29); + + create_object("Painting 01" , 6, 3000, 1, 27, 23, 27, 23); + create_object("Painting 02" , 6, 3000, 2, 29, 24, 29, 24); + create_object("Painting 03" , 6, 3000, 4, 32, 23, 32, 23); + create_object("Painting 04" , 6, 3000, 8, 35, 23, 35, 23); + end; + +OnReload: + // Load Mobilia already existing + debugmes "[REAL ESTATE] Now loading mobilia"; + for (.@i=0; .@i < getarraysize(.layer); .@i++) { + switch (.layer[.@i]) { + case 1: + if (ESTATE_MOBILIA_128 & .objid[.@i]) + array_push(.valid_ids, .@i); + break; + case 2: + if (ESTATE_MOBILIA_4 & .objid[.@i]) + array_push(.valid_ids, .@i); + break; + case 3: + if (ESTATE_MOBILIA_8 & .objid[.@i]) + array_push(.valid_ids, .@i); + break; + case 4: + if (ESTATE_MOBILIA_32 & .objid[.@i]) + array_push(.valid_ids, .@i); + break; + case 5: + if (ESTATE_MOBILIA_64 & .objid[.@i]) + array_push(.valid_ids, .@i); + break; + case 6: + if (ESTATE_MOBILIA_2 & .objid[.@i]) + array_push(.valid_ids, .@i); + break; + default: + break; + } + } + debugmes "Found %d valid objects", getarraysize(.valid_ids); + for (.@j=0; .@j < getarraysize(.valid_ids); .@j++) { + .@id=.valid_ids[.@j]; + setcells "ples@"+getcharid(0), .x1[.@id], .y1[.@id], .x2[.@id], .y2[.@id], .layer[.@id], realestate_cellname(.id, .@id); + } + deletearray .valid_ids; + end; + + + // Additional crap needed because instance system + // Previously declared functions here. Copy paste from functions/, but without $. + function re2_sellprice + { + .@timeleft=ESTATE_RENTTIME-gettimetick(2); // Number of seconds + .@daysleft=.@timeleft/86400; // Number of days left of rent + .@weeksleft=.@timeleft/604800; // Number of weeks left of rent + return (getarg(1)/max(1, 6-.@weeksleft)) - max(0, 45-.@daysleft); + } + function re2_togglemobilia + { + switch (getarg(1)) { + case 1: + ESTATE_MOBILIA_64 = ESTATE_MOBILIA_64 ^ getarg(2); break; + case 2: + ESTATE_MOBILIA_4 = ESTATE_MOBILIA_4 ^ getarg(2); break; + case 3: + ESTATE_MOBILIA_8 = ESTATE_MOBILIA_8 ^ getarg(2); break; + case 4: + ESTATE_MOBILIA_32 = ESTATE_MOBILIA_32 ^ getarg(2); break; + case 5: + ESTATE_MOBILIA_128 = ESTATE_MOBILIA_128 ^ getarg(2); break; + case 6: + ESTATE_MOBILIA_2 = ESTATE_MOBILIA_2 ^ getarg(2); break; + default: + debugmes("[ERROR] [CRITICAL] [REAL ESTATE]: Object %d have Invalid Collision Type: %d (must range 1~6)", getarg(2), getarg(1)); break; + } + if (getarg(3, "error") != "error") { addtimer2(150, "NPCs#RES_PPL::OnReload"); } + return; + } + function re2_hasmobilia + { + switch (getarg(1)) { + case 1: + return ESTATE_MOBILIA_64 & getarg(2); + case 2: + return ESTATE_MOBILIA_4 & getarg(2); + case 3: + return ESTATE_MOBILIA_8 & getarg(2); + case 4: + return ESTATE_MOBILIA_32 & getarg(2); + case 5: + return ESTATE_MOBILIA_128 & getarg(2); + case 6: + return ESTATE_MOBILIA_2 & getarg(2); + default: + debugmes("[ERROR] [CRITICAL] [REAL ESTATE]: Object %d have Invalid Collision Type: %d (must range 1~6)", getarg(2), getarg(1)); return false; + } + return false; + } + +} + + diff --git a/npc/024-14/utils.txt b/npc/024-14/utils.txt new file mode 100644 index 000000000..e9c8853bb --- /dev/null +++ b/npc/024-14/utils.txt @@ -0,0 +1,147 @@ +// TMW2: Moubootaur Legends scripts. +// Author: +// Jesusalva +// Description: +// Real Estate System +// Utils take care of NPCs - Their code, and enable/disable using check_cell +// This file is custom to every room + +// ESTATE_ID → Instance ID of the Estate (required for NPCs, expire) +// ESTATE_RENTTIME → When the rent will expire +// ESTATE_MOBILIA_2 → Bitmask of mobilia currently purchased on Monster Collision (6) (Use on walls only) +// ESTATE_MOBILIA_4 → Bitmask of mobilia currently purchased on Air Collision (2) +// ESTATE_MOBILIA_8 → Bitmask of mobilia currently purchased on Water Collision (3) +// ESTATE_MOBILIA_32 → Bitmask of mobilia currently purchased on Yellow Collision (4) +// ESTATE_MOBILIA_64 → Bitmask of mobilia currently purchased on Player Collision (5) +// ESTATE_MOBILIA_128 → Bitmask of mobilia currently purchased on Normal Collision (1) + +// REAL_ESTATE_CREDITS → Credits equivalent to GP the player have. Will be used first. + +// The sign is the main controller for rent system +// Doorbell is the main controller for indoor +// This is the NPC script controller +024-14,0,0,0 script NPCs#RES_PPL NPC_HIDDEN,{ + // load_npc ( name , map, x , y{, cell} ) + function load_npc { + if (checknpccell(getarg(1), getarg(2), getarg(3), getarg(4, cell_chknopass))) { + enablenpc instance_npcname(getarg(0), ESTATE_ID); + } else { + disablenpc instance_npcname(getarg(0), ESTATE_ID); + } + return; + } + end; + +OnInit: + // Estate Settings + .mapa$="024-14"; // Map name + + // NPC Settings + .sex = G_OTHER; + .distance = 3; + end; + +// Load or unload accordingly +OnReload: + //debugmes "[REAL ESTATE] NPC ONRELOAD"; + // load_npc ( name , map, x , y{, cell} ) + load_npc("Wardrobe#RES_PPL", .mapa$, 25, 26); + load_npc("Cauldron#RES_PPL", .mapa$, 28, 27); + load_npc("Piano#RES_PPL" , .mapa$, 32, 26); + end; + +} + +024-14,25,26,0 script Wardrobe#RES_PPL NPC_NO_SPRITE,{ + openstorage; + end; + +OnInit: + .distance=3; + end; +} + + +024-14,28,27,0 script Cauldron#RES_PPL NPC_NO_SPRITE,{ + mesc l("What will you brew today?"); + if (AlchemySystem(CRAFT_PLAYER)) + mesc l("Success!"), 3; + else + mesc l("That didn't work!"), 1; + close; + +OnInit: + .distance=3; + end; +} + + +024-14,32,26,0 script Piano#RES_PPL NPC_NO_SPRITE,{ + mesc l("Do you want to play a song?"); + mesc l("This is not saved."); + select + l("Nothing"), + l("Default"), + l("Indoors 1 (Peace)"), + l("Indoors 2 (Dimonds)"), + l("TMW Adventure"), + l("Sailing Away!"), + l("Magick Real"), + l("The Forest"), + l("Dragons and Toast"), + l("Unforgiving Lands"), + l("Arabesque (Action)"), + l("No Chains (Tulimshar)"), + l("School of Quirks (Candor)"), + l("Cake Town (Hurnscald)"), + l("Steam (LoF Village)"), + l("Woodland Fantasy"), + l("Birds in the Sunrise"); + + mes ""; + .@m$=""; + switch (@menu) { + case 1: + close; + case 2: + .@m$="8bit_the_hero.ogg"; break; + case 3: + .@m$="peace.ogg"; break; + case 4: + .@m$="peace2.ogg"; break; + case 5: + .@m$="tmw_adventure.ogg"; break; + case 6: + .@m$="sail_away.ogg"; break; + case 7: + .@m$="magick_real.ogg"; break; + case 8: + .@m$="dariunas_forest.ogg"; break; + case 9: + .@m$="dragon_and_toast.ogg"; break; + case 10: + .@m$="Unforgiving_Lands.ogg"; break; + case 11: + .@m$="Arabesque.ogg"; break; + case 12: + .@m$="mvrasseli_nochains.ogg"; break; + case 13: + .@m$="school_of_quirks.ogg"; break; + case 14: + .@m$="caketown.ogg"; break; + case 15: + .@m$="steam.ogg"; break; + case 16: + .@m$="woodland_fantasy.ogg"; break; + case 17: + .@m$="tws_birds_in_the_sunrise.ogg"; break; + + } + changemusic "ples@"+getcharid(0), .@m$; + close; + +OnInit: + .distance=3; + end; +} + diff --git a/npc/functions/timer.txt b/npc/functions/timer.txt index 17a7d4b68..5d7466d0f 100644 --- a/npc/functions/timer.txt +++ b/npc/functions/timer.txt @@ -29,6 +29,13 @@ function script areatimer2 { return .@i; } +// addtimer2(, "::") +function script addtimer2 { + deltimer(getarg(1)); + addtimer(getarg(0), getarg(1)); + return .@i; +} + // maptimer("", , "::") function script maptimer { -- cgit v1.2.3-70-g09d2