// 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 // ID: 5 // $ESTATE_OWNER[.id] → Account ID owner of the Real Estate // $ESTATE_OWNERNAME$[.id] → Human readable name of Real Estate owner // $ESTATE_RENTTIME[.id] → When the rent will expire // $ESTATE_MOBILIA_2[.id] → Bitmask of mobilia currently purchased on Monster Collision (6) (Use on walls only) // $ESTATE_MOBILIA_4[.id] → Bitmask of mobilia currently purchased on Air Collision (2) // $ESTATE_MOBILIA_8[.id] → Bitmask of mobilia currently purchased on Water Collision (3) // $ESTATE_MOBILIA_32[.id] → Bitmask of mobilia currently purchased on Yellow Collision (4) // $ESTATE_MOBILIA_64[.id] → Bitmask of mobilia currently purchased on Normal Collision (1) // $ESTATE_MOBILIA_128[.id] → Bitmask of mobilia currently purchased on Player Collision (5) // $ESTATE_PASSWORD$[.id] → Password to enter the estate. If it is "", then no password required // Note: GMs and Administrators can always use super password "mouboo" to enter a locked estate // $ESTATE_DOORBELL[.id] → If doorbell is disabled (enabled by default) // REAL_ESTATE_CREDITS → Credits equivalent to GP the player have. Will be used first. // The sign is the main controller 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(.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; } if ($ESTATE_OWNER[.id] == getcharid(3)) goto L_Manage; mesc l("This estate currently belongs to @@.", $ESTATE_OWNERNAME$[.id]); close; // 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; // If someone press the doorbell from outside and doorbell is enabled OnDoorbell: if ($ESTATE_DOORBELL[.id]) end; if (.dpost < gettimetick(2)) { npctalk (strcharinfo(0)+" is pressing the doorbell."); // We actually don't want l() } .dpost=gettimetick(2)+.delay; end; // Managment Menu L_Manage: mesc l("@@'s Estate", strcharinfo(0)); mesc ".:: "+ l("Managment Menu") + " ::."; .@gp=REAL_ESTATE_CREDITS+Zeny; mesc l("Rent time available: @@", FuzzyTime($ESTATE_RENTTIME[.id])); mesc l("Total Credits and GP: @@", format_number(.@gp)); mes ""; mesc l("Room password: @@", $ESTATE_PASSWORD$[.id]); if ($ESTATE_DOORBELL[.id]) mesc l("Doorbell is disabled"), 1; next; select l("Leave"), l("Enable/disable doorbell"), l("Manage Furniture"), l("Set room password"); switch (@menu) { case 1: close; break; case 2: $ESTATE_DOORBELL[.id]=!$ESTATE_DOORBELL[.id]; break; case 3: goto L_Furniture; break; case 4: mesc l("(Leave the password blank to disable)"); mesc l("Current Room password: @@", $ESTATE_PASSWORD$[.id]); mesc l("Input new password: "); input .@password$; mesc l("Repeat new password: "); input .@passwordc$; if (.@password$ == .@passwordc$) { $ESTATE_PASSWORD$[.id]=.@password$; mesc l("Password changed with success!"), 3; } else { mesc l("The passwords doesn't match."), 1; } 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 (realestate_hasmobilia(.id, .layer[.@i], .objid[.@i])) @menuentries$+=l("Sell ")+.nams$[.@i]+l(" for ") + format_number( realestate_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 (realestate_hasmobilia(.id, .layer[.@id], .objid[.@id])) { // If you have the mobilia, you're selling it for Mobiliary Credits delcells realestate_cellname(.id, .@id); realestate_togglemobilia(.id, .layer[.@id], .objid[.@id], "NPCs#RES_0097"); REAL_ESTATE_CREDITS+=realestate_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 .mapa$, .x1[.@id], .y1[.@id], .x2[.@id], .y2[.@id], .layer[.@id], realestate_cellname(.id, .@id); areatimer(.mapa$, .x1[.@id], .y1[.@id], .x2[.@id], .y2[.@id], 10, "::OnSlide"); realestate_togglemobilia(.id, .layer[.@id], .objid[.@id], "NPCs#RES_0097"); mesc l("Purchase successful!"); next; } else { mesc l("Not enough funds!"); next; } } // This loops forever goto L_ContinuousLoop; OnInit: .sex = G_OTHER; .distance = 3; // Estate Settings .id=5; // Estate ID .delay=15; // Forced wait between rings .dpost=0; // Last doorbell ring .mapa$="009-7"; // 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("Bed 01" , 5, 5000, 1, 26, 27, 27, 30); create_object("Bed 02" , 5, 5000, 2, 28, 27, 29, 30); create_object("Wardrobe" , 1, 7000, 1, 21, 23, 22, 23); create_object("Stovetop" , 1, 10000, 2, 28, 23, 29, 24); create_object("Shelf 01" , 1, 2000, 4, 25, 23, 25, 23); create_object("Shelf 02" , 1, 2000, 8, 26, 23, 26, 23); create_object("Shelf 03" , 1, 2000, 16, 27, 23, 27, 23); create_object("Shelf 04" , 1, 2000, 32, 30, 23, 30, 23); create_object("Shelf 05" , 1, 2000, 64, 31, 23, 31, 23); create_object("Shelf 06" , 1, 2000, 128, 32, 23, 32, 23); create_object("Shelf 07" , 1, 2000, 256, 33, 23, 33, 23); create_object("Shelf 08" , 1, 2000, 512, 34, 23, 34, 23); create_object("Shelf 09" , 1, 2000, 1024, 35, 23, 35, 23); create_object("Shelf 10" , 1, 2000, 2048, 36, 23, 36, 23); create_object("Shelf 11" , 1, 2000, 4096, 37, 23, 37, 23); create_object("Shelf 12" , 1, 2000, 8192, 38, 23, 38, 23); create_object("Piano" , 3, 10000, 1, 33, 25, 35, 25); create_object("Stove" , 3, 40000, 2, 23, 24, 24, 24); create_object("Left Desk" , 2, 5000, 1, 20, 25, 22, 27); create_object("Right Desk" , 2, 5000, 2, 36, 30, 38, 32); create_object("Left Chair" , 4, 2000, 1, 21, 28, 21, 28); create_object("Right Chair" , 4, 2000, 2, 37, 29, 37, 29); create_object("Painting 01" , 6, 3000, 1, 21, 20, 21, 20); create_object("Painting 02" , 6, 3000, 2, 23, 21, 23, 21); create_object("Painting 03" , 6, 3000, 4, 25, 20, 25, 20); create_object("Painting 04" , 6, 3000, 8, 28, 21, 28, 21); create_object("Painting 05" , 6, 3000, 16, 31, 20, 31, 20); create_object("Painting 06" , 6, 3000, 32, 36, 20, 36, 20); // 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_64[.id] & .objid[.@i]) array_push(.valid_ids, .@i); break; case 2: if ($ESTATE_MOBILIA_4[.id] & .objid[.@i]) array_push(.valid_ids, .@i); break; case 3: if ($ESTATE_MOBILIA_8[.id] & .objid[.@i]) array_push(.valid_ids, .@i); break; case 4: if ($ESTATE_MOBILIA_32[.id] & .objid[.@i]) array_push(.valid_ids, .@i); break; case 5: if ($ESTATE_MOBILIA_128[.id] & .objid[.@i]) array_push(.valid_ids, .@i); break; case 6: if ($ESTATE_MOBILIA_2[.id] & .objid[.@i]) array_push(.valid_ids, .@i); break; default: // We do nothing by default //debugmes("[ERROR] [CRITICAL] [REAL ESTATE]: Object %d have Invalid Collision Type: %d (must range 1~6)", .@i, .layer[.@i]); break; } } //debugmes "Found %d valid objects", getarraysize(.valid_ids); for (.@j=0; .@j < getarraysize(.valid_ids); .@j++) { .@id=.valid_ids[.@j]; setcells .mapa$, .x1[.@id], .y1[.@id], .x2[.@id], .y2[.@id], .layer[.@id], realestate_cellname(.id, .@id); //debugmes "Creating %s in %s", realestate_cellname(.id, .@id), .mapa$; } deletearray .valid_ids; // Load NPCs donpcevent "NPCs#RES_0097::OnReload"; end; }