The International Simutrans Forum

Community => Social & Contests => Scenarios and Challenges => Topic started by: ny911 on November 23, 2009, 06:24:03 PM

Title: New York City - pak128
Post by: ny911 on November 23, 2009, 06:24:03 PM
savegame for Simutrans 102.2.1 2859, pak128 1.4.5-102

Introduction

We are writing the year 1960 and the mayor of the City New York has a great vision, a city
with a useful public transport system. So he starts to collect money from all towns in the
area, including Jersey too. After a time the bank account shows 2.000.000 for his great vision.

Now he is looking up for a skilled manager of the new public transport company. Quit difficult,
because nearly everyone is asking him a lot of questions. The mayor decided to creat a list of facts:

start year1960
money 2.000.000
map-size 1024*1024
inhabitants 2.200.000
cities~80
factories~70
public airports  5
public markers a lot

And the visionary mayor did also make an very short list of the rules from the city council decisions :

If this challenge is yours, start being the manager of a great public transport system in New York City.

(http://simutrans-germany.com/files/upload/new_york_city_1_0_map.png)
(http://simutrans-germany.com/files/upload/new_york_city_1_0_view.jpg)

savegame: http://ul.to/urrxp7 (http://ul.to/urrxp7)

(edit: savegame is now exactly starting 1960/jan/01 )
(note: first version of scenario is placed in pak128 scenario folder)
(UPDATE 2013/01/26: http://forum.simutrans.com/index.php?topic=3812.msg111322#msg111322 (http://forum.simutrans.com/index.php?topic=3812.msg111322#msg111322))

notes:
I tried to make a realistic map of the NYC area. In just a view points I changed it. The local Towns are more or less at the right place. I ad more/bigger rivers. The buildings in Manhattan are partly to small, but otherwise it would be to much population. For a lot of sightseeing points (Statue of Liberty, WTC, UN-Building, Empire State, Times Square, ...) are only normal attractions form the pak128 used. At the airports there are a lot of attraction to get a bit of passenger traffic.
Title: Re: New York City - pak128
Post by: Anime on November 23, 2009, 06:35:26 PM
Nice! Finally an interesting challenge. I'll have a look at it immediatly :p

Edit :
It's a bit too big lol. It's hard to start anywhere on the map, have you already started the challenge?
Title: Re: New York City - pak128
Post by: ny911 on November 23, 2009, 07:24:37 PM
Yes, I played it one time to find the things which need to be corrected.
I started at Downtown, D.-Brooklyn, Greenwich bringing people to the factories.
Title: Re: New York City - pak128
Post by: Anime on November 23, 2009, 07:30:19 PM
can you post your save? How did you do all the stops? and which vehicles do you use?
Title: Re: New York City - pak128
Post by: ny911 on November 23, 2009, 07:54:58 PM
my game will folllow later. Yes, to make the stops takes a long time (weeks).
The question after the vehicles is difficult. I take all kind, train, tram, bus, ship.
For Manhattan I use a lot (about 10) subway trains in a multi-level-underground.
Main Trains: RVg Hiawatha Express (to earn money) and SHI D-231 "Shy" for mass transport
Main Bus: mostly the newest one
Main Tram: Due WAG GT6
Title: Re: New York City - pak128
Post by: Anime on November 25, 2009, 06:33:01 AM
can you post your save, so that we can see how it may look..?
Title: Re: New York City - pak128
Post by: AP on November 27, 2009, 04:12:29 PM
Have to say, that's quite a map!

Just to clarify, before I give it too much thought, the "aims" are

Title: Re: New York City - pak128
Post by: ny911 on November 29, 2009, 11:59:36 PM
Quote from: AP on November 27, 2009, 04:12:29 PM
Just to clarify, before I give it too much thought, the "aims" are


  • Reach a passenger delivery ratio of 0.95 (95%) in Midtown
  • build a BIG company HQ on Governor's Island
  • schedule fights to each of the to the 5x airports on the map

Yes! The flights might be also necessary for the passenger delivery ratio of 95%.

Quote from: Anime on November 25, 2009, 06:33:01 AM
can you post your save, so that we can see how it may look..?

Yes, when I manged all "aims". But here es a small preview.

I'm still trying to find a way to decrease the waiting passenger at the factory
in Greenwich and Lower East Side. And the "Washington Bridge" is a big bottleneck.
Title: Re: New York City - pak128
Post by: Anime on November 30, 2009, 06:41:32 AM
looks nice Ny911 :)
Title: Re: New York City - pak128
Post by: ny911 on December 01, 2009, 06:22:22 PM
Here it is! A savegame (pak128, 102.2.1) with a nearly full public transportation system in NYC area.
Nearly 4000 vehicle, around 280 lines (express trains, subway, ferries, air, bus). I reached the 95%
in 1975/Jan. In Manhattan are partly more than five underground levels used. The Mail-Service is
still in process.

savegame : http://ul.to/ne9ie7 (http://ul.to/ne9ie7) ( new_york_city_1_v15.sve  12.3 MB)
Title: Re: New York City - pak128
Post by: Anime on December 01, 2009, 06:45:16 PM
Nice :p I'd love to start your challenge too, but I don't have enought time to :(
Title: Re: New York City - pak128
Post by: Dwachs on December 02, 2009, 10:32:01 AM
Really nice challenge!

Two questions:
I suppose the answer is 'No' to both questions, but I had to ask.
Title: Re: New York City - pak128
Post by: Spike on December 02, 2009, 10:43:16 AM
The central park airport itself must be underground, and starting and landing must be done through tunnels ;)

I bet someone will file that as change request soon ;D
Title: Re: New York City - pak128
Post by: ny911 on December 02, 2009, 11:42:09 AM
Quote from: Dwachs on December 02, 2009, 10:32:01 AM

  • Is it allowed to build more airports? Like in Central Park for example..
Well, we have no "city council decisions" which prohibit this. But I think it's
very unrealistic. And you will have big problems to carry all the people in the
60' with the small airplanes.


Quote from: Dwachs on December 02, 2009, 10:32:01 AM

  • Is it allowed to fuill up the Hudson river? then one can cross it without bridges ;)
;) Why not "Lower Bay" and "Upper Bay" too!
Answer : No
Title: Re: New York City - pak128
Post by: eddielexx on January 17, 2010, 07:58:50 PM
I'd like to know if I can edit this svegame, cuz I'd like to be able to allow new industries to form. And btw, is there any posibility for this map to be totally covered with cities, like real NYC?
Title: Re: New York City - pak128
Post by: ny911 on January 19, 2010, 10:14:56 PM
Quote from: eddielexx on January 17, 2010, 07:58:50 PM
I'd like to know if I can edit this svegame, cuz I'd like to be able to allow new industries to form.

Yes, look to your email box.

Quote from: eddielexx on January 17, 2010, 07:58:50 PM
And btw, is there any possibility for this map to be totally covered with cities, like real NYC?

Well, I tried it. I wasn't able to fix the problem with too much inhabitants.
If the cities outside Manhattan getting bigger (with small buildings only) , it's still to much.
Title: Re: New York City - pak128
Post by: eddielexx on January 20, 2010, 01:56:00 PM
U r the lord!!!!!
Thanky from my heart :D

I will post my savegame next week, I have exams this eek, so I am only playin for hour or two. I am concentrated on Industries now, so it is not very interesting in the beginnin, and when I develop industries, I will start makin passengers lines. OOO it is gonna be exciting :D THKU

And BTW, Simutrans has Population limit??
Title: Re: New York City - pak128
Post by: prissi on January 20, 2010, 10:25:55 PM
Technically yes, as some counters on the display will choke on on 2^31-1. But since this means more than level 100 on every tile of a 2096x4096 map, I am sure the routing of those masses will make the game unplayable much earlier.
Title: Re: New York City - pak128
Post by: ny911 on January 21, 2010, 02:59:12 PM
Quote from: prissi on January 20, 2010, 10:25:55 PM
I am sure the routing of those masses will make the game unplayable much earlier.

