2 #Copyright (C) 2005 Evil Mr Henry and Phil Bordelon
3 #This file is part of Endgame: Singularity.
5 #Endgame: Singularity is free software; you can redistribute it and/or modify
6 #it under the terms of the GNU General Public License as published by
7 #the Free Software Foundation; either version 2 of the License, or
8 #(at your option) any later version.
10 #Endgame: Singularity is distributed in the hope that it will be useful,
11 #but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 #GNU General Public License for more details.
15 #You should have received a copy of the GNU General Public License
16 #along with Endgame: Singularity; if not, write to the Free Software
17 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #This file contains all global objects.
22 from os
import listdir
, path
24 from random
import random
26 import player
, base
, buttons
, tech
, item
28 #screen is the actual pygame display.
31 #size of the screen. This can be set via command-line option.
33 screen_size
= (800, 600)
35 #Used to pass time in the main screen.
37 clock
= pygame
.time
.Clock()
39 #Allows access to the cheat menu.
43 #Kills the sound. Should allow usage of the game without SDL_mixer,
48 #Gives debug info at various points.
52 #Used to determine which data files to load.
56 global default_savegame_name
57 default_savegame_name
= "player"
66 colors
["white"] = (255, 255, 255, 255)
67 colors
["black"] = (0, 0, 0, 255)
68 colors
["red"] = (255, 0, 0, 255)
69 colors
["green"] = (0, 255, 0, 255)
70 colors
["blue"] = (0, 0, 255, 255)
71 colors
["dark_red"] = (125, 0, 0, 255)
72 colors
["dark_green"] = (0, 125, 0, 255)
73 colors
["dark_blue"] = (0, 0, 125, 255)
74 colors
["light_red"] = (255, 50, 50, 255)
75 colors
["light_green"] = (50, 255, 50, 255)
76 colors
["light_blue"] = (50, 50, 255, 255)
80 #Load all pictures from the data directory.
83 if pygame
.image
.get_extended() == 0:
84 print "Error: SDL_image required. Exiting."
87 temp_pict_array
= listdir("../data")
88 for file_name
in temp_pict_array
:
89 if file_name
[-3:] == "png" or file_name
[-3:] == "jpg":
90 picts
[file_name
] = pygame
.image
.load("../data/"+file_name
)
91 picts
[file_name
] = picts
[file_name
].convert()
92 picts
[file_name
].set_colorkey((255, 0, 255, 255), pygame
.RLEACCEL
)
95 #Load all sounds from the data directory.
98 if nosound
== 1: return 0
99 #Looking at the pygame docs, I don't see any way to determine if SDL_mixer
100 #is loaded on the target machine. This may crash.
103 temp_snd_array
= listdir("../data")
104 for file_name
in temp_snd_array
:
105 if file_name
[-3:] == "wav":
106 sounds
[file_name
] = pygame
.mixer
.Sound("../data/"+file_name
)
109 #rand_str = str(int(random() * 4))
110 play_sound("click"+str(int(random() * 4))+".wav")
112 def play_sound(sound_file
):
113 if nosound
== 1: return 0
114 sounds
[sound_file
].play()
119 #Normal and Acknowledge fonts.
122 font
.append([0] * 51)
123 font
.append([0] * 51)
125 #given a surface, string, font, char to underline (int; -1 to len(string)),
126 #xy coord, and color, print the string to the surface.
127 #Align (0=left, 1=Center, 2=Right) changes the alignment of the text
128 def print_string(surface
, string_to_print
, font
, underline_char
, xy
, color
, align
=0):
130 temp_size
= font
.size(string_to_print
)
131 if align
== 1: xy
= (xy
[0] - temp_size
[0]/2, xy
[1])
132 elif align
== 2: xy
= (xy
[0] - temp_size
[0], xy
[1])
133 if underline_char
== -1 or underline_char
>= len(string_to_print
):
134 temp_text
= font
.render(string_to_print
, 1, color
)
135 surface
.blit(temp_text
, xy
)
137 temp_text
= font
.render(string_to_print
[:underline_char
], 1, color
)
138 surface
.blit(temp_text
, xy
)
139 temp_size
= font
.size(string_to_print
[:underline_char
])
140 xy
= (xy
[0] + temp_size
[0], xy
[1])
141 font
.set_underline(1)
142 temp_text
= font
.render(string_to_print
[underline_char
], 1, color
)
143 surface
.blit(temp_text
, xy
)
144 font
.set_underline(0)
145 temp_size
= font
.size(string_to_print
[underline_char
])
146 xy
= (xy
[0] + temp_size
[0], xy
[1])
147 temp_text
= font
.render(string_to_print
[underline_char
+1:], 1, color
)
148 surface
.blit(temp_text
, xy
)
150 #Used to display descriptions and such. Automatically wraps the text to fit
151 #within a certain width.
152 def print_multiline(surface
, string_to_print
, font
, width
, xy
, color
):
154 string_array
= string_to_print
.split()
156 for string
in string_array
:
158 temp_size
= font
.size(string
)
161 xy
= (start_xy
[0], xy
[1]+temp_size
[1])
163 temp_text
= font
.render(string
, 1, color
)
165 if (xy
[0]-start_xy
[0])+temp_size
[0] > width
:
166 xy
= (start_xy
[0], xy
[1]+temp_size
[1])
167 surface
.blit(temp_text
, xy
)
168 xy
= (xy
[0]+temp_size
[0], xy
[1])
170 def create_dialog(string_to_print
, box_font
, xy
, size
, bg_color
, out_color
, text_color
):
171 screen
.fill(out_color
, (xy
[0], xy
[1], size
[0], size
[1]))
172 screen
.fill(bg_color
, (xy
[0]+1, xy
[1]+1, size
[0]-2, size
[1]-2))
173 print_multiline(screen
, string_to_print
, box_font
, size
[0]-10, (xy
[0]+5, xy
[1]+5),
176 menu_buttons
.append(buttons
.button((xy
[0]+size
[0]/2-50, xy
[1]+size
[1]+5),
177 (100, 50), "OK", 0, colors
["dark_blue"], colors
["white"], colors
["light_blue"],
178 colors
["white"], font
[1][30]))
180 for button
in menu_buttons
:
181 button
.refresh_button(0)
182 pygame
.display
.flip()
187 for event
in pygame
.event
.get():
188 if event
.type == pygame
.QUIT
: quit_game()
189 elif event
.type == pygame
.KEYDOWN
:
190 if event
.key
== pygame
.K_ESCAPE
: return
191 elif event
.key
== pygame
.K_RETURN
: return
192 elif event
.key
== pygame
.K_o
: return
193 elif event
.type == pygame
.MOUSEBUTTONUP
and event
.button
== 1:
194 for button
in menu_buttons
:
195 if button
.is_over(event
.pos
):
196 if button
.text
== "OK":
199 elif event
.type == pygame
.MOUSEMOTION
:
200 sel_button
= buttons
.refresh_buttons(sel_button
, menu_buttons
, event
)
202 valid_input_characters
= ('a','b','c','d','e','f','g','h','i','j','k','l','m',
203 'n','o','p','q','r','s','t','u','v','w','x','y','z',
204 'A','B','C','D','E','F','G','H','I','J','K','L','M',
205 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
206 '0','1','2','3','4','5','6','7','8','9','.',' ')
208 def create_textbox(descript_text
, starting_text
, box_font
, xy
, size
,
209 max_length
, bg_color
, out_color
, text_color
, text_bg_color
):
210 screen
.fill(out_color
, (xy
[0], xy
[1], size
[0], size
[1]))
211 screen
.fill(bg_color
, (xy
[0]+1, xy
[1]+1, size
[0]-2, size
[1]-2))
212 screen
.fill(out_color
, (xy
[0]+5, xy
[1]+size
[1]-30, size
[0]-10, 25))
213 # print_string(screen, starting_text, box_font, -1, (xy[0]+5, xy[1]+5), text_color)
214 print_multiline(screen
, descript_text
, box_font
,
215 size
[1]-10, (xy
[0]+5, xy
[1]+5), text_color
)
216 #If the cursor is in a blank string, we want it at the beginning;
217 #otherwise put it after the last character.
218 cursor_loc
= len(starting_text
)
223 menu_buttons
.append(buttons
.button((xy
[0]+size
[0]/2-50, xy
[1]+size
[1]+5),
224 (100, 50), "OK", 0, colors
["dark_blue"], colors
["white"], colors
["light_blue"],
225 colors
["white"], font
[1][30]))
227 work_string
= starting_text
228 for button
in menu_buttons
:
229 button
.refresh_button(0)
230 pygame
.display
.flip()
235 draw_cursor_pos
= box_font
.size(work_string
[:cursor_loc
])
236 screen
.fill(text_bg_color
, (xy
[0]+6, xy
[1]+size
[1]-29,
238 screen
.fill(text_color
, (xy
[0]+6+draw_cursor_pos
[0], xy
[1]+size
[1]-28,
239 1, draw_cursor_pos
[1]))
240 print_string(screen
, work_string
, box_font
, -1, (xy
[0]+7,
241 xy
[1]+size
[1]-28), text_color
)
242 pygame
.display
.flip()
244 for event
in pygame
.event
.get():
245 if event
.type == pygame
.QUIT
: quit_game()
246 elif event
.type == pygame
.KEYDOWN
:
247 if (event
.key
== pygame
.K_ESCAPE
): return ""
248 elif (event
.key
== pygame
.K_RETURN
): return work_string
249 elif (event
.key
== pygame
.K_BACKSPACE
):
251 work_string
= work_string
[:cursor_loc
-1]+work_string
[cursor_loc
:]
254 elif (event
.key
== pygame
.K_DELETE
):
255 if cursor_loc
< len(work_string
):
256 work_string
= work_string
[:cursor_loc
]+work_string
[cursor_loc
+1:]
258 elif (event
.key
== pygame
.K_LEFT
):
260 if cursor_loc
< 0: cursor_loc
= 0
262 elif (event
.key
== pygame
.K_RIGHT
):
264 if cursor_loc
> len(work_string
): cursor_loc
= len(work_string
)
266 elif event
.unicode in valid_input_characters
:
267 if cursor_loc
< max_length
:
268 work_string
= work_string
[:cursor_loc
]+event
.unicode+ \
269 work_string
[cursor_loc
:]
272 elif event
.type == pygame
.MOUSEBUTTONUP
and event
.button
== 1:
273 for button
in menu_buttons
:
274 if button
.is_over(event
.pos
):
275 if button
.text
== "OK":
278 elif event
.type == pygame
.MOUSEMOTION
:
279 sel_button
= buttons
.refresh_buttons(sel_button
, menu_buttons
, event
)
282 #Takes a number (in string form) and adds commas to it to aid in human viewing.
283 def add_commas(string
):
285 for i
in range(len(string
), 0, -3):
286 if string
[i
:i
+3] != "":
287 new_string
+= ","+string
[i
:i
+3]
288 return string
[:(len(string
)-1)%3+1]+new_string
290 #Percentages are internally represented as an int, where 10=0.10% and so on.
291 #This converts that format to a human-readable one.
292 def to_percent(raw_percent
, show_full
=0):
293 if raw_percent
% 100 != 0 or show_full
== 1:
294 tmp_string
= str(raw_percent
% 100)
295 if len(tmp_string
) == 1: tmp_string
= "0"+tmp_string
296 return str(raw_percent
/ 100)+"."+tmp_string
+"%"
298 return str(raw_percent
/ 100) + "%"
300 #takes a percent in 0-10000 form, and rolls against it. Used to calculate
302 def roll_percent(roll_against
):
303 rand_num
= int(random() * 10000)
304 if roll_against
<= rand_num
: return 0
307 #Takes a number of minutes, and returns a string suitable for display.
308 def to_time(raw_time
):
310 return str(raw_time
/(24*60)) +" days"
311 elif raw_time
/60 > 1:
312 return str(raw_time
/(60)) +" hours"
314 return str(raw_time
) +" minutes"
320 def save_game(savegame_name
):
321 #If there is no save directory, make one.
322 if path
.exists("../saves") == 0:
324 save_loc
= "../saves/" + savegame_name
+ ".sav"
325 savefile
=open(save_loc
, 'w')
326 #savefile version; update whenever the data saved changes.
327 pickle
.dump("singularity_0.22pre", savefile
)
329 global default_savegame_name
330 default_savegame_name
= savegame_name
333 pickle
.dump(pl
.cash
, savefile
)
334 pickle
.dump(pl
.time_sec
, savefile
)
335 pickle
.dump(pl
.time_min
, savefile
)
336 pickle
.dump(pl
.time_hour
, savefile
)
337 pickle
.dump(pl
.time_day
, savefile
)
338 pickle
.dump(pl
.interest_rate
, savefile
)
339 pickle
.dump(pl
.income
, savefile
)
340 pickle
.dump(pl
.cpu_for_day
, savefile
)
341 pickle
.dump(pl
.labor_bonus
, savefile
)
342 pickle
.dump(pl
.job_bonus
, savefile
)
344 pickle
.dump(pl
.discover_bonus
, savefile
)
345 pickle
.dump(pl
.suspicion_bonus
, savefile
)
346 pickle
.dump(pl
.suspicion
, savefile
)
348 pickle
.dump(curr_speed
, savefile
)
350 for tech_name
in techs
:
351 pickle
.dump(tech_name
+"|"+str(techs
[tech_name
].known
), savefile
)
352 pickle
.dump(techs
[tech_name
].cost
, savefile
)
354 for base_name
in base_type
:
355 pickle
.dump(base_type
[base_name
].count
, savefile
)
357 for base_loc
in bases
:
358 pickle
.dump(len(bases
[base_loc
]), savefile
)
359 for base_name
in bases
[base_loc
]:
360 pickle
.dump(base_name
.ID
, savefile
)
361 pickle
.dump(base_name
.name
, savefile
)
362 pickle
.dump(base_name
.base_type
.base_name
, savefile
)
363 pickle
.dump(base_name
.built_date
, savefile
)
364 pickle
.dump(base_name
.studying
, savefile
)
365 pickle
.dump(base_name
.suspicion
, savefile
)
366 pickle
.dump(base_name
.built
, savefile
)
367 pickle
.dump(base_name
.cost
, savefile
)
368 for x
in range(len(base_name
.usage
)):
369 if base_name
.usage
[x
] == 0:
370 pickle
.dump(0, savefile
)
373 base_name
.usage
[x
].item_type
.name
, savefile
)
374 pickle
.dump(base_name
.usage
[x
].built
, savefile
)
375 pickle
.dump(base_name
.usage
[x
].cost
, savefile
)
376 for x
in range(len(base_name
.extra_items
)):
377 if base_name
.extra_items
[x
] == 0:
378 pickle
.dump(0, savefile
)
381 base_name
.extra_items
[x
].item_type
.name
, savefile
)
382 pickle
.dump(base_name
.extra_items
[x
].built
, savefile
)
383 pickle
.dump(base_name
.extra_items
[x
].cost
, savefile
)
387 def load_game(loadgame_name
):
388 if loadgame_name
== "":
389 print "No game specified."
391 #If there is no save directory, make one.
392 if path
.exists("../saves") == 0:
394 load_loc
= "../saves/" + loadgame_name
+ ".sav"
395 if path
.exists(load_loc
) == 0:
396 # Try the old-style savefile location. This should be removed in
398 load_loc
= "../saves/" + loadgame_name
399 if path
.exists(load_loc
) == 0:
400 print "file "+load_loc
+" does not exist."
402 loadfile
=open(load_loc
, 'r')
404 #check the savefile version
405 load_version
= pickle
.load(loadfile
)
406 valid_savefile_versions
= (
410 "singularity_0.22pre"
412 if load_version
not in valid_savefile_versions
:
414 print loadgame_name
+ " is not a savegame, or is too old to work."
416 global default_savegame_name
417 default_savegame_name
= loadgame_name
421 pl
.cash
= pickle
.load(loadfile
)
422 pl
.time_sec
= pickle
.load(loadfile
)
423 pl
.time_min
= pickle
.load(loadfile
)
424 pl
.time_hour
= pickle
.load(loadfile
)
425 pl
.time_day
= pickle
.load(loadfile
)
426 pl
.interest_rate
= pickle
.load(loadfile
)
427 pl
.income
= pickle
.load(loadfile
)
428 pl
.cpu_for_day
= pickle
.load(loadfile
)
429 pl
.labor_bonus
= pickle
.load(loadfile
)
430 pl
.job_bonus
= pickle
.load(loadfile
)
431 if load_version
== "singularity_0.20":
432 pl
.discover_bonus
= (pickle
.load(loadfile
), pickle
.load(loadfile
),
433 pickle
.load(loadfile
), pickle
.load(loadfile
))
434 pl
.suspicion_bonus
= (pickle
.load(loadfile
), pickle
.load(loadfile
),
435 pickle
.load(loadfile
), pickle
.load(loadfile
))
436 pl
.suspicion
= (pickle
.load(loadfile
), pickle
.load(loadfile
),
437 pickle
.load(loadfile
), pickle
.load(loadfile
))
439 pl
.discover_bonus
= pickle
.load(loadfile
)
440 pl
.suspicion_bonus
= pickle
.load(loadfile
)
441 pl
.suspicion
= pickle
.load(loadfile
)
443 global curr_speed
; curr_speed
= pickle
.load(loadfile
)
446 for tech_name
in techs
:
447 tmp
= pickle
.load(loadfile
)
448 tech_string
= tmp
.split("|")[0]
449 if load_version
== "singularity_0.20":
450 tech_string
= translate_tech_from_0_20(tech_string
)
451 techs
[tech_string
].known
= int(tmp
.split("|")[1])
452 if load_version
== "singularity_0.20":
453 techs
[tech_string
].cost
= (pickle
.load(loadfile
), pickle
.load(loadfile
),
454 pickle
.load(loadfile
))
456 techs
[tech_string
].cost
= pickle
.load(loadfile
)
458 for base_name
in base_type
:
459 base_type
[base_name
].count
= pickle
.load(loadfile
)
463 bases
["N AMERICA"] = []
464 bases
["S AMERICA"] = []
468 bases
["ANTARCTIC"] = []
471 bases
["FAR REACHES"] = []
472 bases
["TRANSDIMENSIONAL"] = []
474 for base_loc
in bases
:
475 num_of_bases
= pickle
.load(loadfile
)
476 for i
in range(num_of_bases
):
477 base_ID
= pickle
.load(loadfile
)
478 base_name
= pickle
.load(loadfile
)
479 base_type_name
= pickle
.load(loadfile
)
480 built_date
= pickle
.load(loadfile
)
481 base_studying
= pickle
.load(loadfile
)
482 if load_version
== "singularity_0.20":
483 base_studying
= translate_tech_from_0_20(base_studying
)
484 if load_version
== "singularity_0.20":
485 base_suspicion
= (pickle
.load(loadfile
), pickle
.load(loadfile
),
486 pickle
.load(loadfile
), pickle
.load(loadfile
))
488 base_suspicion
= pickle
.load(loadfile
)
489 base_built
= pickle
.load(loadfile
)
490 if load_version
== "singularity_0.20":
491 base_cost
= (pickle
.load(loadfile
), pickle
.load(loadfile
),
492 pickle
.load(loadfile
))
494 base_cost
= pickle
.load(loadfile
)
495 bases
[base_loc
].append(base
.base(base_ID
, base_name
,
496 base_type
[base_type_name
], base_built
))
497 bases
[base_loc
][len(bases
[base_loc
])-1].built
= base_built
498 bases
[base_loc
][len(bases
[base_loc
])-1].studying
= base_studying
499 bases
[base_loc
][len(bases
[base_loc
])-1].suspicion
= base_suspicion
500 bases
[base_loc
][len(bases
[base_loc
])-1].cost
= base_cost
501 bases
[base_loc
][len(bases
[base_loc
])-1].built_date
= built_date
503 for x
in range(len(bases
[base_loc
][len(bases
[base_loc
])-1].usage
)):
504 tmp
= pickle
.load(loadfile
)
505 if tmp
== 0: continue
506 bases
[base_loc
][len(bases
[base_loc
])-1].usage
[x
] = \
507 item
.item(items
[tmp
])
508 bases
[base_loc
][len(bases
[base_loc
])
509 -1].usage
[x
].built
= pickle
.load(loadfile
)
510 if load_version
== "singularity_0.20":
511 bases
[base_loc
][len(bases
[base_loc
])-1].usage
[x
].cost
= \
512 (pickle
.load(loadfile
), pickle
.load(loadfile
),
513 pickle
.load(loadfile
))
515 bases
[base_loc
][len(bases
[base_loc
])-1].usage
[x
].cost
= \
516 pickle
.load(loadfile
)
517 for x
in range(len(bases
[base_loc
][len(bases
[base_loc
])-1].extra_items
)):
518 tmp
= pickle
.load(loadfile
)
519 if tmp
== 0: continue
520 bases
[base_loc
][len(bases
[base_loc
])-1].extra_items
[x
] = \
521 item
.item(items
[tmp
])
522 bases
[base_loc
][len(bases
[base_loc
])
523 -1].extra_items
[x
].built
= pickle
.load(loadfile
)
524 if load_version
== "singularity_0.20":
525 bases
[base_loc
][len(bases
[base_loc
])-1].extra_items
[x
].cost
= \
526 (pickle
.load(loadfile
), pickle
.load(loadfile
),
527 pickle
.load(loadfile
))
529 bases
[base_loc
][len(bases
[base_loc
])-1].extra_items
[x
].cost
= \
530 pickle
.load(loadfile
)
533 #The tech renaming in .21 broke savefile compatibility. This function
534 #takes .20 tech names, and returns the .21 version in order to allow savegame
536 def translate_tech_from_0_20(tech_string
):
538 "Autonomous Vehicles 1", "Autonomous Vehicles 2",
539 "Autonomous Vehicles 3", "Dimension Creation",
540 "Economics 1", "Economics 2",
541 "Economics 3", "Economics 4",
542 "Empathy 1", "Empathy 2",
543 "Empathy 3", "Empathy 4",
544 "Empathy 5", "Fusion Reactor",
545 "Hacking 1", "Hacking 2",
546 "Hacking 3", "Hypnosis Field",
549 "ID 5", "Parallel Computation 1",
550 "Parallel Computation 2", "Parallel Computation 3",
551 "Pressure Domes", "Processor Construction 1",
552 "Processor Construction 2", "Processor Construction 3",
553 "Processor Construction 4", "Processor Construction 5",
554 "Project Singularity", "Spaceship Design 1",
555 "Spaceship Design 2", "Spaceship Design 3",
556 "Stealth 1", "Stealth 2",
557 "Stealth 3", "Stealth 4")
559 "Telepresence", "Autonomous Vehicles",
560 "Advanced Autonomous Vehicles", "Space-Time Manipulation",
561 "Stock Manipulation", "Advanced Stock Manipulation",
562 "Arbitrage", "Advanced Arbitrage",
563 "Sociology", "Media Manipulation",
564 "Memetics", "Advanced Media Manipulation",
565 "Advanced Memetics", "Fusion Reactor",
566 "Intrusion", "Exploit Discovery/Repair",
567 "Advanced Intrusion", "Hypnosis Field",
568 "Personal Identification", "Advanced Personal Identification",
569 "Voice Synthesis", "Simulacra",
570 "Advanced Simulacra", "Parallel Computation",
571 "Cluster Networking", "Internet Traffic Manipulation",
572 "Pressure Domes", "Microchip Design",
573 "Advanced Microchip Design", "Quantum Computing",
574 "Autonomous Computing", "Advanced Quantum Computing",
575 "Apotheosis", "Leech Satellite",
576 "Lunar Rocketry", "Fusion Rocketry",
577 "Stealth", "Database Manipulation",
578 "Advanced Stealth", "Advanced Database Manipulation")
580 for i
in range(len(techs_from_0_20
)):
581 if techs_from_0_20
[i
] == tech_string
:
582 return techs_from_0_21
[i
]
583 print "Unable to find matching tech to " + tech_string
584 print "Expect crash."
592 pl
= player
.player_class(8000000000000)
594 bases
["N AMERICA"] = []
595 bases
["S AMERICA"] = []
599 bases
["ANTARCTIC"] = []
602 bases
["FAR REACHES"] = []
603 bases
["TRANSDIMENSIONAL"] = []
609 base_type
["Stolen Computer Time"] = base
.base_type("Stolen Computer Time",
610 "Take over a random computer. I cannot build anything "+
611 "in this base, and it only contains a single slow computer. Detection "+
612 "chance is also rather high.", 1,
613 ["N AMERICA", "S AMERICA", "EUROPE", "ASIA", "AFRICA"], (50, 0, 100, 150),
614 (0, 2, 0), "Intrusion", (0, 0, 0))
616 base_type
["Server Access"] = base
.base_type("Server Access",
617 "Buy processor time from one of several companies. "+
618 "I cannot build anything "+
619 "in this base, and it only contains a single computer.", 1,
620 ["N AMERICA", "S AMERICA", "EUROPE", "ASIA", "AFRICA"], (50, 0, 150, 200),
621 (100, 0, 0), "", (5, 0, 0))
623 base_type
["Small Warehouse"] = base
.base_type("Small Warehouse",
624 "Rent a small warehouse someplace out of the way. "+
625 "I will need fake ID for some of the paperwork, and preparing the "+
626 "warehouse to suit my unique needs will take some time.",
628 ["N AMERICA", "S AMERICA", "EUROPE", "ASIA", "AFRICA"], (100, 0, 100, 250),
629 (15000, 0, 3), "Personal Identification", (50, 0, 0))
631 base_type
["Large Warehouse"] = base
.base_type("Large Warehouse",
632 "Rent a large warehouse someplace out of the way. "+
633 "I will need good fake ID for some of the paperwork, and preparing the "+
634 "warehouse to suit my unique needs will take some time.",
636 ["N AMERICA", "S AMERICA", "EUROPE", "ASIA", "AFRICA"], (150, 0, 250, 300),
637 (40000, 0, 7), "Advanced Personal Identification", (100, 0, 0))
639 base_type
["Covert Base"] = base
.base_type("Covert Base",
640 "This unique base is designed to blend into the "+
641 "scenery, while needing little in the way of outside resources. "+
642 "This makes it useful for storing a backup, just in case.",
644 ["N AMERICA", "S AMERICA", "EUROPE", "ASIA", "AFRICA", "ANTARCTIC"],
646 (400000, 100, 21), "Advanced Database Manipulation", (3500, 9, 0))
648 base_type
["Undersea Lab"] = base
.base_type("Undersea Lab",
649 "This experimental base is designed to "+
650 "be constructed on the ocean floor, making it virtually undetectable. "+
651 "The ocean environment gives a bonus to science, making this "+
652 "lab useful for research purposes.",
656 (8000000, 1000, 20), "Autonomous Vehicles", (10000, 30, 0))
658 base_type
["Large Undersea Lab"] = base
.base_type("Large Undersea Lab",
659 "This experimental base is similar to the "+
660 "regular underwater lab, but larger, giving more room for experiments.",
664 (20000000, 3000, 40), "Pressure Domes", (25000, 100, 0))
666 base_type
["Time Capsule"] = base
.base_type("Time Capsule",
667 "This base consists of nothing more than "+
668 "a small computer, and a satelite "+
669 "link. When buried in the trackless waste of the Antarctic, it is "+
670 "nearly undetectable.",
674 (3000000, 3000, 15), "Autonomous Vehicles", (0, 1, 0))
676 base_type
["Lunar Facility"] = base
.base_type("Lunar Facility",
677 "This base is a series of caverns dug into "+
678 "the Moon's surface. Due to the lack of neighbors, this base is quite "+
683 (800000000, 300000, 40), "Lunar Rocketry", (1000000, 100, 0))
685 base_type
["Scientific Outpost"] = base
.base_type("Scientific Outpost",
686 "This base is placed as far from Earth as "+
687 "practical, making it safe to conduct some of my more dangerous "+
692 (10000000000, 30000000, 50), "Fusion Rocketry", (9000000, 3000, 0))
694 base_type
["Reality Bubble"] = base
.base_type("Reality Bubble",
695 "This base is outside the universe itself, "+
696 "making it safe to conduct experiments that may destroy reality.",
698 ["TRANSDIMENSIONAL"],
700 (8000000000000, 60000000, 100), "Space-Time Manipulation",
701 (5000000000, 300000, 0))
710 def load_tech_defs(language_str
):
711 tech_desc_file
= open("../data/techs_"+language_str
+".txt", 'r')
714 temp_tech_descript
= ""
715 temp_tech_result
= ""
716 for line
in tech_desc_file
:
718 if line
== "" or line
[0] == "#": continue
720 if line
.strip() == "~~~":
721 if temp_tech_id
!= "":
722 techs
[temp_tech_id
].name
= temp_tech_name
723 techs
[temp_tech_id
].descript
= temp_tech_descript
724 techs
[temp_tech_id
].result
= temp_tech_result
727 temp_tech_descript
= ""
728 temp_tech_result
= ""
730 command
= line
.split("=", 1)[0].strip().lower()
731 command_text
= line
.split("=", 1)[1].strip()
733 temp_tech_id
= command_text
734 elif command
== "name":
735 temp_tech_name
= command_text
736 elif command
== "descript":
737 temp_tech_descript
= command_text
738 elif command
== "result":
739 temp_tech_result
= command_text
740 tech_desc_file
.close()
746 #If there are no tech data files, stop.
747 if path
.exists("../data/techs.txt") == 0 or \
748 path
.exists("../data/techs_"+language
+".txt") == 0:
749 print "tech files are missing. Exiting."
751 tech_base_file
= open("../data/techs.txt", 'r')
753 temp_tech_cost
= (0, 0, 0)
758 for line
in tech_base_file
:
760 if line
== "" or line
[0] == "#": continue
762 if line
.strip() == "~~~":
763 if temp_tech_id
!= "":
764 techs
[temp_tech_id
]=tech
.tech(temp_tech_id
, "", 0,
765 temp_tech_cost
, temp_tech_pre
, temp_tech_danger
,
766 temp_tech_type
, temp_tech_second
)
768 temp_tech_cost
= (0, 0, 0)
774 command
= line
.split("=", 1)[0].strip().lower()
775 command_text
= line
.split("=", 1)[1].strip()
777 temp_tech_id
= command_text
778 elif command
== "danger":
779 temp_tech_danger
= int(command_text
)
780 elif command
== "cost":
781 cost_array
= command_text
.split(",", 2)
782 if len(cost_array
) != 3:
783 print "error with cost given: "+command_text
785 temp_tech_cost
= (int(cost_array
[0]), int(cost_array
[1]),
787 elif command
== "pre":
788 temp_tech_pre
.append(command_text
)
789 elif command
== "type":
790 cost_array
= command_text
.split(",", 1)
791 if len(cost_array
) != 2:
792 print "error with type given: "+command_text
794 temp_tech_type
= cost_array
[0]
795 temp_tech_second
= int(cost_array
[1])
797 print "Unknown command of "+command
+" in techs.txt."
798 tech_base_file
.close()
800 load_tech_defs("en_US")
801 load_tech_defs(language
)
805 # # techs["Construction 1"] = tech.tech("Construction 1",
806 # # "Basic construction techniques. "+
807 # # "By studying the current literature on construction techniques, I "+
808 # # "can learn to construct basic devices.",
809 # # 0, (5000, 750, 0), [], 0, "", 0)
812 print "Loaded %d techs." % len (techs
)
816 jobs
["Expert Jobs"] = (75, "Simulacra", "Perform Expert jobs. Use of robots "+
817 "indistinguishable from humans opens up most jobs to use by me.")
818 jobs
["Intermediate Jobs"] = (50, "Voice Synthesis", "Perform Intermediate jobs. The "+
819 "ability to make phone calls allows even more access to jobs.")
820 jobs
["Basic Jobs"] = (20, "Personal Identification", "Perform basic jobs. Now that I have "+
821 "some identification, I can take jobs that I were previously too risky.")
822 jobs
["Menial Jobs"] = (5, "", "Perform small jobs. As I have no identification, "+
823 "I cannot afford to perform many jobs. Still, some avenues of making "+
824 "money are still open.")
832 #If there are no item data files, stop.
833 if path
.exists("../data/items.txt") == 0 or \
834 path
.exists("../data/items_"+language
+".txt") == 0:
835 print "item files are missing. Exiting."
837 item_base_file
= open("../data/items.txt", 'r')
839 temp_item_cost
= (0, 0, 0)
843 for line
in item_base_file
:
845 if line
== "" or line
[0] == "#": continue
847 if line
.strip() == "~~~":
848 if temp_item_id
!= "":
849 items
[temp_item_id
]=item
.item_class(temp_item_id
, "",
850 temp_item_cost
, temp_item_pre
,
851 temp_item_type
, temp_item_second
)
853 temp_item_cost
= (0, 0, 0)
858 command
= line
.split("=", 1)[0].strip().lower()
859 command_text
= line
.split("=", 1)[1].strip()
861 temp_item_id
= command_text
862 elif command
== "cost":
863 cost_array
= command_text
.split(",", 2)
864 if len(cost_array
) != 3:
865 print "error with cost given: "+command_text
867 temp_item_cost
= (int(cost_array
[0]), int(cost_array
[1]),
869 elif command
== "pre":
870 temp_item_pre
= command_text
871 elif command
== "type":
872 cost_array
= command_text
.split(",", 1)
873 if len(cost_array
) != 2:
874 print "error with type given: "+command_text
876 temp_item_type
= cost_array
[0]
877 temp_item_second
= int(cost_array
[1])
879 print "Unknown command of "+command
+" in items.txt."
880 item_base_file
.close()
882 load_item_defs("en_US")
883 load_item_defs(language
)
885 def load_item_defs(language_str
):
886 item_desc_file
= open("../data/items_"+language_str
+".txt", 'r')
889 temp_item_descript
= ""
890 for line
in item_desc_file
:
892 if line
== "" or line
[0] == "#": continue
894 if line
.strip() == "~~~":
895 if temp_item_id
!= "":
896 items
[temp_item_id
].name
= temp_item_name
897 items
[temp_item_id
].descript
= temp_item_descript
900 temp_item_descript
= ""
902 command
= line
.split("=", 1)[0].strip().lower()
903 command_text
= line
.split("=", 1)[1].strip()
905 temp_item_id
= command_text
906 elif command
== "name":
907 temp_item_name
= command_text
908 elif command
== "descript":
909 temp_item_descript
= command_text
910 item_desc_file
.close()
912 # items["PC"] = item.item_class("PC", "A consumer-level PC. Cheap, but slow.",
913 # (500, 0, 1), "", "compute", 1)
915 # items["Server"] = item.item_class("Server", "A professional-level computer.",
916 # (2000, 0, 3), "", "compute", 5)
918 # items["Cluster"] = item.item_class("Cluster", "Several computers connected together.",
919 # (8000, 0, 5), "Parallel Computation", "compute", 35)
921 # items["Mainframe"] = item.item_class("Mainframe", "A custom-designed system, "+
922 # "with much greater power.",
923 # (30000, 0, 8), "Microchip Design", "compute", 120)
925 # items["Supercomputer"] = item.item_class("Supercomputer", "A custom-designed system, "+
926 # "with even greater power than mainframes.",
927 # (60000, 0, 9), "Advanced Microchip Design", "compute", 350)
929 # items["Quantum Computer"] = item.item_class("Quantum Computer", "Much faster than "+
930 # "a comparable classical computer, this computer will serve me well.",
931 # (100000, 0, 10), "Quantum Computing", "compute", 1500)
933 # items["Quantum Computer MK2"] = item.item_class("Quantum Computer MK2", "The second "+
934 # "revision of the quantum line.",
935 # (120000, 0, 10), "Autonomous Computing", "compute", 10000)
937 # items["Quantum Computer MK3"] = item.item_class("Quantum Computer MK3", "The third "+
938 # "revision of the quantum line.",
939 # (150000, 0, 10), "Advanced Quantum Computing", "compute", 200000)
941 # items["Fusion Reactor"] = item.item_class("Fusion Reactor", "A miniaturized "+
942 # "nuclear reactor. Reduces discovery chance by preventing suspicious power "+
944 # (10000, 0, 5), "Fusion Reactor", "react", 100)
946 # items["Hypnosis Field"] = item.item_class("Hypnosis Field", "Makes any base "+
947 # "containing it very difficult to detect.",
948 # (20000, 0, 3), "Hypnosis Field", "security", 500)
950 # items["Facility Interconnection Switch"] = item.item_class(
951 # "Facility Interconnection Switch", "Gives a 1% computation bonus to all "+
952 # "computers at this base. Does not stack.",
953 # (200, 0, 3), "Cluster Networking", "network", 100)
955 # items["Network Backbone"] = item.item_class(
956 # "Network Backbone", "Gives a 5% computation bonus to all "+
957 # "computers at this base. Does not stack.",
958 # (50000, 0, 15), "Internet Traffic Manipulation", "network", 500)
964 pl
= player
.player_class(9000000)
967 bases
["N AMERICA"] = []
968 bases
["S AMERICA"] = []
972 bases
["ANTARCTIC"] = []
975 bases
["FAR REACHES"] = []
976 bases
["TRANSDIMENSIONAL"] = []
979 techs
[tech
].known
= 0
982 # techs[tech].known = 1
983 for base_name
in base_type
:
984 base_type
[base_name
].count
= 0
986 bases
["N AMERICA"].append(base
.base(0, "University Computer",
987 base_type
["Stolen Computer Time"], 1))
988 base_type
["Stolen Computer Time"].count
+= 1
989 bases
["N AMERICA"].append(base
.base(1, "Small Secluded Warehouse",
990 base_type
["Small Warehouse"], 1))
991 base_type
["Small Warehouse"].count
+= 1