* /trunk/code/singularity.py
[singularity-git.git] / code / g.py
blob3e848af373056027e5a0df2db0b24a133fa06d78
1 #file: g.py
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.
21 import pygame, sys
22 from os import listdir, path
23 import pickle
24 from random import random
26 import player, base, buttons, tech, item
28 #screen is the actual pygame display.
29 global screen
31 #size of the screen. This can be set via command-line option.
32 global screen_size
33 screen_size = (800, 600)
35 #Used to pass time in the main screen.
36 global clock
37 clock = pygame.time.Clock()
39 #Allows access to the cheat menu.
40 global cheater
41 cheater = 0
43 #Kills the sound. Should allow usage of the game without SDL_mixer,
44 # but is untested.
45 global nosound
46 nosound = 0
48 #Gives debug info at various points.
49 global debug
50 debug = 0
52 #Used to determine which data files to load.
53 global language
54 language = "en_US"
56 global default_savegame_name
57 default_savegame_name = "player"
59 def quit_game():
60 sys.exit()
62 #colors:
63 colors = {}
65 def fill_colors():
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)
79 picts = {}
80 #Load all pictures from the data directory.
81 def load_pictures():
82 global picts
83 if pygame.image.get_extended() == 0:
84 print "Error: SDL_image required. Exiting."
85 sys.exit()
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)
94 sounds = {}
95 #Load all sounds from the data directory.
96 def load_sounds():
97 global sounds
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.
101 pygame.mixer.init()
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)
108 def play_click():
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()
116 # Font functions.
119 #Normal and Acknowledge fonts.
120 global fonts
121 font = []
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):
129 if 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)
136 else:
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):
153 start_xy = xy
154 string_array = string_to_print.split()
156 for string in string_array:
157 string += " "
158 temp_size = font.size(string)
160 if string == "\\n ":
161 xy = (start_xy[0], xy[1]+temp_size[1])
162 continue
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),
174 text_color)
175 menu_buttons = []
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()
184 sel_button = -1
185 while 1:
186 clock.tick(60)
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":
197 play_click()
198 return
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)
219 # if cursor_loc > 0:
220 # cursor_loc += 1
222 menu_buttons = []
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()
231 sel_button = -1
232 need_redraw = True
233 while 1:
234 if need_redraw:
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,
237 size[0]-12, 23))
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()
243 need_redraw = False
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):
250 if cursor_loc > 0:
251 work_string = work_string[:cursor_loc-1]+work_string[cursor_loc:]
252 cursor_loc -= 1
253 need_redraw = True
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:]
257 need_redraw = True
258 elif (event.key == pygame.K_LEFT):
259 cursor_loc -= 1
260 if cursor_loc < 0: cursor_loc = 0
261 need_redraw = True
262 elif (event.key == pygame.K_RIGHT):
263 cursor_loc += 1
264 if cursor_loc > len(work_string): cursor_loc = len(work_string)
265 need_redraw = True
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:]
270 cursor_loc += 1
271 need_redraw = True
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":
276 play_click()
277 return work_string
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):
284 new_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+"%"
297 else:
298 return str(raw_percent / 100) + "%"
300 #takes a percent in 0-10000 form, and rolls against it. Used to calculate
301 #percentage chances.
302 def roll_percent(roll_against):
303 rand_num = int(random() * 10000)
304 if roll_against <= rand_num: return 0
305 return 1
307 #Takes a number of minutes, and returns a string suitable for display.
308 def to_time(raw_time):
309 if raw_time/60 > 48:
310 return str(raw_time/(24*60)) +" days"
311 elif raw_time/60 > 1:
312 return str(raw_time/(60)) +" hours"
313 else:
314 return str(raw_time) +" minutes"
318 #load/save
320 def save_game(savegame_name):
321 #If there is no save directory, make one.
322 if path.exists("../saves") == 0:
323 mkdir("../saves")
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
332 #general player data
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)
371 else:
372 pickle.dump(
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)
379 else:
380 pickle.dump(
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)
385 savefile.close()
387 def load_game(loadgame_name):
388 if loadgame_name == "":
389 print "No game specified."
390 return -1
391 #If there is no save directory, make one.
392 if path.exists("../saves") == 0:
393 mkdir("../saves")
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
397 # a few versions.
398 load_loc = "../saves/" + loadgame_name
399 if path.exists(load_loc) == 0:
400 print "file "+load_loc+" does not exist."
401 return -1
402 loadfile=open(load_loc, 'r')
404 #check the savefile version
405 load_version = pickle.load(loadfile)
406 valid_savefile_versions = (
407 "singularity_0.20",
408 "singularity_0.21",
409 "singularity_0.21a",
410 "singularity_0.22pre"
412 if load_version not in valid_savefile_versions:
413 loadfile.close()
414 print loadgame_name + " is not a savegame, or is too old to work."
415 return -1
416 global default_savegame_name
417 default_savegame_name = loadgame_name
419 #general player data
420 global pl
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))
438 else:
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)
444 global techs
445 load_techs()
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))
455 else:
456 techs[tech_string].cost = pickle.load(loadfile)
458 for base_name in base_type:
459 base_type[base_name].count = pickle.load(loadfile)
461 global bases
462 bases = {}
463 bases["N AMERICA"] = []
464 bases["S AMERICA"] = []
465 bases["EUROPE"] = []
466 bases["ASIA"] = []
467 bases["AFRICA"] = []
468 bases["ANTARCTIC"] = []
469 bases["OCEAN"] = []
470 bases["MOON"] = []
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))
487 else:
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))
493 else:
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))
514 else:
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))
528 else:
529 bases[base_loc][len(bases[base_loc])-1].extra_items[x].cost = \
530 pickle.load(loadfile)
531 loadfile.close()
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
535 #loading.
536 def translate_tech_from_0_20(tech_string):
537 techs_from_0_20 = (
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",
547 "ID 1", "ID 2",
548 "ID 3", "ID 4",
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")
558 techs_from_0_21 = (
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")
579 i = 0
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."
585 return -1
589 # Data
591 curr_speed = 1
592 pl = player.player_class(8000000000000)
593 bases = {}
594 bases["N AMERICA"] = []
595 bases["S AMERICA"] = []
596 bases["EUROPE"] = []
597 bases["ASIA"] = []
598 bases["AFRICA"] = []
599 bases["ANTARCTIC"] = []
600 bases["OCEAN"] = []
601 bases["MOON"] = []
602 bases["FAR REACHES"] = []
603 bases["TRANSDIMENSIONAL"] = []
605 base_type = {}
608 #Base types
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"],
645 (50, 100, 100, 0),
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.",
654 ["OCEAN"],
655 (50, 100, 150, 0),
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.",
662 ["OCEAN"],
663 (100, 200, 200, 0),
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.",
672 ["ANTARCTIC"],
673 (0, 10, 10, 0),
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 "+
679 "large.",
680 600,
681 ["MOON"],
682 (50, 300, 200, 0),
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 "+
688 "experiments.",
689 225,
690 ["FAR REACHES"],
691 (10, 200, 100, 0),
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"],
699 (0, 300, 150, 0),
700 (8000000000000, 60000000, 100), "Space-Time Manipulation",
701 (5000000000, 300000, 0))
706 #Techs.
708 techs = {}
710 def load_tech_defs(language_str):
711 tech_desc_file = open("../data/techs_"+language_str+".txt", 'r')
712 temp_tech_id = ""
713 temp_tech_name = ""
714 temp_tech_descript = ""
715 temp_tech_result = ""
716 for line in tech_desc_file:
717 line=line.strip()
718 if line == "" or line[0] == "#": continue
719 #add a new tech.
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
725 temp_tech_id = ""
726 temp_tech_name = ""
727 temp_tech_descript = ""
728 temp_tech_result = ""
729 continue
730 command = line.split("=", 1)[0].strip().lower()
731 command_text= line.split("=", 1)[1].strip()
732 if command == "id":
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()
742 def load_techs():
743 global techs
744 techs = {}
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."
750 sys.exit()
751 tech_base_file = open("../data/techs.txt", 'r')
752 temp_tech_id = ""
753 temp_tech_cost = (0, 0, 0)
754 temp_tech_pre = []
755 temp_tech_danger = 0
756 temp_tech_type = ""
757 temp_tech_second = 0
758 for line in tech_base_file:
759 line=line.strip()
760 if line == "" or line[0] == "#": continue
761 #add a new tech.
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)
767 temp_tech_id = ""
768 temp_tech_cost = (0, 0, 0)
769 temp_tech_pre = []
770 temp_tech_danger = 0
771 temp_tech_type = ""
772 temp_tech_second = 0
773 continue
774 command = line.split("=", 1)[0].strip().lower()
775 command_text= line.split("=", 1)[1].strip()
776 if command == "id":
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
784 sys.exit()
785 temp_tech_cost = (int(cost_array[0]), int(cost_array[1]),
786 int(cost_array[2]))
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
793 sys.exit()
794 temp_tech_type = cost_array[0]
795 temp_tech_second = int(cost_array[1])
796 else:
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)
811 if debug:
812 print "Loaded %d techs." % len (techs)
813 load_techs()
815 jobs = {}
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.")
827 items = {}
828 def load_items():
829 global items
830 items = {}
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."
836 sys.exit()
837 item_base_file = open("../data/items.txt", 'r')
838 temp_item_id = ""
839 temp_item_cost = (0, 0, 0)
840 temp_item_pre = ""
841 temp_item_type = ""
842 temp_item_second = 0
843 for line in item_base_file:
844 line=line.strip()
845 if line == "" or line[0] == "#": continue
846 #add a new item.
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)
852 temp_item_id = ""
853 temp_item_cost = (0, 0, 0)
854 temp_item_pre = ""
855 temp_item_type = ""
856 temp_item_second = 0
857 continue
858 command = line.split("=", 1)[0].strip().lower()
859 command_text= line.split("=", 1)[1].strip()
860 if command == "id":
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
866 sys.exit()
867 temp_item_cost = (int(cost_array[0]), int(cost_array[1]),
868 int(cost_array[2]))
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
875 sys.exit()
876 temp_item_type = cost_array[0]
877 temp_item_second = int(cost_array[1])
878 else:
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')
887 temp_item_id = ""
888 temp_item_name = ""
889 temp_item_descript = ""
890 for line in item_desc_file:
891 line=line.strip()
892 if line == "" or line[0] == "#": continue
893 #add a new item.
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
898 temp_item_id = ""
899 temp_item_name = ""
900 temp_item_descript = ""
901 continue
902 command = line.split("=", 1)[0].strip().lower()
903 command_text= line.split("=", 1)[1].strip()
904 if command == "id":
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 "+
943 # "drains.",
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)
960 def new_game():
961 global curr_speed
962 curr_speed = 1
963 global pl
964 pl = player.player_class(9000000)
965 global bases
966 bases = {}
967 bases["N AMERICA"] = []
968 bases["S AMERICA"] = []
969 bases["EUROPE"] = []
970 bases["ASIA"] = []
971 bases["AFRICA"] = []
972 bases["ANTARCTIC"] = []
973 bases["OCEAN"] = []
974 bases["MOON"] = []
975 bases["FAR REACHES"] = []
976 bases["TRANSDIMENSIONAL"] = []
977 load_techs()
978 for tech in techs:
979 techs[tech].known = 0
980 # if cheater == 1:
981 # for tech in techs:
982 # techs[tech].known = 1
983 for base_name in base_type:
984 base_type[base_name].count = 0
985 #Starting base
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