// TMW2 Script
// Author:
// Jesusalva
// Description:
// Central Town Political System Controller
// Note: The office is NOT Mayor, we have from kings to mayors here and you're
// not a citzen (yet). It'll be... I'll think in a name better than Minister.
// Perhaps, Town Administrator.
// Variables:
// $LOC_MAYOR$ - Stores the name of current Hurnscald Mayor
// $LOC_MONEY - Total money reserves of Hurnscald
// $LOC_TAX - How much in % is charged as taxes. (OnBuy income)
// $LOC_EXPORT - Defines how much Hurnscald exports (weekly income)
// $LOC_REPUTATION - Town reputation. Affects Max Tax and Weekly Income;
// Note: Tax cannot exceed 10% ie 1000. Reputation must be between 0 and 100.
//
// "Temporary Arrays":
// $LOC_CANDIDATE$ - Candidate for Office
// $LOC_VOTES - Number of votes of Candidate
// Proccess Taxes from purchases
// PurchaseTaxes( Location )
function script PurchaseTaxes {
.@tax=0;
for (.@i=0; .@i < getarraysize(@bought_nameid); .@i++) {
// Note: Some NPC might not
.@price=getiteminfo(@bought_nameid[.@i], ITEMINFO_BUYPRICE);
.@tax+=.@price*@bought_quantity[.@i];
}
MonsterMoney += (.@price / 5); // MK Control
.@loc$=strtoupper(getarg(0, LOCATION$));
.@vat=getd("$"+.@loc$+"_TAX");
.@tax=.@tax*.@vat/10000;
if (.@tax) {
debugmes "%s paid %d in taxes to %s prefecture!", strcharinfo(0), .@tax, .@loc$;
.@gp=getd("$"+.@loc$+"_MONEY");
setd("$"+.@loc$+"_MONEY", .@gp+.@tax);
.@tp=POL_LocToTP(.@loc$);
if (#EXILED & .@tp)
Zeny=max(0, Zeny-.@tax);
}
return;
}
// Proccess Taxes from sales (20% from purchase tax)
// SaleTaxes( Location )
function script SaleTaxes {
.@tax=0;
for (.@i=0; .@i < getarraysize(@sold_nameid); .@i++) {
// Note: Some NPC might not
.@price=getiteminfo(@sold_nameid[.@i], ITEMINFO_SELLPRICE);
.@tax+=.@price*@sold_quantity[.@i];
}
MonsterMoney += (.@p / 25); // MK Control (smaller than others)
.@loc$=strtoupper(getarg(0, LOCATION$));
.@vat=getd("$"+.@loc$+"_TAX");
.@vat=.@vat*3/4; // Only 75% of purchase tax (defaults to 0.75% I guess)
.@tax=.@tax*.@vat/10000;
if (.@tax) {
debugmes "Sale: %s paid %d in taxes to %s prefecture!", strcharinfo(0), .@tax, .@loc$;
.@gp=getd("$"+.@loc$+"_MONEY");
setd("$"+.@loc$+"_MONEY", .@gp+.@tax);
dispbottom col(l("%s is happy because you've paid %d GP in taxes!", getd("$"+.@loc$+"_MAYOR$"), .@tax), 1);
Zeny-=.@tax; // Player must pay the taxes
.@tp=POL_LocToTP(.@loc$);
/*
if (#EXILED & .@tp)
Zeny=max(0, Zeny-.@tax);
*/
}
return;
}
// Adjusts prices for crafts
// POL_AdjustPrice( price, {TOWNCODE} )
function script POL_AdjustPrice {
.@p=getarg(0);
.@l$=strtoupper(getarg(1, LOCATION$));
// Town Admin is always tax exempt
if (getd("$" + .@l$ + "_MAYOR$") == strcharinfo(0))
.@p=0;
// Town option for tax immunity
if (getd("$" + .@l$ + "_TAXOFF") && !(#EXILED & POL_LocToTP(.@l$))) {
.@vat=getd("$"+.@l$+"_TAX");
.@tax=.@p*.@vat/10000;
.@p-=.@tax;
}
// Return adjusted price
return .@p;
}
// Change a town money at player expense
// POL_PlayerMoney( price, {TOWNCODE} )
function script POL_PlayerMoney {
.@p=getarg(0);
.@l$=strtoupper(getarg(1, LOCATION$));
.@t=POL_LocToTP(.@l$);
MonsterMoney += (.@p / 5); // MK Control
Zeny-=.@p;
// Town option for tax immunity
if (getd("$" + .@l$ + "_TAXOFF") && !(#EXILED & POL_LocToTP(.@l$))) {
return 0;
}
// Calculate tax and add to town vault
.@vat=getd("$"+.@l$+"_TAX");
.@tax=.@p*.@vat/10000;
.@GP=getd("$" + .@l$ + "_MONEY");
if (playerattached()) {
if (is_gm())
dispbottom l("GP: %d + %d", .@GP, .@tax);
}
setd("$" + .@l$ + "_MONEY", .@GP+.@tax);
// Return the taxes paid
return .@tax;
}
- script Politics NPC_HIDDEN,{
// Daily Paperwork Penalty
OnClock2359:
if ($TULIM_DAILYQUEST != gettimeparam(GETTIME_DAYOFMONTH) && $TULIM_MAYOR$ != "Jesus Saves")
$TULIM_REPUTATION=limit(0, $TULIM_REPUTATION-2, 100);
if ($HALIN_DAILYQUEST != gettimeparam(GETTIME_DAYOFMONTH) && $HALIN_MAYOR$ != "Jesus Saves")
$HALIN_REPUTATION=limit(0, $HALIN_REPUTATION-2, 100);
if ($HURNS_DAILYQUEST != gettimeparam(GETTIME_DAYOFMONTH) && $HURNS_MAYOR$ != "Jesus Saves")
$HURNS_REPUTATION=limit(0, $HURNS_REPUTATION-2, 100);
if ($NIVAL_DAILYQUEST != gettimeparam(GETTIME_DAYOFMONTH) && $NIVAL_MAYOR$ != "Jesus Saves")
$NIVAL_REPUTATION=limit(0, $NIVAL_REPUTATION-2, 100);
if ($LOF_DAILYQUEST != gettimeparam(GETTIME_DAYOFMONTH) && $LOF_MAYOR$ != "Jesus Saves")
$LOF_REPUTATION=limit(0, $LOF_REPUTATION-2, 100);
if ($FROSTIA_DAILYQUEST != gettimeparam(GETTIME_DAYOFMONTH) && $FROSTIA_MAYOR$ != "Jesus Saves")
$FROSTIA_REPUTATION=limit(0, $FROSTIA_REPUTATION-2, 100);
if ($CANDOR_DAILYQUEST != gettimeparam(GETTIME_DAYOFMONTH) && $CANDOR_MAYOR$ != "Jesus Saves")
$CANDOR_REPUTATION=limit(0, $CANDOR_REPUTATION-2, 100);
end;
OnSun0000:
// Weekly reputation-based income (throttled to 50%)
$TULIM_MONEY+=$TULIM_EXPORT*limit(10, $TULIM_REPUTATION, 100)/200;
$HALIN_MONEY+=$HALIN_EXPORT*limit(10, $HALIN_REPUTATION, 100)/200;
$HURNS_MONEY+=$HURNS_EXPORT*limit(10, $HURNS_REPUTATION, 100)/200;
$LOF_MONEY+=$LOF_EXPORT*limit(10, $LOF_REPUTATION, 100)/200;
$NIVAL_MONEY+=$NIVAL_EXPORT*limit(10, $NIVAL_REPUTATION, 100)/200;
$FROSTIA_MONEY+=$FROSTIA_EXPORT*limit(10, $FROSTIA_REPUTATION, 100)/200;
$CANDOR_MONEY+=$CANDOR_EXPORT*limit(10, $CANDOR_REPUTATION, 100)/200;
// Weekly tax-based income
$TULIM_MONEY+=$TULIM_EXPORT*$TULIM_TAX*7/10000;
$HALIN_MONEY+=$HALIN_EXPORT*$HALIN_TAX*7/10000;
$HURNS_MONEY+=$HURNS_EXPORT*$HURNS_TAX*7/10000;
$LOF_MONEY+=$LOF_EXPORT*$LOF_TAX*7/10000;
$NIVAL_MONEY+=$NIVAL_EXPORT*$NIVAL_TAX*7/10000;
$FROSTIA_MONEY+=$FROSTIA_EXPORT*$FROSTIA_TAX*7/10000;
$CANDOR_MONEY+=$CANDOR_EXPORT*$CANDOR_TAX*7/10000;
// Send salary to Town Administrators (20% from exports and 5GP/reputation)
// Strange Coins: 1 each 10 reputation points
.@msg$=sprintf(
"You've received the money for the term (%02d/%02d, the %dth legislature)",
gettime(GETTIME_DAYOFMONTH),
gettime(GETTIME_MONTH),
gettimeparam(GETTIME_WEEKDAY));
.@tax=$TULIM_EXPORT/500;
.@tax+=$TULIM_REPUTATION*5;
.@tax=min($TULIM_MONEY, .@tax);
.@cp=limit(1, $TULIM_REPUTATION/10, 10);
$TULIM_MONEY-=.@tax;
rodex_sendmail(gf_charnameid($TULIM_MAYOR$), "Tulimshar Townhall", "Term Income", .@msg$, .@tax, StrangeCoin, .@cp);
.@tax=$HALIN_EXPORT/500;
.@tax+=$HALIN_REPUTATION*5;
.@tax=min($HALIN_MONEY, .@tax);
.@cp=limit(1, $HALIN_REPUTATION/10, 10);
$HALIN_MONEY-=.@tax;
rodex_sendmail(gf_charnameid($HALIN_MAYOR$), "Halinarzo Townhall", "Term Income", .@msg$, .@tax, StrangeCoin, .@cp);
.@tax=$HURNS_EXPORT/500;
.@tax+=$HURNS_REPUTATION*5;
.@tax=min($HURNS_MONEY, .@tax);
.@cp=limit(1, $HURNS_REPUTATION/10, 10);
$HURNS_MONEY-=.@tax;
rodex_sendmail(gf_charnameid($HURNS_MAYOR$), "Hurnscald Townhall", "Term Income", .@msg$, .@tax, StrangeCoin, .@cp);
.@tax=$LOF_EXPORT/500;
.@tax+=$LOF_REPUTATION*5;
.@tax=min($LOF_MONEY, .@tax);
.@cp=limit(1, $LOF_REPUTATION/10, 10);
$LOF_MONEY-=.@tax;
rodex_sendmail(gf_charnameid($LOF_MAYOR$), "LoF Townhall", "Term Income", .@msg$, .@tax, StrangeCoin, .@cp);
.@tax=$NIVAL_EXPORT/500;
.@tax+=$NIVAL_REPUTATION*5;
.@tax=min($NIVAL_MONEY, .@tax);
.@cp=limit(1, $NIVAL_REPUTATION/10, 10);
$NIVAL_MONEY-=.@tax;
rodex_sendmail(gf_charnameid($NIVAL_MAYOR$), "Nivalis Townhall", "Term Income", .@msg$, .@tax, StrangeCoin, .@cp);
/* Towns with volunteer town admins
.@tax=$FROSTIA_EXPORT/500;
.@tax+=$FROSTIA_REPUTATION*5;
.@tax=min($FROSTIA_MONEY, .@tax);
.@cp=limit(1, $FROSTIA_REPUTATION/10, 10);
$FROSTIA_MONEY-=.@tax;
rodex_sendmail(gf_charnameid($FROSTIA_MAYOR$), "Frostia Townhall", "Term Income", .@msg$, .@tax, StrangeCoin, .@cp);
.@tax=$CANDOR_EXPORT/500;
.@tax+=$CANDOR_REPUTATION*5;
.@tax=min($CANDOR_MONEY, .@tax);
.@cp=limit(1, $CANDOR_REPUTATION/10, 10);
$CANDOR_MONEY-=.@tax;
rodex_sendmail(gf_charnameid($CANDOR_MAYOR$), "Candor Townhall", "Term Income", .@msg$, .@tax, StrangeCoin, .@cp);
*/
// Conduct elections
.@w=array_highest($TULIM_VOTES);
if ($TULIM_CANDIDATE$[.@w] != "")
$TULIM_MAYOR$=$TULIM_CANDIDATE$[.@w];
deletearray($TULIM_CANDIDATE$);
deletearray($TULIM_VOTES);
array_push($TULIM_CANDIDATE$, ($TULIM_REPUTATION < 15 ? "Jesus Saves" : $TULIM_MAYOR$));
array_push($TULIM_VOTES, 0);
.@w=array_highest($HALIN_VOTES);
if ($HALIN_CANDIDATE$[.@w] != "")
$HALIN_MAYOR$=$HALIN_CANDIDATE$[.@w];
deletearray($HALIN_CANDIDATE$);
deletearray($HALIN_VOTES);
array_push($HALIN_CANDIDATE$, ($HALIN_REPUTATION < 15 ? "Jesus Saves" : $HALIN_MAYOR$));
array_push($HALIN_VOTES, 0);
.@w=array_highest($HURNS_VOTES);
if ($HURNS_CANDIDATE$[.@w] != "")
$HURNS_MAYOR$=$HURNS_CANDIDATE$[.@w];
deletearray($HURNS_CANDIDATE$);
deletearray($HURNS_VOTES);
array_push($HURNS_CANDIDATE$, ($HURNS_REPUTATION < 15 ? "Jesus Saves" : $HURNS_MAYOR$));
array_push($HURNS_VOTES, 0);
.@w=array_highest($LOF_VOTES);
if ($LOF_CANDIDATE$[.@w] != "")
$LOF_MAYOR$=$LOF_CANDIDATE$[.@w];
deletearray($LOF_CANDIDATE$);
deletearray($LOF_VOTES);
array_push($LOF_CANDIDATE$, ($LOF_REPUTATION < 15 ? "Jesus Saves" : $LOF_MAYOR$));
array_push($LOF_VOTES, 0);
.@w=array_highest($NIVAL_VOTES);
if ($NIVAL_CANDIDATE$[.@w] != "")
$NIVAL_MAYOR$=$NIVAL_CANDIDATE$[.@w];
deletearray($NIVAL_CANDIDATE$);
deletearray($NIVAL_VOTES);
array_push($NIVAL_CANDIDATE$, ($NIVAL_REPUTATION < 15 ? "Jesus Saves" : $NIVAL_MAYOR$));
array_push($NIVAL_VOTES, 0);
.@w=array_highest($FROSTIA_VOTES);
if ($FROSTIA_CANDIDATE$[.@w] != "")
$FROSTIA_MAYOR$=$FROSTIA_CANDIDATE$[.@w];
deletearray($FROSTIA_CANDIDATE$);
deletearray($FROSTIA_VOTES);
array_push($FROSTIA_CANDIDATE$, ($FROSTIA_REPUTATION < 15 ? "Jesus Saves" : $FROSTIA_MAYOR$));
array_push($FROSTIA_VOTES, 0);
.@w=array_highest($CANDOR_VOTES);
if ($CANDOR_CANDIDATE$[.@w] != "")
$CANDOR_MAYOR$=$CANDOR_CANDIDATE$[.@w];
deletearray($CANDOR_CANDIDATE$);
deletearray($CANDOR_VOTES);
array_push($CANDOR_CANDIDATE$, ($CANDOR_REPUTATION < 15 ? "Jesus Saves" : $CANDOR_MAYOR$));
array_push($CANDOR_VOTES, 0);
// Notify new mayors of their victory
rodex_sendmail(gf_charnameid($TULIM_MAYOR$), "Tulimshar Townhall", "Election Victory", "You've been elected to the office!");
rodex_sendmail(gf_charnameid($HALIN_MAYOR$), "Halinarzo Townhall", "Election Victory", "You've been elected to the office!");
rodex_sendmail(gf_charnameid($HURNS_MAYOR$), "Hurnscald Townhall", "Election Victory", "You've been elected to the office!");
rodex_sendmail(gf_charnameid($LOF_MAYOR$), "LoF Townhall", "Election Victory", "You've been elected to the office!");
rodex_sendmail(gf_charnameid($NIVAL_MAYOR$), "Nivalis Townhall", "Election Victory", "You've been elected to the office!");
// Towns where admins are named, instead of elected
//rodex_sendmail(gf_charnameid($FROSTIA_MAYOR$), "Frostia Townhall", "Election Victory", "You've been elected to the office!");
//rodex_sendmail(gf_charnameid($CANDOR_MAYOR$), "Candor Townhall", "Election Victory", "You've been elected to the office!");
end;
}
/////////////////////////
// Dialog helpers
// General info
// POL_Information( )
function script POL_Information {
mesc l("Weekly, at Sunday 00:00, elections are held.");
mesc l("The current town administrator will be inscribed for re-election automatically.");
mesc l("However, if town has less than 15 reputation, they'll need to re-apply manually, and may lose the office for the bot account.");
dnext;
mesc l("Town Administrator can use the town money for investments, and also receive a salary depending on how well the town is.");
next;
mesc l("A player may be the town admin of several different towns.");
mesc l("However, an account may only apply for an office weekly.");
mesc l("The account with highest votes will win. Ties will be solved by randomness.");
mesc l("An account may vote anywhere, but only once per town (weekly).");
next;
mesc l("The town administrator benefits for free services on the town.");
mesc l("Also, they can control the city taxes, which are applied upon purchases and sales within the town.");
mesc l("However, they must visit their town office and do daily paperwork, every day. Otherwise, town reputation will go down.");
mesc l("If town reputation reaches zero, the town will only be able to get money with taxes.");
return;
}
// Candidate Info and voting
// POL_Candidate( TOWNCODE )
function script POL_Candidate {
copyarray( .@cd$, getd("$"+getarg(0)+"_CANDIDATE$"), getarraysize(getd("$"+getarg(0)+"_CANDIDATE$")) );
copyarray( .@vt, getd("$"+getarg(0)+"_VOTES"), getarraysize(getd("$"+getarg(0)+"_VOTES")) );
.@list$="Don't vote";
for (.@i=0;.@i<getarraysize(.@cd$);.@i++) {
mesc .@cd$[.@i] + " - "+.@vt[.@i] + " " + l("votes");
.@list$+=":"+.@cd$[.@i];
}
next;
if (#POL_VOTEDAY[POL_LocToTP(getarg(0))] == gettimeparam(GETTIME_WEEKDAY))
return;
mesc l("In whom to vote?");
select .@list$;
.@vote=@menu-2;
// Didn't vote
if (.@vote < 0)
return;
// You cannot vote on yourself
if (getd("$"+getarg(0)+"_CANDIDATE$"+"["+.@vote+"]") == strcharinfo(0)) {
mesc l("You cannot vote on yourself!"), 1;
// mesc l("Use an alt char to do that.");
return;
}
// Cast the vote
#POL_VOTEDAY[POL_LocToTP(getarg(0))]=gettimeparam(GETTIME_WEEKDAY);
.@str$="$"+getarg(0)+"_VOTES"+"["+.@vote+"]";
.@vt=getd(.@str$);
setd(.@str$, .@vt+1);
mesc l("The vote was cast."), 3;
mesc l("You supported: ")+getd("$"+getarg(0)+"_CANDIDATE$"+"["+.@vote+"]"), 3;
next;
return true;
}
// Town info
// POL_TownInfo( TOWNCODE )
function script POL_TownInfo {
.@MAYOR$=getd("$"+getarg(0)+"_MAYOR$");
.@GP=getd("$"+getarg(0)+"_MONEY");
.@TX=getd("$"+getarg(0)+"_TAX");
.@EX=getd("$"+getarg(0)+"_EXPORT");
.@RP=getd("$"+getarg(0)+"_REPUTATION");
if (strcharinfo(0) == .@MAYOR$ || is_gm()) {
mesc l("Town Money: @@", .@GP), 2;
mesc l("Town Reputation: %d | %d.%02d %% Tax", .@RP, .@TX/100, .@TX%100), 2;
mesc l("Town Weekly Exports: @@", .@EX), 2;
} else {
mesc l("Town Tax: %d.%02d %%", .@TX/100, .@TX%100), 2;
}
return;
}
// Town Management
// POL_Manage( TOWNCODE )
function script POL_Manage {
.@town$="$"+getarg(0);
.@MAYOR$=getd("$"+getarg(0)+"_MAYOR$");
.@TP=POL_LocToTP(getarg(0));
if (strcharinfo(0) != .@MAYOR$)
return;
// How many actions do you have?
// You get 1 action/4-hour, capped to 6
.@left=(gettimeparam(GETTIME_HOUR)/4)-TOWN_ACTIONS[.@TP];
if (.@left > 6) {
.@left=6;
TOWN_ACTIONS[.@TP]=(gettimeparam(GETTIME_HOUR)/4)-6;
}
do
{
.@GP=getd("$"+getarg(0)+"_MONEY");
.@TX=getd("$"+getarg(0)+"_TAX");
.@EX=getd("$"+getarg(0)+"_EXPORT");
.@RP=getd("$"+getarg(0)+"_REPUTATION");
.@CR=getd("$"+getarg(0)+"_TAXOFF");
.@DQ=getd("$"+getarg(0)+"_DAILYQUEST");
.@SE=getd("$"+getarg(0)+"_SIEGEXP");
.@left=(gettimeparam(GETTIME_HOUR)/4)-TOWN_ACTIONS[.@TP];
.@repeat = .@left;
mesc l("Town Money: @@", .@GP), 2;
mesc l("Town Reputation: %d | %d.%02d %% Tax", .@RP, .@TX/100, .@TX%100), 2;
mesc l("Town Weekly Exports: @@", .@EX), 2;
mesc l("Total actions left: %d", .@left), (.@left > 1 ? 9 : 1);
if (#EXILED & .@TP)
mesc l("WARNING: A previous town admin exiled you. The effects will persist unless you revert your own exile."), 1;
next;
menuint
l("Nothing"), 0,
rif(.@DQ != gettimeparam(GETTIME_DAYOFMONTH), l("Do some paperwork")), 1,
rif(.@left, l("Invest into boosting town exports")), 10,
rif(.@left > 1, l("Invest all into boosting town exports")), 11,
rif(.@left, l("Invest into boosting town reputation")), 20,
rif(.@left > 1, l("Invest all into boosting town reputation")), 21,
rif(.@left, l("Raise city taxes")), 30,
rif(.@left, l("Lower city taxes")), 35,
rif(.@CR && .@RP, l("Tax crafters")), 40,
rif(!.@CR, l("Don't tax crafters")), 41,
rif(.@left && !.@SE && $GAME_STORYLINE < 5, l("Town Defense Program")), 60,
rif(.@left >= 6, l("Exile a player")), 70,
rif(.@left >= 6, l("Revert a player exile")), 71,
rif(.@left, l("Raise server wide EXP")), 80,
rif(Zeny > $ALLIANCE_TAX1, l("Donate to town")), 90,
l("Resign"), 99;
mes "";
switch (@menuret) {
// Mark 0: Cycle
case 1:
if (rand2(3) == 1)
setd(.@town$+"_REPUTATION", limit(0, .@RP+1, 100));
setd(.@town$+"_DAILYQUEST", gettimeparam(GETTIME_DAYOFMONTH));
getexp rand2(BaseLevel+JobLevel), rand2(BaseLevel+JobLevel);
Mobpt += rand2(JobLevel);
mesc l("You dealt with paperwork."), 2;
break;
// Mark 10: Exports
case 10:
.@repeat = 1;
// fall-through
case 11:
// direct formula exists, but is difficult to implement with integer math:
// k = (10 + rand(1/52, 1/24))/10; newEX = k^.@repeat*.@EX + (1-k^.@repeat)/(1-k)
.@newEX = .@EX;
for(.@i = 0; .@i < .@repeat; .@i += 1) {
.@cost = .@newEX/10;
.@newEX += rand2(.@cost/52, .@cost/24) + 1;
}
// to prevent GP cost fluctuating in the menu (excuse for bulk discount):
.@cost = .@repeat * .@EX/10;
mesc l("Investing in Exportations"), 3;
mesc l("You need @@ GP to make this investment.", .@cost);
if (.@GP < .@cost)
break;
mesc l("Are you sure?");
if (askyesno() == ASK_YES) {
.@GP=getd("$"+getarg(0)+"_MONEY");
setd(.@town$+"_MONEY", .@GP-.@cost);
setd(.@town$+"_EXPORT", .@newEX);
TOWN_ACTIONS[.@TP] += .@repeat;
mesc l("Investment executed"), 2;
next;
}
break;
// Mark 20: Reputation
case 20:
.@repeat = 1;
// fall-through
case 21:
.@repeat = max(1, min(.@repeat, 100 - .@RP));
.@cost = .@repeat * .@RP * 3;
mesc l("Investing into Reputation"), 3;
if (.@RP >= 100) {
mesc l("Reputation cannot go above 100!"), 1;
next;
break;
}
mesc l("You need @@ GP to make this investment.", .@cost);
if (.@GP < .@cost)
break;
mesc l("Are you sure?");
if (askyesno() == ASK_YES) {
.@GP=getd("$"+getarg(0)+"_MONEY");
setd(.@town$+"_MONEY", .@GP - .@cost);
setd(.@town$+"_REPUTATION", .@RP + .@repeat);
TOWN_ACTIONS[.@TP] += .@repeat;
mesc l("Investment executed"), 2;
next;
}
break;
// Mark 30: TAXES and Tax Governance
case 30:
.@cost=.@TX/12;
mesc l("Raising Taxes"), 3;
mesc l("You need @@ Reputation to make this investment.", .@cost);
mesc l("Taxes will raise in 0.02~0.05%, capped at 15%.");
if (.@RP < .@cost || .@TX >= 1500)
break;
mesc l("Are you sure?");
if (askyesno() == ASK_YES) {
setd(.@town$+"_REPUTATION", .@RP-.@cost);
setd(.@town$+"_TAX", .@TX+rand2(2,5));
TOWN_ACTIONS[.@TP]+=1;
mesc l("Taxes raised"), 1;
next;
}
break;
case 35:
.@cost=.@TX/32;
mesc l("Lowering Taxes"), 3;
mesc l("You will gain @@ Reputation.", .@cost);
mesc l("Taxes will fall in 0.01~0.03%, capped at 0.00%");
if (.@TX <= 0 || .@RP >= 100)
break;
mesc l("Are you sure?");
if (askyesno() == ASK_YES) {
.@val=.@TX-(.@cost ? rand2(1,3) : 1);
setd(.@town$+"_TAX", max(0, .@val));
setd(.@town$+"_REPUTATION", min(100, .@RP+.@cost));
TOWN_ACTIONS[.@TP]+=1;
mesc l("Taxes lowered"), 1;
next;
}
break;
// Mark 40: Tax Crafters and Town Policies
case 40:
setd("$"+getarg(0)+"_TAXOFF", false);
setd(.@town$+"_REPUTATION", .@RP-1);
mesc l("Crafters are now paying taxes."), 1;
break;
case 41:
setd("$"+getarg(0)+"_TAXOFF", true);
setd(.@town$+"_REPUTATION", .@RP+1);
mesc l("Crafters no longer pays taxes. (Tax exempt)"), 1;
break;
// Mark 60: Global events interference
case 60:
.@cost = 2000 - (.@RP * 10);
mesc l("Town Defense Program"), 3;
mesc l("You need @@ GP to make this investment.", .@cost);
mesc l("This program will cause experience gain to be tripled during the next siege to the town.");
if (.@GP < .@cost)
break;
mesc l("Are you sure?");
if (askyesno() == ASK_YES) {
setd(.@town$+"_SIEGEXP", 1);
setd(.@town$+"_MONEY", .@GP-.@cost);
TOWN_ACTIONS[.@TP]+=1;
mesc l("Town Defense Program enabled."), 1;
next;
}
break;
// Mark 70: Exile and Player functions
case 70:
mesc l("Exiled players will not be able to save to menhir."), 1;
mesc l("A global announcement will be made."), 1;
mesc l("Player must be online for the operation to finish."), 1;
mesc l("This will cost you all your action points."), 1;
next;
mesc l("Please insert player name to exile."), 1;
input .@ex$;
if (.@ex$ == "")
break;
.@id=getcharid(3, .@ex$);
if (.@id < 1) {
mesc l("The player is offline or does not exist.");
break;
}
if (.@id == getcharid(3)) {
mesc l("You cannot exile yourself!");
break;
}
.@town=POL_LocToTP(getarg(0));
.@you=getcharid(3);
attachrid(.@id);
dispbottom l("You have been EXILED from %s by %s.", getarg(0), .@MAYOR$);
#EXILED=#EXILED|.@town;
.@l$=LocToMap(TPToLoc(.@town));
if (getsavepoint(0) == .@l$)
savepoint "000-1", 22, 22;
// LOCATION$ will be redefined once you leave so no worries
detachrid();
attachrid(.@you);
kamibroadcast(sprintf("%s has EXILED %s from %s.",
.@MAYOR$, .@ex$, getarg(0)));
TOWN_ACTIONS[.@TP]+=6;
break;
case 71:
mesc l("Please insert player name to cancel exile."), 1;
mesc l("Player must be online for the operation to finish."), 1;
mesc l("This will cost you all your action points."), 1;
input .@ex$;
if (.@ex$ == "")
break;
.@id=getcharid(3, .@ex$);
if (.@id < 1) {
mesc l("The player is offline or does not exist.");
break;
}
.@town=POL_LocToTP(getarg(0));
.@you=getcharid(3);
attachrid(.@id);
if (#EXILED & .@town) {
dispbottom l("You are NO LONGER EXILED from %s by %s.", getarg(0), .@MAYOR$);
#EXILED=#EXILED^.@town;
}
detachrid();
attachrid(.@you);
kamibroadcast(sprintf("%s has ANNULLED THE EXILE %s from %s.",
.@MAYOR$, .@ex$, getarg(0)));
TOWN_ACTIONS[.@TP]+=6;
break;
// Mark 80: Town and Server Governance
case 80:
.@gcost=50000;
.@rcost=25;
.@b=5+(.@RP/10);
.@time = ($GAME_STORYLINE >= 5 ? 3 : 2);
if ($GAME_STORYLINE >= 5)
.@b = .@b * 3 / 2; // 50% Bonus after MK is dead
mesc l(".:: Server Boom ::."), 3;
mesc l("To cause a server happy hour (+%d%% EXP), you need:", .@b);
mesc l("%s GP and %d REP.", fnum(.@gcost), .@rcost);
tutmes l("* Actual effect lasts %d hours.", .@time), l("Note"), false;
if (.@RP < .@rcost || .@GP < .@gcost)
break;
mesc l("Are you sure?");
if (askyesno() == ASK_YES) {
setd(.@town$+"_REPUTATION", .@RP-.@rcost);
setd(.@town$+"_MONEY", .@GP-.@gcost);
TOWN_ACTIONS[.@TP]+=1;
mesc l("Server Happy Hour Decreed"), 1; // Will not be shown
kamibroadcast(sprintf("%s has sponsored a Server Happy Hour using tax money!", .@MAYOR$));
// Effective immediately
$@EXP_EVENT=.@b;
$@EXP_EVENT_TIME=.@time;
donpcevent "@exprate::OnPlayerCall";
// Drop Rate will apply, ONLY IF Monster King has been defeated
if ($GAME_STORYLINE >= 5) {
$@DROP_EVENT=.@b * any(1,1,2,2,3) / 3;
$@DROP_EVENT_TIME=3;
donpcevent "@droprate::OnPlayerCall";
}
// We must terminate dialog now and close all context for EXPRATE.
closeclientdialog;
end;
}
break;
// Mark 90: Office
case 90:
mesc l("The alliance will take %s GP as fee, +%d%% tax over donations.", fnum($ALLIANCE_TAX1), $ALLIANCE_TAX2), 1;
mesc l("You can donate up to %s GP.", fnum(Zeny-$ALLIANCE_TAX1));
input .@donate, 0, Zeny-$ALLIANCE_TAX1;
if (.@donate <= 0)
break;
Zeny -= $ALLIANCE_TAX1;
.@tax = .@donate * (100-$ALLIANCE_TAX2) / 100;
setd(.@town$+"_MONEY", .@GP+.@tax);
Zeny -= .@donate;
mesc l("Donation completed."), 2;
break;
case 99:
mesc l("Really resign?"), 1;
next;
if (askyesno() == ASK_YES) {
setd(.@town$+"_MAYOR$", "Jesus Saves");
// If you have already received a vote, this will be skipped
if (getd(.@town$+"_VOTES[0]") <= 0 &&
getd(.@town$+"_CANDIDATE$[0]") == strcharinfo(0))
setd(.@town$+"_CANDIDATE$[0]", "Jesus Saves");
mesc l("YOU HAVE RESIGNED THE OFFICE."), 1;
close;
}
default:
return;
}
// End script
} while (true);
return;
}