summaryrefslogblamecommitdiff
path: root/npc/functions/politics.txt
blob: df7b0d61d6f28b531c9ac57ae0e1f6b22714de69 (plain) (tree)
1
2
3
4
5
6
7
8






                                                                                 
                                  






                                                                             



                                                 





                                                            
                                   







                                                                                        
                                       
                                              


                                    



           
                                                    



                                                          
                                   




                                                                   
                                                                     


                                                                                              
                                       
                                              
                                                                                                                   



                                    



           



                                         
                                              

                                          
                                                           


                                       
                                           












                                            
                                              




                                       
                                           





                                              





                                                     




                                

                                            

                          
                                                                                                
                                                             
                                                                                                
                                                             
                                                                                                
                                                             
                                                                                                
                                                             
                                                                                            
                                                         
                                                                                                    


                                                                 
          
                    





                                                                            




                                                                               
                        




                                                                                                                                        
                        




                                                                                                                                        
                        




                                                                                                                                        
                      




                                                                                                                                
                        




                                                                                                                                      
                          


                                                                                                                                        




                                             

                                                 
 




                                             

                                                 





                                             

                                                 





                                         

                                             





                                             

                                                 





                                                 

                                                     








                                                                                                                                 
        









                                                           
                                                                                              



                                                                                                                                      

                                                                                          
         

                                                                                                            

                                                                                                                                     







                                                                                                           
 
                         

                                                             
                                


         
                                                                              

                               

                   




                   
                                  
                                                                             




                                                  
                    
                                                                       
                                                 



                                    
                                                                                  

                

 
 







                                           
                                                
                                          
                                                                                    




                                                   
 

                 

                                         











                                           
                                       
                                           

                                      
                                                                                



                                               
                                                                                 



                                        

                                                 

                                       


                        


                             
                                                                   


                                                                          










                                                                      
                                                         


























                                                                      
                           























                                                                              
                                           


                     










                                                                     



















                                                                                     

                                                             
                                                                       


























                                                                                             




                                        
                                                       
                                                                            
                                                     
                                                                     
                                                                  












                                                           
// 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];
    }
    .@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];
    }
    .@loc$=strtoupper(getarg(0, LOCATION$));
    .@vat=getd("$"+.@loc$+"_TAX");
    .@vat=.@vat*2/10; // Only 20% of purchase tax, this is often 0.2%
    .@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;
        .@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")) {
		.@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$);

	Zeny-=.@p;

	// Town option for tax immunity
	if (getd("$" + .@l$ + "_TAXOFF")) {
		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);
    end;

OnSun0000:
    // Weekly income
    $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;

    // Send salary to Town Administrators (20% from exports and 5GP/reputation)
    .@tax=$TULIM_EXPORT*limit(0, $TULIM_REPUTATION, 100)/500;
    .@tax+=$TULIM_REPUTATION*5;
    .@tax=min($TULIM_MONEY, .@tax);
    $TULIM_MONEY-=.@tax;
    rodex_sendmail(gf_charnameid($TULIM_MAYOR$), "Tulimshar Townhall", "Term Income", "You've received the money for the term.", .@tax);

    .@tax=$HALIN_EXPORT*limit(0, $HALIN_REPUTATION, 100)/500;
    .@tax+=$HALIN_REPUTATION*5;
    .@tax=min($HALIN_MONEY, .@tax);
    $HALIN_MONEY-=.@tax;
    rodex_sendmail(gf_charnameid($HALIN_MAYOR$), "Halinarzo Townhall", "Term Income", "You've received the money for the term.", .@tax);

    .@tax=$HURNS_EXPORT*limit(0, $HURNS_REPUTATION, 100)/500;
    .@tax+=$HURNS_REPUTATION*5;
    .@tax=min($HURNS_MONEY, .@tax);
    $HURNS_MONEY-=.@tax;
    rodex_sendmail(gf_charnameid($HURNS_MAYOR$), "Hurnscald Townhall", "Term Income", "You've received the money for the term.", .@tax);

    .@tax=$LOF_EXPORT*limit(0, $LOF_REPUTATION, 100)/500;
    .@tax+=$LOF_REPUTATION*5;
    .@tax=min($LOF_MONEY, .@tax);
    $LOF_MONEY-=.@tax;
    rodex_sendmail(gf_charnameid($LOF_MAYOR$), "LoF Townhall", "Term Income", "You've received the money for the term.", .@tax);

    .@tax=$NIVAL_EXPORT*limit(0, $NIVAL_REPUTATION, 100)/500;
    .@tax+=$NIVAL_REPUTATION*5;
    .@tax=min($NIVAL_MONEY, .@tax);
    $NIVAL_MONEY-=.@tax;
    rodex_sendmail(gf_charnameid($NIVAL_MAYOR$), "Nivalis Townhall", "Term Income", "You've received the money for the term.", .@tax);

    .@tax=$FROSTIA_EXPORT*limit(0, $FROSTIA_REPUTATION, 100)/500;
    .@tax+=$FROSTIA_REPUTATION*5;
    .@tax=min($FROSTIA_MONEY, .@tax);
    $FROSTIA_MONEY-=.@tax;
    rodex_sendmail(gf_charnameid($FROSTIA_MAYOR$), "Frostia Townhall", "Term Income", "You've received the money for the term.", .@tax);

    // 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_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_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_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_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_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_MAYOR$);
    array_push($FROSTIA_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!");
    rodex_sendmail(gf_charnameid($FROSTIA_MAYOR$), "Frostia 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("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 incide 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;
    }
    return;
}