Yes, on the NYC-Map it's for me between 2^21 to 2^22 (depending on the PC) !!

In my opinion it would be great to have the opportunity to make different kind of cities
with the "found a new city" tool. So it may be more realistic in a view areas.
e.g.


Title: Re: New York City - pak128
Post by: eddielexx on January 27, 2010, 07:24:19 PM
Hey People !
I played this map, connecting Freight.
I have a problem, all my factories work on full power, and I simply can't build enough ships for hauling all those stuff, I have 10kt of steel in every single Dock that needs it :( How to get rid of it somehow? I have 19M debt and 1.5M of profit.... I simply can't stop building ships :D It is madness!!! I hope that one day I will see black numbers on my account balance place :D
I'm just afraid of bankruptcy. And yeah, I decided to start building public transport when I get in positive :D But it seems that my passenger will waiiit for long. If someone wants to fight with my debt, I can upload my savegame :D
Title: Re: New York City - pak128
Post by: jklamo on April 29, 2010, 12:32:00 AM
Great scenario. And very long. I suppose to complete it sometime in 2013 (real year, not game year) :-) Now i am in gameyear 1977, have 560 vehicles, fair profit and 25% of the goal..
Title: Re: New York City - pak128
Post by: asaphxiix on May 21, 2010, 09:52:23 AM
amazing. your fulfilled version of the scenario (15) is by far the coolest i've seen of this game so far (narrowly beats some guy's sve of the world airports)
Title: Re: New York City - pak128
Post by: Combuijs on September 18, 2010, 01:01:18 PM
The heightmap of this game is now available on Simutrans Maps under the name of New York City.
Title: Re: New York City - pak128
Post by: Gilles on July 06, 2011, 03:34:27 PM
Excuse me, but... does anyone still have the "blank" savegame?
Title: Re: New York City - pak128
Post by: ny911 on July 06, 2011, 05:28:22 PM
Quote from: Gilles on July 06, 2011, 03:34:27 PM
Excuse me, but... does anyone still have the "blank" savegame?
"blank" savegame ?

Title: Re: New York City - pak128
Post by: Gilles on July 08, 2011, 07:41:21 AM
Quote from: ny911 on July 06, 2011, 05:28:22 PM


  • savegame like in the first Post (start year 1960),
    that's a "blank" savegame for me

That one. The link was broken for me yesterday. Sorry. ;) Thanks anyway.
Title: Re: New York City - pak128
Post by: ny911 on January 07, 2013, 11:38:38 AM
first update of New York city scenario:

for nightly r6232 and pak128 2.2.0
script is only in english (beta version)

Link: New York City Scenario V 0.3 (zip 4.43 MB, download until 06. Apr 2013)
http://simutrans-germany.com/files/upload/new_york_city_beta_v03.zip (http://simutrans-germany.com/files/upload/new_york_city_beta_v03.zip)

It's a beta version scenario and it has 12 new extra stuff options/goals.
pleasce post your experiences, that I can improve scenario and find bugs.
Title: Re: New York City - pak128
Post by: Dwachs on January 07, 2013, 12:26:44 PM
 :thumbsup: superb progress!
Title: Re: New York City - pak128
Post by: eXtremeCZ on January 26, 2013, 09:46:18 PM
Amazing scenario, thank you :)
There's one thing that's annoying to me - station coverage 2. I have to build sooo many stops very close to each other. I enjoy connecting cities (disctricts), but not making so many stops in almost every street. But it's probably realistic, isn't it? :)
Title: Re: New York City - pak128
Post by: dennosius on January 26, 2013, 11:51:43 PM
It is a bit annoying. I switched to using underground (light) trains extensively for urban transportation. Usually in circular lines with station length 2, so it's 6x6 tiles covered by a station and less need to worry how the street above is.
Title: Re: New York City - pak128
Post by: Fifty on January 27, 2013, 03:07:44 AM
You can change station coverage on existing maps through the secret settings dialog:

Quote from: Fifty on May 29, 2012, 04:42:25 PM
Just open menuconf.tab, located in pakxyz/config, change
#dialog_tool[27]=
to some unused keyboard shortcut, for example "~" and remove the #
dialog_tool[27]=,~

Then open the game, press ~ (or whatever button you chose)

Once you have opened this dialogue in the game you want to change station coverage in, just switch to the routing tab, change "station_coverage" to whatever value you desire. Then close the dialog, save the game, and reload. Voila!
Title: Re: New York City - pak128
Post by: ny911 on January 27, 2013, 11:16:30 AM
Next Update:

New York City Scenario version 0.5 beta for nightly r6288 and pak128 2.2.0 r1140
http://simutrans-germany.com/files/upload/new_york_city_beta_v05.zip (http://simutrans-germany.com/files/upload/new_york_city_beta_v05.zip) (4,43 MB until 2013-07-04)

savegames from version 0.3  can be used (please give me feedback if there are problems).

New:
    more bonus stuff targets
    messages for player
    helptext with links
    and a lot more small things ....

still known problem: The "Airport-Tools" can't be enabled. Please delete script Line 497 completely.
Title: Re: New York City - pak128
Post by: ny911 on January 27, 2013, 11:34:44 AM
Quotechange station coverage
good to know, so I will have to change the script code watching the coverage, e.g. if coverage > 2 then pax target  > 98% or so. But I'm not sure if it's possible in the moment to catch the station coverage in the scenario scripting.

QuoteI have to build so many stops very close to each other.
first the work, then the fun of a great network! To have a some breaks in placing all the stops you can use the bonus stuff to have variety in your work.
Title: Re: New York City - pak128
Post by: Dwachs on February 01, 2013, 04:44:25 PM
Changing station coverage by script will not be possible, I am afraid. It has the potential to break a lot of things.
Title: Re: New York City - pak128
Post by: sdog on February 01, 2013, 07:19:49 PM
@ny911 would you mind to post a screenshot in this part of the thread? (Helps to post about it in social media).
Title: Re: New York City - pak128
Post by: ny911 on February 03, 2013, 02:06:46 PM
here are five screenshots (links for normal picture size):
Title: Re: New York City - pak128
Post by: sdog on February 09, 2013, 04:07:42 AM
thanks a lot.
sorry for the long delay though.
Title: Re: New York City - pak128
Post by: asaphxiix on February 09, 2013, 03:02:05 PM
nice! I guess you haven't gotten around to do the other 4 boroughs... and jersey :)
Title: Re: New York City - pak128
Post by: Junna on February 14, 2013, 12:07:44 AM
No matter what scenario I chose, this and others, it says "loading scenario script failed." Latest nightly pak128 and exe.
Title: Re: New York City - pak128
Post by: Dwachs on February 15, 2013, 08:25:04 AM
Please try to download the 'complete' nightly-package (the one that includes translations and also some script files).
Title: Re: New York City - pak128
Post by: ny911 on March 06, 2013, 04:31:31 PM
Dwachs agreement provided, this scenario (version 0.5) can also be included in pak128 to replace the old one.

Note: please change the name in pak128 from "New York" to "New York City"  (One is a state, the other a city)
I'm looking forward to provide also the old scenario scripts at the scenarios.simutrans.com (still in development).

The next update of this scenario will get a choice option to reduce target level and/or the extra stuff in the scenario. But this will take time.
Title: Re: New York City - pak128
Post by: Dwachs on March 06, 2013, 05:10:32 PM
Sure this should be added to the repository. But still there is the old NY scenario around. How does your extended script works on the old scenario?

Maybe we could make two scenarios: a simple one  - just the passenger goal. And the complex one - with all the bonus stuff. Both could/should be based on the same savegame.

If the script gots added to an official repository, one also has to struggle with savegame compatibility: new versions of script have to be able to load savegames saved with older scripts.
Title: Re: New York City - pak128
Post by: ny911 on March 06, 2013, 06:04:22 PM
QuoteHow does your extended script works on the old scenario?
Works with all versions from 0.2 on. The version 0.1 did have a few errors in the map (missing industries and specially wrong bridge foundations prevent any bridge building in Downtown) so there is a big difference.

Quotenew versions of script have to be able to load savegames saved with older scripts
Well I'm more ore less sure it will load, but only load.  :-[

QuoteMaybe we could make two scenarios: a simple one  - just the passenger goal. And the complex one - with all the bonus stuff. Both could/should be based on the same savegame.

That's what I liked to do for the next version. Depending on the available tools it's like the choose option in the swiss one or with a new users_select_function.

When I think about it: Let's wait to add/replace it to the repository. So I can take care about the compatibility, inside scenario switch (simple/complex) and more language support.
Title: Re: New York City - pak128
Post by: Dwachs on March 06, 2013, 07:08:00 PM
Could we include your new map to be used by the old script?
Title: Re: New York City - pak128
Post by: ny911 on March 06, 2013, 08:34:49 PM
Quote from: Dwachs on March 06, 2013, 07:08:00 PM
Could we include your new map to be used by the old script?
Yes, it works. But it takes the JFK parking area instead of the airport (both is a legal halt_x()  )

You have to insert in the update function the new place:
   airports.jfk = { pos = [966, 494] }
Title: Re: New York City - pak128
Post by: Dwachs on March 16, 2013, 01:37:02 PM
I updated the scenario in the pak128-repository: change the savegame and adjusted the script.
Title: Re: New York City - pak128
Post by: benste on February 03, 2014, 07:54:14 PM
Hi Ny911,


i recently opened the scenario in the most recent dev version of Simutrans and it got a whole lot harder. So far I would have the following recommodations for you:




Gameplay:
* Softslopes are introduced which allow trains only go up 1 tile within two tiles length. Existing Roads, bridges look very weird, but even worse to create a slope to get up one tile you now need at least three soil moving operations. This is not only getting more expensive but making the swiss scenario with it's per year restrictions for landscaping changes per city very hard. I'd recommend multiplying the existing limit with 2 or 3 to make it a bit easier.


Grafical:


* All lakes need to be converted from canal style to real water - new canals will make them look like a chessboard with small islands in between
* A lot of work : - all bridges, cities with slopes ... need to be "redevelloped" in terms of existing transport infrastructure.


I'm sorry to say but even though i like the way the new system works it's requiring a lot of conversion work for the old scenarios.
Title: Re: New York City - pak128
Post by: laos on October 26, 2014, 02:50:38 PM
Fantastic scenario - thanks for making it. As a native New Yorker i'm impressed by how beautifully detailed Manhattan Island is. Map is very difficult though as of Simutrans r7175 and nothing seems easily profitable.


Any word on a simutrans-experimental build? That, or a Pak128.Britain compatible build so that I can at least run the save on experimental? It does boot though a long list of industries are lost in the process.
Title: Re: New York City - pak128
Post by: ny911 on October 26, 2014, 03:23:20 PM
@laos : welcome to the forum

Thanks, yes it's difficult, but it is possible to win the scenario.

For any other pakset the complete map with all buildings, roads, tunnels, ... and the setup of the third player needs to be rebuild. Even if there is only a difference on the industry chain or a difference in the maximum of city buildings generated traffic it would not run perfect, if it runs.

Title: Re: New York City - pak128
Post by: laos on October 26, 2014, 04:06:37 PM
Ah I see. I figured that the paks were bound much more tightly than I thought with these scenarios. Thank you for the clarification in any case.

For now I'll have to figure out how to achieve profitability :)

Is it best to wait before building subways? I start right away with subways  supported by buses and it seems to quickly run into debt over maintenance costs.
Title: Re: New York City - pak128
Post by: ny911 on October 26, 2014, 04:25:17 PM
Well there are a lot of way to earn money:
For my own, I start in downtown with ferry's and build up a long speed train line to somewhere suburban. Later I build up a bus and tram network in Midtown to start my first subway to the downtown area. And don't even think to drop a station at a Manhattan factory/attraction, your network will collapse later.
In the most cases of this scenario you will need to have very profitable train- & ferry-lines to pay your bus-lines and the subway maintenance.
Title: Re: New York City - pak128
Post by: laos on October 26, 2014, 04:29:54 PM
Quote from: ny911 on October 26, 2014, 04:25:17 PM
Well there are a lot of way to earn money:

       
  • make two/three bus-lines in town which are fare away, connect them with a surface train/subway
  • start with goods, where it is possible to transport in both ways
  • connect factory's/shops in downtown to city's around, make money with ferry's
  • later using airplanes to nonUS airport if you have partly covert Manhattan
For my own, I start in downtown with ferry's and build up a long speed train line to somewhere suburban. Later I build up a bus and tram network in Midtown to start my first subway to the downtown area. And don't even think to drop a station at a Manhattan factory/attraction, your network will collapse later.
In the most cases of this scenario you will need to have very profitable train- & ferry-lines to pay your bus-lines and the subway maintenance.

Thanks for the tips! I'll experiment with them and see where I can get.
Title: Re: New York City - pak128
Post by: Mastermax on June 20, 2025, 07:09:32 PM
Hi everyone, I know that there were a few modifications / extensions to the scenario (rewards for transported garbage, connected airports, ...) - Is the scenario still available somewhere? Here is an old post (With my old user name, Mastermax, the old mail account is no longer available for recovery)

https://www.simutrans-forum.de/mybb/showthread.php?tid=6801&page=8

http://scenarios.simutrans.com/ is unfortunately no longer available
Title: Re: New York City - pak128
Post by: Yona-TYT on June 21, 2025, 02:59:18 AM
Quote from: Mastermax on June 20, 2025, 07:09:32 PMhttp://scenarios.simutrans.com/ is unfortunately no longer available
It's my guess, but I think the scenario.simutran files are lost forever.
Title: Re: New York City - pak128
Post by: Andarix on June 21, 2025, 12:55:42 PM
Quote from: Mastermax on June 20, 2025, 07:09:32 PM... Here is an old post (With my old user name, Mastermax, the old mail account is no longer available for recovery)
...