// Town Managment
// POL_Manage( TOWNCODE )
function	script	POL_Manage	{
    .@town$="$"+getarg(0);
    .@MAYOR$=getd("$"+getarg(0)+"_MAYOR$");

    if (strcharinfo(0) != .@MAYOR$)
        return;

    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");

    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;
    next;
    menuint
        l("Nothing"), 0,
        rif(.@DQ != gettimeparam(GETTIME_DAYOFMONTH), l("Do some paperwork")), 1,
        l("Invest in Exportations"), 10,
        l("Invest in Reputation"), 20,
        l("Raise city taxes"), 30,
        l("Lower city taxes"), 35,
        rif(.@CR && .@RP, l("Tax crafters")), 40,
        rif(!.@CR, l("Don't tax crafters")), 41,
        l("Exile a player"), 70,
        l("Revert a player exile"), 71,
        l("Resign"), 99;
    mes "";
    switch (@menuret) {
        // Mark 0: Cycle
        case 1:
            if (rand(3) == 1)
                setd(.@town$+"_REPUTATION", limit(0, .@RP+1, 100));
            setd(.@town$+"_DAILYQUEST", gettimeparam(GETTIME_DAYOFMONTH));
            mesc l("You dealt with paperwork."), 2;
            break;
        // Mark 10: Exports
        case 10:
            .@cost=.@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", .@EX+rand2(4,6));
                mesc l("Investment executed"), 2;
                next;
            }
            break;
        // Mark 20: Reputation
        case 20:
            .@cost=.@RP*3;
            mesc l("Investing in 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+1);
                mesc l("Investment executed"), 2;
                next;
            }
            break;
        // Mark 30: TAXES
        case 30:
            .@cost=.@TX/11;
            mesc l("Raising Taxes"), 3;
            mesc l("You need @@ Reputation to make this investment.", .@cost);
            mesc l("Taxes will raise in 0.01~0.03%, capped at 10%.");
            if (.@RP < .@cost || .@TX >= 1000)
                break;
            mesc l("Are you sure?");
            if (askyesno() == ASK_YES) {
                setd(.@town$+"_REPUTATION", .@RP-.@cost);
                setd(.@town$+"_TAX", .@TX+rand2(1,3));
                mesc l("Taxes raised"), 1;
                next;
            }
            break;
        case 35:
            .@cost=.@TX/30;
            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) {
                setd(.@town$+"_TAX", max(0, .@TX-.@cost));
                setd(.@town$+"_REPUTATION", min(100, .@RP+.@cost));
                mesc l("Taxes lowered"), 1;
                next;
            }
            break;
        // Mark 40: Tax Crafters
		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 70: Exile
        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;
            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;
            }
            .@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;
            if (getsavepoint(0) == LocToMap(TPToLoc(.@town)))
                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)));
            break;
        case 71:
            mesc l("Please insert player name to cancel 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;
            }
            .@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 ANNULED THE EXILE %s from %s.",
                          .@MAYOR$, .@ex$, getarg(0)));
            break;
        // Mark 90: Office
        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;
}