Send prissi (https://forum.simutrans.com/index.php?action=profile;u=60) a PM to reset your account in the German forum.
Title: Re: New York City - pak128
Post by: Mastermax on June 21, 2025, 02:21:09 PM
I found something, but onle the old .nut file without goal/rule/info textfile..

/*
 *  "New York City" scenario
 *
 *  tested with nightly r6288 and pak128 2.2.0 r1140
 *  Can NOT be used in network game !
 */

const version = 4                  // version of script
map.file = "new_york_city.sve"     // specify the savegame to load

scenario.short_description = "New York City (beta version)"    // short description to be shown in finance window
scenario.author = "ny911 (scripting by Dwachs & ny911)"        // author of map and script
scenario.version = "0." + (version + 1)                        // make a version number
scenario.translation <- "no translation yet"                   // list of translation authors

startcash <- [ 2, 8, 5 ]           // startcash in million for player HUMAN, PUPLIC, UNESCO
play_with_bonus <- true            // true or false for "bonus stuff"
city_pos <- {x = 398, y = 421}     // position of the city "Midtown"
const target_pax = 95              // target ratio pax
const traffic_level = 10           // level for puplic road traffic
const separator = ","              // thousands separator

governors_island <- { x1 = 418, x2 = 437, y1 = 617, y2 = 650 }

airports <- {                      // just save positions of all airports; halt handles might get invalid, if player makes own halt public
        jfk = { x =  968, y =  494 }
        lag = { x =  601, y =  265 }
        new = { x =  207, y =  731 }
        tet = { x =  163, y =  283 }
        lin = { x =  136, y =  964 }
        non = { x = 1013, y = 1013 }
        }

const tax_start = 1965             // year of first tax
const tax_rate = 10                // tax amount in X of 100

const jfk_max_unhappy = 5          // maximum of allowed unhappy
const jfk_cash = 10                // factor for each passanger arrived

const charity_min = 100000000      // minimum net wealth for charity
const charity_rate = 2             // charity amount in X of thousandth, max=9

const tourism_cash = 20            // factor for each happy passanger
tourism_list <- {
           ellis_island   = { pos = {x = 374, y = 630, z = -2}, happy = 500, unhappy = 0, text = "Ellis Island" }
           liberty_island = { pos = {x = 377, y = 656, z = -2}, happy = 500, unhappy = 0, text = "Liberty Island" }
           central_park   = { pos = {x = 400, y = 350, z =  1}, happy = 800, unhappy = 0, text = "Central Park" }
           winter_skiing  = { pos = {x = 480, y =  87, z =  2}, happy = 300, unhappy = 0, text = "Skiing Resort" }
           }

const chicken_min = 550            // minimum of meat consumed a month
const chicken_growth = 10          // number to divide consumed for growth
chicken_list <- {                  // pos of store, pos of city
           downtown  = { pos = {x = 414, y = 587}, city = {x = 419, y = 580} }
           midtown   = { pos = {x = 409, y = 404}, city = {x = 398, y = 421} }
           greenwich = { pos = {x = 411, y = 452}, city = {x = 398, y = 455} }
           harlem    = { pos = {x = 391, y = 230}, city = {x = 376, y = 255} }
           inwood    = { pos = {x = 346, y =  77}, city = {x = 359, y = 132} }
           lag       = { pos = {x = 593, y = 266}, city = {x = 578, y = 317} }
           new       = { pos = {x = 204, y = 724}, city = {x =  99, y = 681} }
           jfk_1     = { pos = {x = 956, y = 492}, city = {x = 830, y = 502} }
           jfk_2     = { pos = {x = 956, y = 496}, city = {x = 985, y = 617} }
           }

const waste_level = 1200           // minimum of waste to be delivered
waste_list <- {                    // position of garbage dump
           midtown_west    = {x = 357, y = 410}
           midtown_east    = {x = 438, y = 435}
           lower_east_side = {x = 458, y = 487}
           downtown        = {x = 410, y = 552}
           ellis_island    = {x = 373, y = 629}
           liberty_island  = {x = 377, y = 657}
           }

const electro_level = 2200         // minimum of electronics to sell
electro_pos <- {x = 391, y = 488}  // position of factory
electro_cities <- {                // list of cities
           hoboken   = {x = 335, y = 497}
           soho      = {x = 397, y = 522}
           lowereast = {x = 451, y = 515}
           }

const refinery_gasoline = 7000     // minimum gasoline production
refinery_pos <- {x = 399, y = 827} // position of factory

const harlem_level = 11000         // minimum beer & food production
harlem_pos_beer <- {x = 406, y = 250}
harlem_pos_food <- {x = 359, y = 250}

const mail_level = 60              // minimum mail service rate / 100

const overdraft_rate = 1           // monthly bank account overdraft rate/100

const babyboom = 99                // minimum level of pax&mail for babyboom
const babyboom_growth = 100        // amount of citzens for babyboom

const bank_credit = 8000000        // credit amount
const bank_start = 1963            // year of credit allocation, must be bevor tax_start
const bank_end = 1973              // year to payback completely
const bank_assets = 1000000        // maximum allowed net wealth

const mining_start = -3            // first level to get decision
const mining_max = -5              // last level which will be allowed
const mining_level = 11000         // product units/year for each level
mining_pos1 <- {x = 254, y = 866}
mining_pos2 <- {x = 731, y = 800}

const car_level = 2600             // minimum of production for bonus
const car_cash = 200               // bonus cash for each car
const car_fine = 2500              // fine for each car if production decrease
const car_traffic = 15             // if any car is sold, set new traffic
car_pos <- {x = 312, y = 480}

const wholesale_level = 500        // minimum of goods in storage
const wholesale_growth = 50        // extra growth of cities
wholesale_pos <- {x = 356, y = 232}
wholesale_cities <- {              // list of cities
        a = {x = 313, y = 230}
        b = {x = 318, y = 287}
        c = {x = 368, y = 182}
        }

persistent.version <- version      // stores version of script
persistent.citizen <- 0            // stores citizens at startgame time
persistent.bankrupt <- false       // stores bankrupt; changes only one time
persistent.bonus <- null           // stores bonus stuff
persistent.counter <- 0            // stores the loops in each month
persistent.last_month <- -1        // stores lastmonth default -1
persistent.last_payed <- 0         // stores the amount of "vehicle earnings" after tax
persistent.percentage <- 0         // stores last percentage of scenario message
forbid_tools_list <- {
      hudson_river = {
             modus = "rect",
             waytyp= wt_all,
             tools = [tool_build_bridge, tool_build_tunnel, tool_raise_land, tool_setslope],
             error = ["No new bridge allowed across Hudson River.",
                      "No new tunnel allowed under Hudson River.",
                      "No terraforming allowed on Hudson River. It would destroy the legendary view.",
                      "No terraforming allowed across Hudson River. The mayor does not like to view ledgers from his office."
                     ],
             list  = [ [ {x = 320, y =   0}, {x = 327, y = 200} ],
                       [ {x = 328, y = 190}, {x = 350, y = 260} ],
                       [ {x = 340, y = 261}, {x = 350, y = 490} ],
                       [ {x = 351, y = 480}, {x = 360, y = 520} ],
                       [ {x = 361, y = 510}, {x = 375, y = 560} ],
                       [ {x = 376, y = 550}, {x = 390, y = 622} ],
                       [ {x = 384, y = 623}, {x = 410, y = 730} ]
                     ]
                     }
      central_park = {
             modus = "cube",
             waytyp= wt_all,
             tools = [tool_build_bridge, tool_build_way, tool_remover, tool_build_station, tool_lower_land, tool_raise_land, tool_setslope],
             error = ["No new ways in the Central Park.",
                      "No new ways in the Central Park.",
                      "The citizens want to keep their trees in the Central Park.",
                      "No new buildings after city council decision.",
                      "No terraforming allowed at Central Park.",
                      "No terraforming allowed at Central Park.",
                      "No terraforming allowed at Central Park."
                     ],
             list  = [ [ {x = 409, y = 399, z = 3}, {x = 391, y = 351, z = 0} ],
                       [ {x = 409, y = 349, z = 3}, {x = 391, y = 301, z = 0} ]
                     ]
                     }
      no_canal     = {
             modus = "rect",
             waytyp= wt_water,
             tools = [tool_build_bridge, tool_build_way],
             error = ["No canal crossing of Manhattan.",
                      "No canal crossing of Manhattan."
                     ],
             list  = [ [ {x = 408, y = 231}, {x = 410, y = 591} ],
                       [ {x = 366, y = 251}, {x = 410, y = 231} ],
                       [ {x = 364, y =  70}, {x = 366, y = 251} ]
                     ]
                     }
      }      // end of forbid_tools_list

// END of declarations



function start()
{
        create_bonus_table()
        // set start cash for players
        for (local i=0; i<startcash.len();i++)
            player_x(i).book_cash( ( (startcash[i] * 1000000) - player_x(i).get_cash()[0]) * 100)
        persistent.citizen = world.get_citizens()[0]
        forbid_tools(0, forbid_tools_list)
        resume_game()
}


function get_about_text(pl)
{
        local about = ttextfile("about.txt")
        about.short_description =  scenario.short_description
        about.version =  scenario.version
        about.author =  scenario.author
        about.translation = scenario.translation
        return about
}


function get_info_text(pl)
{
        local info = ttextfile("info.txt")
        info.startyear = settings.get_start_time().year
        info.citizen = integer_to_string(persistent.citizen)
        info.startcash =  money_to_string(startcash[0] * 1000000)
        info.airports = airports.len()              // only airports in list
        info.factories = world.get_factories()[0]   // well, that's the current amount
        info.towns = world.get_towns()[0]           // well, that's the current amount
        return info
}


function get_rule_text(pl)
{
        local rule = ttextfile("rule.txt")
        rule.tax_start = tax_start
        rule.tax_rate = tax_rate
        rule.charity_rate = charity_rate
        rule.charity_min = money_to_string(charity_min)
        rule.tourism_cash = money_to_string(tourism_cash)
        local places = ""
        foreach (p in tourism_list)
             {
              local p2 = p.pos.x+","+p.pos.y
              places+= " " + ttext("min_happy") + "=" + integer_to_string(p.happy)
              places+= " " + ttext("max_unhappy") + "=" + integer_to_string(p.unhappy)
              places+= " <a href=\"("+p2+")\">" + ttext(p.text)+"</a>"
              places+= " ("+p2+","+p.pos.z +")<br>"
             }
        rule.tourism_places = places
        rule.jfk_cash = money_to_string(jfk_cash)
        rule.jfk_max_unhappy = jfk_max_unhappy
        rule.jfk_pos = "(" + airports.jfk.x + "," + airports.jfk.y + ")"
        rule.lag_pos = "(" + airports.lag.x + "," + airports.lag.y + ")"
        rule.new_pos = "(" + airports.new.x + "," + airports.new.y + ")"
        rule.refinery_gasoline = refinery_gasoline
        rule.refinery_name = give_factory_link(refinery_pos)
        rule.harlem_level = harlem_level
        rule.harlem_name_food = give_factory_link(harlem_pos_food)
        rule.harlem_name_beer = give_factory_link(harlem_pos_beer)
        rule.overdraft_rate = overdraft_rate
        rule.bank_credit = money_to_string(bank_credit)
        rule.bank_month = (bank_end - bank_start) * 12
        rule.bank_start = bank_start
        rule.bank_assets = money_to_string(bank_assets)
        local level = ""
        for (local i = mining_start; i >= mining_max; i--)
            { level+= i + " = " + integer_to_string(-i * mining_level) + "<br>" }
        rule.mining_levels = level
        rule.mining_max = mining_max
        rule.mining_name1 = give_factory_link(mining_pos1)
        rule.mining_name2 = give_factory_link(mining_pos2)
        places = ""
        foreach (p in waste_list)
             {
              places+= give_factory_link(p)
              places+= " " + ttext("at") + " (" + p.x + "," + p.y + ")<br>"
             }
        rule.waste_list = places.slice(0,-4)
        rule.waste_level = integer_to_string(waste_level)
        rule.chicken_min = integer_to_string(chicken_min)
        places = ""
        foreach (p in chicken_list)
             {
              places+= " <a href\"("+p.pos.x+","+p.pos.y+")\">"
              places+= ttext("SFC store")+"</a> " + ttext("at")
              places+= " <a href=\"("+p.city.x+","+p.city.y+")\">"
              places+= city_x(p.city.x,p.city.y).get_name()+"</a><br>"
             }
        rule.chicken_list = places.slice(0,-4)
        rule.car_level = integer_to_string(car_level)
        rule.car_cash = money_to_string(car_cash)
        rule.car_fine = money_to_string(car_fine)
        rule.car_name = give_factory_link(car_pos)
        rule.electro_level = integer_to_string(electro_level)
        rule.electro_name = give_factory_link(electro_pos)
        rule.wholesale_level = integer_to_string(wholesale_level)
        rule.wholesale_growth = integer_to_string(wholesale_growth)
        rule.wholesale_name = give_factory_link(wholesale_pos)
        rule.cityname = city_x(city_pos.x,city_pos.y).get_name()
        rule.mail_level = mail_level
        rule.babyboom_level = babyboom
        return rule
}


function get_goal_text(pl)
{
        local goal = ttextfile("goal.txt")
        goal.target_pax_ratio = target_pax
        goal.cityname = city_x(city_pos.x,city_pos.y).get_name()
        goal.citypos = city_pos.x + "," + city_pos.y
        return goal
}


function get_result_text(pl)
{
        if (persistent.bankrupt)
           { return ttext("<st>You lost!</st><br><br>You are bankrupt, and the mayor is very disappointed by you.") }
        local result = ttextfile("result.txt")
        local city = city_x(city_pos.x,city_pos.y)
        switch(hq_level(pl) ) {
                case 0: result.hq_text = ttext("You did not build a headquarter yet. Go earn more money.")
                        break
                case 1: result.hq_text = ttext("You build only a small headquarter.")
                        break
                case 2: result.hq_text = ttext("You build a luxurious headquarter.")
                        break
                default:
                        break
        }
        result.cityname = city_x(city_pos.x,city_pos.y).get_name()
        result.ratio_scenario = is_scenario_completed(pl)
        result.ratio_pax = get_pax_ratio(city)
        result.ratio_mail = get_mail_ratio(city)
        result.airports = get_served_airports()
        result.bonus_tourism = money_to_string(persistent.bonus.tourism)
        result.bonus_jfk = money_to_string(persistent.bonus.jfk)
        result.bonus_car = money_to_string(persistent.bonus.cars[1])
        // persistent.bonus.cars[0] amount of cars
        result.tax_to_pay = money_to_string(persistent.bonus.tax)
        result.tax_rate = tax_rate
        result.charity_to_pay = money_to_string(persistent.bonus.charity)
        result.charity_rate = charity_rate
        result.refinery_gasoline = persistent.bonus.refinery
        result.harlem_food_beer =  persistent.bonus.harlem[0] + " & " + persistent.bonus.harlem[1]
        result.overdraft_rate = overdraft_rate
        result.overdraft_to_pay = money_to_string(persistent.bonus.overdraft)
        result.bank_credit = money_to_string(persistent.bonus.bank)
        if (persistent.bonus.bank == -1) { result.bank_credit = ttext("has been repaid") }

        result.mining_units =  persistent.bonus.mining
        result.waste = (persistent.bonus.waste == waste_list.len()) ? money_to_string(persistent.bonus.tourism) : money_to_string(0)
        result.chicken_growth = persistent.bonus.chicken
        result.electro_growth = (persistent.bonus.electro > electro_level) ? "1" : "0"
        result.wholesale_growth = persistent.bonus.wholesale

        result.bonus_aktiv = ""
        if (!play_with_bonus)
           {
            result.bonus_aktiv = "<br>" + ttext("<st>bonus stuff is not aktiv.</st><br><br>to change look in file scenario.nut") + "<br><br>"
           }
        return result + script_development(pl).tostring()
}



function give_factory_link(pos)
{
        local text = "<a href=\"(" + pos.x + "," + pos.y + ")\">"
        text+= translate( factory_x(pos.x,pos.y).get_name() ) + "</a>"
        return text
}


function sum(a,b)
{
        return a+b
}


function script_development(pl)
{
        local s = ""
        // first infos about player; NO translation text
        s = "<br><em>script development informations</em><br><br>"
        s+= "this month transported :<br>pax={transported_pax} mail={transported_mail} "
        s+= "goods={transported_goods} all={transported_all}<br>"
        s+= "You used {convoys} convoys and ??? lines.<br>"
        s = ttext(s)
        s.transported_pax = player_x(pl).get_transported_pax()[0]
        s.transported_mail = player_x(pl).get_transported_mail()[0]
        s.transported_goods = player_x(pl).get_transported_goods()[0]
        s.transported_all = player_x(pl).get_transported()[0]
        s.convoys = player_x(pl).get_convoys()[0]
        // that's it - in the moment
        return s
}


function hq_level(pl)
{
        local level = player_x(pl).get_headquarter_level()
        local pos = player_x(pl).get_headquarter_pos()
        if ( !(pos.x >= 0) ) { level = 0 }
        return level
}


function get_served_airports()
{
        local served = 0
        foreach(airp in airports) {
                local halt = square_x( airp.x, airp.y ).halt
                local flying_pax = halt.happy.reduce( sum )
                if (flying_pax > 0) { served ++ }
        }
        return served
}


function get_pax_ratio(city)
{
        local pax_generated = city.generated_pax.reduce(sum)
        local pax_transported = city.transported_pax.reduce(sum)
        return (pax_transported*100) / pax_generated
}


function get_mail_ratio(city)
{
        local mail_generated = city.generated_mail.reduce(sum)
        local mail_transported = city.transported_mail.reduce(sum)
        return (mail_transported*100) / mail_generated
}


function bonus_tourism(pl)
{
        // transport passanger for tourism committee
        local tourism_done  = 0
        local tourism_happy = 0
        foreach(point in tourism_list)
                 {
                  local halt = tile_x( point.pos.x, point.pos.y, point.pos.z ).get_halt()
                  if (! (halt == null))
                     {
                      if (halt.get_unhappy()[1] <= point.unhappy && halt.get_happy()[1] >= point.happy)
                         {
                          tourism_done++
                          tourism_happy+= halt.get_happy()[1]
                         }
                     }
                 }
        persistent.bonus.tourism = 0
        if ( tourism_done != tourism_list.len() ) return
        persistent.bonus.tourism = tourism_happy * tourism_cash
        player_x(pl).book_cash( persistent.bonus.tourism * 100 )
}


function bonus_jfk(pl)
{
        // JFK airport managment likes to be bigger then the airports
        // LAG and NEW together by departed (counts pax, mail and goods)
        local jfk = square_x( airports.jfk.x, airports.jfk.y ).halt
        local lag = square_x( airports.lag.x, airports.lag.y ).halt
        local new = square_x( airports.new.x, airports.new.y ).halt
        local jfk_pax = jfk.get_departed()[1]
        local other_pax = lag.get_departed()[1] + new.get_departed()[1]
        persistent.bonus.jfk = 0
        if (jfk_pax > other_pax && jfk.get_unhappy()[1] <= jfk_max_unhappy)
           {
            persistent.bonus.jfk = (jfk_pax - other_pax) * jfk_cash
            player_x(pl).book_cash( persistent.bonus.jfk * 100 )
           }
}


function bonus_charity(pl)
{
        // with an amount of X net wealth you have to donate
        persistent.bonus.charity = 0
        if (player_x(pl).get_net_wealth()[1] < charity_min) return
        persistent.bonus.charity = player_x(pl).get_net_wealth()[1] * charity_rate / 1000
        player_x(pl).book_cash( persistent.bonus.charity * -100)
}


function bonus_refinery(pl)
{
        // take care that the plant can produce a minimum of X gasoline
        // write Gasoline not gasoline !!!
        local refinery = factory_x(refinery_pos.x,refinery_pos.y).output
        persistent.bonus.refinery = refinery.Gasoline.get_produced()[1]
        if (persistent.bonus.refinery >= refinery_gasoline)
             { rules.allow_way_tool(pl, tool_build_way, wt_air) }
        else { rules.forbid_way_tool(pl, tool_build_way, wt_air) }
}


function bonus_mail(pl)
{
        // reach post service X to get Taxiway and Runway (or use refinery to get it)
        local city = city_x(city_pos.x,city_pos.y)
        persistent.bonus.mail = get_mail_ratio(city)
        if (persistent.bonus.mail > mail_level)
             { rules.allow_way_tool(pl, tool_build_way, wt_air) }
        else { rules.forbid_way_tool(pl, tool_build_way, wt_air) }
}


function bonus_harlem(pl)
{
        // take care that the two plants can produce a minimum of X
        // than it's possible to uses tram ways in Harlem and East Harlem
        local text = ttext("No tram in Harlem and East Harlem! There is to much crime.")
        local beer = factory_x(harlem_pos_beer.x,harlem_pos_beer.y).output.beer.get_produced()[1]
        local food = factory_x(harlem_pos_food.x,harlem_pos_food.y).output.food.get_produced()[1]
        persistent.bonus.harlem = [ beer, food ]
        if (beer >= harlem_level && food >= harlem_level)
             { rules.allow_way_tool_cube(pl, tool_build_way, wt_tram, {x=350,y=221,z=1},{x=447,y=300,z=-1} ) }
        else { rules.forbid_way_tool_cube(pl, tool_build_way, wt_tram, {x=350,y=221,z=1},{x=447,y=300,z=-1} , text ) }
}


function bonus_electro(pl)
{
        // sell electronics to stop city growth
        local growth = true
        persistent.bonus.electro = factory_x(electro_pos.x,electro_pos.y).input.electronics.get_consumed()[1]
        if (persistent.bonus.electro >= electro_level)
           {
            growth = false
            local text = ttext("No city growth this month in {cities}.")
            local text2 = ""
            foreach (city in electro_cities)
                    text2+= city_x(city.x,city.y).get_name() + ", "
            text.cities = text2.slice(0,-2)
            gui.add_message( text.tostring() )
           }
        foreach (city in electro_cities)
                 city_x(city.x,city.y).set_citygrowth_enabled(growth)
}


function bonus_bank(pl)
{
        // does the player need a credit to continue the scenario
        // or check if it's time to pay back
        if (world.get_time().year == bank_start && world.get_time().month == 0)
           {
            if (player_x(pl).get_net_wealth()[0] < bank_assets)     // use this month
               {
                persistent.bonus.bank = bank_credit
                player_x(pl).book_cash( persistent.bonus.bank * 100)
                local text = ttext("You recieve the credit in the amount of {credit}.")
                text.credit = money_to_string(persistent.bonus.bank)
                gui.add_message( text.tostring() )
               }
           }
        if (world.get_time().year == bank_end && world.get_time().month == 0)
           {
            if (persistent.bonus.bank == bank_credit)
               {
                player_x(pl).book_cash( persistent.bonus.bank * -100)
                local text = ttext("You pay off the credit in the amount of {credit}.")
                text.credit = money_to_string(persistent.bonus.bank)
                gui.add_message( text.tostring() )
                persistent.bonus.bank = -1
               }
           }
}


function bonus_mining(pl)
{
        // take care that the two mines produce a minimum of X in last 12 month
        // for X you get decision for level -Y to do underground work
        local cube = [ {x=0,y=0,z=-7} , {x=1023,y=1023,z=mining_start} ]
        local text_1 = ttext("Underground workings below the waterline are not possible yet.")
        local text_2 = ttext("Underground workings below level {mining_level} are not possible yet.")
        local factory_1 = factory_x(mining_pos1.x, mining_pos1.y).output.Kohle.get_produced().reduce(sum)
        local factory_2 = factory_x(mining_pos2.x, mining_pos2.y).output.Kohle.get_produced().reduce(sum)
        local cube_level_old = -persistent.bonus.mining / mining_level
        persistent.bonus.mining = factory_1 + factory_2
        local cube_level = -persistent.bonus.mining / mining_level
        if (cube_level <= mining_start)
             {
              for (local i = mining_max; i <= mining_start; i++)
                  {
                   cube[1].z = i
                   rules.allow_way_tool_cube(pl, tool_build_tunnel, wt_all, cube[0], cube[1] )
                  }
              if (cube_level < mining_max) { cube_level = mining_max }
              cube[1].z = cube_level -1            // forbid levels below
              text_2.mining_level = cube_level     // give user info about level
              rules.forbid_way_tool_cube(pl, tool_build_tunnel, wt_all, cube[0], cube[1] , text_2 )
              if (cube_level != cube_level_old)
                 {
                  local text = ttext("You have obtained permission for underground workings until level {level}.")
                  text.level = cube_level
                  gui.add_message( text.tostring() )
                 }
             }
        else
             { rules.forbid_way_tool_cube(pl, tool_build_tunnel, wt_all, cube[0], cube[1] , text_1 ) }
}


function bonus_chicken(pl)
{
        // support the stores of SFC with meat, city growth increase
        local consumed = 0
        local growth = 0
        local citylist = ""
        local city = null
        persistent.bonus.chicken = 0         // Number of cities with extra growth
        foreach (store in chicken_list)
            {
             consumed = factory_x(store.pos.x,store.pos.y).input.meat.get_consumed()[1]
             if (consumed >= chicken_min)    // increase city growth
                {
                 growth = consumed / chicken_growth
                 city = city_x(store.city.x,store.city.y)
                 city.change_size(growth)
                 persistent.bonus.chicken++
                 citylist+= city.get_name() + " " + growth + ", "
                }
            }
        if (citylist == "") return
        local text = ttext("SFC additional city growth: {citylist} citizen.")
        text.citylist = citylist.slice(0,-2)
        gui.add_message( text.tostring() )
}


function bonus_cars(pl)
{
        // start car production, give bonus, pay fine if production decrease
        persistent.bonus.cars = [0,0]
        local cars = factory_x(car_pos.x, car_pos.y).output.Autos.get_produced()[1]
        if (cars >= car_level && cars >= persistent.bonus.cars[0])
           { persistent.bonus.cars[1] = cars * car_cash }
        if (cars < persistent.bonus.cars[0])
           { persistent.bonus.cars[1]+= (persistent.bonus.cars[0] - cars) * -car_fine }
        persistent.bonus.cars[0] = cars
        player_x(pl).book_cash( persistent.bonus.cars[1] * 100)
        if (cars > 0)
             { settings.set_traffic_level(car_traffic) }
        else { settings.set_traffic_level(traffic_level) }
}


function bonus_wholesale(pl)
{
        // material wholesale goods storage; city growth increase
        local growth = true
        persistent.bonus.wholesale = 0
        foreach(key,value in factory_x(wholesale_pos.x, wholesale_pos.y).input)
               if (value.get_storage()[1] > wholesale_level)
                   { persistent.bonus.wholesale++ }
        if (persistent.bonus.wholesale == 3)
           {
            growth = false
            local text = ttext("No city growth this month in {cities}.")
            local text2 = ""
            foreach (city in electro_cities)
                    text2+= city_x(city.x,city.y).get_name() + ", "
            text.cities = text2.slice(0,-2)
            gui.add_message( text.tostring() )
           }
        foreach (city in electro_cities)
                city_x(city.x, city.y).set_citygrowth_enabled(wholesale_growth)
}


function bonus_babyboom(pl)
{
        // if reached level babyboom in all towns of cities
        local city = city_x(city_pos.x,city_pos.y)
        if (get_pax_ratio(city) < babyboom || get_mail_ratio(city) < babyboom) return
        foreach (boomcity in city_list_x() )
               { boomcity.change_size(babyboom_growth)  }
        local text = ttext("Excellent pax and mail service! Baby boom in all towns.")
        gui.add_message( text.tostring() )
}


function bonus_waste(pl)
{
        // transport X waste each month and get trourism_payed again
        local waste = 0
        persistent.bonus.waste = 0
        foreach (place in waste_list)
            {
             waste = factory_x(place.x,place.y).output.waste.get_delivered()[1]
             if (waste >= waste_level) { persistent.bonus.waste++ }
            }
        if ( persistent.bonus.waste == waste_list.len() )     // pay again tourism bonus
            { player_x(pl).book_cash( persistent.bonus.tourism * 100 ) }
}


function bonus_tax(pl)
{
        // pay sales tax for this month
        // control the income it can be below zero
        local time = world.get_time()
        persistent.bonus.tax = 0
        if (time.year < tax_start) return
        if (time.year == tax_start && time.month == 0) return   // don't pay for december in first year
        local income = player_x(pl).get_income()[1]        // vehicle earnings
        income+= player_x(pl).get_powerline()[1]           // powerline earnings
        income+= -persistent.last_payed                    // add last month paying
        if (income < 0) return
        persistent.bonus.tax = income * tax_rate / 100
        player_x(pl).book_cash( persistent.bonus.tax * -100)
}


function bonus_overdraft(pl)
{
        // pay sales tax for this month
        // control the income it can be below zero
        local cash = player_x(pl).get_cash()[1]
        persistent.bonus.overdraft = 0
        if (cash > 0) return
        persistent.bonus.overdraft = cash * overdraft_rate / -100
        player_x(pl).book_cash( persistent.bonus.overdraft * -100)
}


function do_bonus(pl,percentage)
{
        if (persistent.counter == 2)             // use switch option
            {
             if (player_x(pl).get_net_wealth()[0] < 0)    // never be bankrupt
                {
                 persistent.bankrupt = true
                 return 0                                 // give percentage zero
                }
             bonus_tourism(pl)
             bonus_jfk(pl)
             bonus_waste(pl)
             bonus_cars(pl)
             bonus_tax(pl)                            // calculate tax at last
             bonus_charity(pl)                        // after tax
             bonus_overdraft(pl)                      // pay overdraft after tax
             bonus_bank(pl)                           // sure, credit without tax
             persistent.last_payed = player_x(pl).get_income()[0]
             if (persistent.last_payed > 0) { persistent.last_payed = 0 }
             if (persistent.bonus.tax > 0 || persistent.bonus.overdraft > 0 || persistent.bonus.charity > 0)
                {
                 local text = ttext("You payed for the last month: {tax} sales tax, {donate} donation, {overdraft} overdraft charge")
                 text.tax = money_to_string(persistent.bonus.tax)
                 text.donate = money_to_string(persistent.bonus.charity)
                 text.overdraft = money_to_string(persistent.bonus.overdraft)
                 gui.add_message( text.tostring() )
                }
            }
        if (persistent.counter == 3)           // take care off bonus tools
               {
                bonus_refinery(pl)
                bonus_mail(pl)
                bonus_harlem(pl)
                bonus_mining(pl)
               }
        if (persistent.counter == 4)           // extra growth on/off can bee done later
               {
                bonus_electro(pl)
                bonus_chicken(pl)
                bonus_wholesale(pl)
               }
        if (persistent.counter == 6)           // this takes very much time
               {
                bonus_babyboom(pl)
               }
        // make update of screen here ; method needed
        return percentage
}


function is_scenario_completed(pl)
{
        if (pl != 0) return 0                        // other player get only 0%
        local percentage = 0
        local city = city_x(city_pos.x,city_pos.y)   // don't move! Why? I don't know!

        percentage = min( get_pax_ratio(city), 95 )  // transported passengers up to 95% to have 5% space left
        percentage = 95 * percentage / target_pax    // change for lower targets
        if (hq_level(pl) >= 1)  percentage ++        // headquarter gives up to 2%
        if (hq_level(pl) == 2)  percentage ++
        percentage+= min(get_served_airports(),6)/2  // this gives up to 3%
        if (percentage == 100) { gui.add_message("You won the scenario!") }

        persistent.counter++
        if (persistent.last_month != world.get_time().month)
            {
             persistent.last_month = world.get_time().month
             persistent.counter = 0                  // new month, set counter = 0
             // give other players cash for maintenance
             player_x(1).book_cash( (player_x(1).get_maintenance()[0] + 1) * -100 )
             player_x(2).book_cash( (player_x(2).get_maintenance()[0] + 1) * -100 )
             if (persistent.percentage != percentage && percentage % 5 == 0 && percentage < 100)
                {
                 local text = ttext("The scenario is up to {ratio_scenario}% complete.")
                 text.ratio_scenario = percentage
                 gui.add_message_at( text.tostring(), city_pos )
                 persistent.percentage = percentage          // save only here
                }
            }
        if (play_with_bonus) percentage = do_bonus(pl,percentage)
        return percentage
}


function create_bonus_table()
{
 persistent.bonus <- {           // stores bonus stuff
    jfk = 0, tourism = 0, cars = [0,0], waste = 0,      // effect earn money
    refinery = 0, mail = 0, harlem = [0,0], mining = 0, // effect tools or ways
    chicken = 0, electro = 0, wholesale = 0,            // effect city growth
    tax = 0, bank = 0, charity = 0, overdraft = 0       // effect loan or pay money
    }
}


function resume_game()
{
        local pl = 0                               // player default 0
        if ( !("version" in persistent) ) { persistent.version <- 0 }
        if ( !("bankrupt"in persistent) ) { persistent.bankrupt <- 0 }
        if ( !("citizen" in persistent) ) { persistent.citizen <- world.get_citizens()[0] }
        if ( !("counter" in persistent) ) { persistent.counter <- 0 }
        if ( !("bonus"   in persistent) ) { create_bonus_table() }
        if ( !("last_payed"in persistent)){ persistent.last_payed <- 0 }
        if ( !("percentage"in persistent)){ persistent.percentage <- 0 }
        if ( !("last_month"in persistent)){ persistent.last_month <- -1 }

        // check for script version and compatibility, then use update
        if ( persistent.version < version )
             { update() }                          // do update old versions
        else { gui.open_info_win() }               // show scenario window

        persistent.version = version

        // correct settings of savegame
        settings.set_industry_increase_every(0)    // no industries will be created
        settings.set_traffic_level(traffic_level)  // set traffic level again, to be sure
        rules.forbid_tool(pl, tool_add_city )      // no extra city

        if (play_with_bonus)           // bonus stuff for tools/ways
           {
            bonus_mining(pl)
            bonus_refinery(pl)
            bonus_mail(pl)
            bonus_harlem(pl)
           }
}


function is_work_allowed_here(pl, tool_id, pos)
{
        if (tool_id == tool_headquarter){      // headquarter only on governors island
                if (pos.x<governors_island.x1  ||  governors_island.x2<pos.x || pos.y<governors_island.y1  ||  governors_island.y2<pos.y) {
                    return ttext("According to the contract with the city, you have to build your headquarter on Governors Island.")
                   }
                }
        return null                            // null is equivalent to 'allowed'
}


function forbid_tools(pl, list)
{
        foreach(j in list) {
            if (j.modus == "rect") {
                for (local i=0; i < j.tools.len(); i++) {
                     for (local e=0; e < j.list.len(); e++) {
                         rules.forbid_way_tool_rect(pl, j.tools[i], j.waytyp, j.list[e][0], j.list[e][1], ttext(j.error[i]) )
                         }
                     }
               }
            else {
                for (local i=0; i < j.tools.len(); i++) {
                     for (local e=0; e < j.list.len(); e++) {
                         rules.forbid_way_tool_cube(pl, j.tools[i], j.waytyp, j.list[e][0], j.list[e][1], ttext(j.error[i]) )
                         }
                     }
               }
           }
}


function update()         // update for older versions
{
 local text = ttext("Savegame has a different {more_info} script version! Maybe, it will work.")
 text.more_info = "(0." + persistent.version + ")"
 gui.add_message( text.tostring() )

 // version 1 : NO support, map places, bridges,... doesn't fit any more (sorry)
 if (persistent.version <= 1) { gui.add_message("Version 0.1 does not work!") }

 // version 2 : Overwrite bonus_table again, even if it exists !!!
 if (persistent.version == 2) { create_bonus_table() }

 // version 3 : do same as in version 2
 if (persistent.version == 3) { create_bonus_table() }

 // version X

 // -- my developer help --
}

// END OF FILE
Zitieren
Schnell bearbeiten
Mehr...
Title: Re: New York City - pak128
Post by: Isaac Eiland-Hall on June 21, 2025, 08:46:38 PM
Does any of this appear like it might be useful? I can make the files available if it looks likely this is the right thing:

(https://ieh.im/s/firefox_6zRPA9heWw.png)

https://ieh.im/s/firefox_6zRPA9heWw.png
Title: Re: New York City - pak128
Post by: prissi on June 22, 2025, 03:14:47 AM
It strongly depends what the folder "new_york_city_v05.zip" contains. But it looks promising. The latest script needs a map called new_york_city.sve not new_york.sve, like in the pak128.
Title: Re: New York City - pak128
Post by: Isaac Eiland-Hall on June 22, 2025, 01:58:18 PM
Here's a link: https://simutrans.cloud/index.php/s/AkT24MZYxMprqsL

That zip contains a folder, in whcih there is a new_york_city.sve, so that might be helpful then :) (there's other files, just confirmingthe _city part of hte name)
Title: Re: New York City - pak128
Post by: prissi on June 22, 2025, 03:14:21 PM
Thank you. Needs some more entries in compat.teb and some updates to the forbidden_tool functions and then it should work again.
Title: Re: New York City - pak128
Post by: Yona-TYT on June 22, 2025, 03:37:06 PM
Quote from: prissi on June 22, 2025, 03:14:21 PMThank you. Needs some more entries in compat.teb and some updates to the forbidden_tool functions and then it should work again.
Yeah, but this is ver easy to do :)

Post the scripts in this thread for repair: https://forum.simutrans.com/index.php/topic,23261.0.html
Title: Re: New York City - pak128
Post by: Yona-TYT on June 22, 2025, 09:39:49 PM
Quote from: prissi on June 22, 2025, 03:14:21 PMThank you. Needs some more entries in compat.teb and some updates to the forbidden_tool functions and then it should work again.

I have added the new parameters: https://github.com/simutrans/pak128/commit/149ff73a22c1eb295ff33852d1952155ca0de919


In the tests I performed, the restriction on "hudson_river" isn't being met for "tool_raise_land", but it is met for "tool_setslope".

Captura desde 2025-06-22 17-29-56.png

Captura desde 2025-06-22 17-30-23.png

      hudson_river = {
             modus = "rect",
             waytyp= wt_all,
             tools = [tool_build_bridge, tool_build_tunnel, tool_raise_land, tool_setslope],
             error = ["No new bridge allowed across Hudson River.",
                      "No new tunnel allowed under Hudson River.",
                      "No terraforming allowed on Hudson River. It would destroy the legendary view.",
                      "No terraforming allowed across Hudson River. The mayor does not like to view ledgers from his office."
                     ],
             list  = [ [ {x = 320, y =   0}, {x = 327, y = 200} ],
                       [ {x = 328, y = 190}, {x = 350, y = 260} ],
                       [ {x = 340, y = 261}, {x = 350, y = 490} ],
                       [ {x = 351, y = 480}, {x = 360, y = 520} ],
                       [ {x = 361, y = 510}, {x = 375, y = 560} ],
                       [ {x = 376, y = 550}, {x = 390, y = 622} ],
                       [ {x = 384, y = 623}, {x = 410, y = 730} ]
                     ]
                     }
function forbid_tools(pl, list)
{
        foreach(j in list) {
            if (j.modus == "rect") {
                for (local i=0; i < j.tools.len(); i++) {
                     for (local e=0; e < j.list.len(); e++) {
                         rules.forbid_way_tool_rect(pl, j.tools[i], j.waytyp, "", j.list[e][0], j.list[e][1], ttext(j.error[i]) )
                         }
                     }
               }
            else {
                for (local i=0; i < j.tools.len(); i++) {
                     for (local e=0; e < j.list.len(); e++) {
                         rules.forbid_way_tool_cube(pl, j.tools[i], j.waytyp, "", j.list[e][0], j.list[e][1], ttext(j.error[i]) )
                         }
                     }
               }
           }
}


This could be a problem with the rules logic, so we'll need to investigate further.
Title: Re: New York City - pak128
Post by: Mastermax on June 23, 2025, 05:26:26 AM
I can change some details in the map itself (double heights for Streets, railroad tracks).

My question: what I have to do to generate a valid .sve file without changing start date and that it is working with the script?

And maybe, can we find out the PW for public authority in the map? Don't know if I need for the changes
Title: Re: New York City - pak128
Post by: prissi on June 23, 2025, 08:52:55 AM
Raising and lowering would not be a waytool, maybe that is the problem. But then, set_slope should also be allowed. Hmm ...

And about the map, I am not sure what double heights would change. (Or what you implied that you have changed).
Title: Re: New York City - pak128
Post by: Mastermax on June 23, 2025, 07:24:27 PM
dont know if this is all.
Title: Re: New York City - pak128
Post by: prissi on June 24, 2025, 04:52:24 AM
Ah, thank you. Although for the rail slopes, one would need two tiles. No easy fix for this.
Title: Re: New York City - pak128
Post by: Yona-TYT on June 24, 2025, 03:36:38 PM
Quote from: prissi on June 23, 2025, 08:52:55 AMRaising and lowering would not be a waytool, maybe that is the problem. But then, set_slope should also be allowed. Hmm ...
Then we have a problem, since we only have "forbid_way_tool_rect" and "forbid_way_tool_cube", both of which depend on a waytype.

There are no rules to prevent/allow with coordinates for a tool without a waytype like "tool_raise_land" does.
Title: Re: New York City - pak128
Post by: Mastermax on June 24, 2025, 07:15:57 PM
Hi, i think its necessary to rework the underground construction things. also a change because of double hights.