OSDN Git Service

翻訳
[lcs-jp/lcs-jp.git] / src / daily / activities.cpp
1 /*
2
3 Copyright (c) 2002,2003,2004 by Tarn Adams                                            //
4                                                                                       //
5 This file is part of Liberal Crime Squad.                                             //
6                                                                                     //
7     Liberal Crime Squad is free software; you can redistribute it and/or modify     //
8     it under the terms of the GNU General Public License as published by            //
9     the Free Software Foundation; either version 2 of the License, or               //
10     (at your option) any later version.                                             //
11                                                                                     //
12     Liberal Crime Squad is distributed in the hope that it will be useful,          //
13     but WITHOUT ANY WARRANTY; without even the implied warranty of                  //
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   See the                  //
15     GNU General Public License for more details.                                    //
16                                                                                     //
17     You should have received a copy of the GNU General Public License               //
18     along with Liberal Crime Squad; if not, write to the Free Software              //
19     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA   02111-1307   USA     //
20 */
21
22 /*
23         This file was created by Chris Johnson (grundee@users.sourceforge.net)
24         by copying code from game.cpp.
25         To see descriptions of files and functions, see the list at
26         the bottom of includes.h in the top src folder.
27 */
28
29 // Note: this file is encoded in the PC-8 / Code Page 437 / OEM-US character set
30 // (The same character set used by Liberal Crime Squad when it is running)
31 // Certain special characters won't display correctly unless your text editor is
32 // set to use that character set, such as this e with an accent: é
33
34 // In Windows Notepad with the Terminal font, OEM/DOS encoding it should work fine.
35 // You can set this in Notepad by going to Format->Font and choosing the Terminal font,
36 // then choosing OEM/DOS in the Script dropdown box.
37
38 // In Notepad++ go to the Encoding menu, Character sets, Western European, OEM-US... easy!
39
40 // In Code::Blocks's editor go to Settings->Editor->the Other Settings tab and
41 // then pick WINDOWS-437 from the dropdown box and then choose the radio button
42 // to make this the default encoding and disable auto-detection of the encoding.
43 // Then close the file and reopen it (since Code::Blocks detects the encoding
44 // when it opens the file and it can't be changed after that; what we changed was
45 // how it detects encoding for files it opens in the future, not files already open).
46
47 // In Microsoft Visual C++, right-click the file in the Solution Explorer,
48 // select "Open With...", choose "C++ Source Code Editor (with encoding)",
49 // then choose "OEM United States - Codepage 437".
50
51 // In MS-DOS Editor (included with Windows as EDIT.COM in your system32 directory),
52 // the codepage will be correct already since it's running in a console window just
53 // like Liberal Crime Squad. Well OK, the encoding might be wrong, but then it's wrong
54 // in Liberal Crime Squad TOO, and to fix it, go to Control Panel, Regional and Language Settings,
55 // Advanced tab, and choose English (United States) from the dropdown box as the encoding
56 // for non-Unicode applications, then press OK.
57
58 // If you have a Linux or other UNIX-based system you are obviously smart enough
59 // to figure out for yourself how to open a file in OEM-US PC-8 codepage 437 in
60 // your favorite text editor. If you're on Mac OS X, well that's UNIX-based, figure
61 // it out for yourself.
62
63 #include <externs.h>
64
65 void doActivitySolicitDonations(vector<Creature *> &solicit, char &clearformess);
66 void doActivitySellTshirts(vector<Creature *> &tshirts, char &clearformess);
67 void doActivitySellArt(vector<Creature *> &art, char &clearformess);
68 void doActivitySellMusic(vector<Creature *> &music, char &clearformess);
69 void doActivitySellBrownies(vector<Creature *> &brownies, char &clearformess);
70 void doActivityHacking(vector<Creature *> &hack, char &clearformess);
71 void doActivityGraffiti(vector<Creature *> &graffiti, char &clearformess);
72 void doActivityProstitution(vector<Creature *> &prostitutes, char &clearformess);
73 void doActivityLearn(vector<Creature *> &students, char &clearformess);
74 void doActivityTrouble(vector<Creature *> &trouble, char &clearformess);
75 void doActivityTeach(vector<Creature *> &teachers, char &clearformess);
76 void doActivityBury(vector<Creature *> &bury, char &clearformess);
77
78
79 void adjustblogpower(int &power)
80 {
81    if(power<20)
82    {
83       switch(LCSrandom(20))
84       {
85       case 0:addstr("a sub-Liberal");break;
86       case 1:addstr("a really bad");break;
87       case 2:addstr("a pathetic");break;
88       case 3:addstr("a dreadful");break;
89       case 4:addstr("a god-awful");break;
90       case 5:addstr("a Conservative");break;
91       case 6:addstr("a heinous");break;
92       case 7:addstr("an embarrassing");break;
93       case 8:addstr("a shameful");break;
94       case 9:addstr("a counter-productive");break;
95       case 10:addstr("a sad");break;
96       case 11:addstr("a vapid");break;
97       case 12:addstr("a weak");break;
98       case 13:addstr("a brainless");break;
99       case 14:addstr("a repellant");break;
100       case 15:addstr("a nonsensical");break;
101       case 16:addstr("a ludicrous");break;
102       case 17:addstr("a half-baked");break;
103       case 18:addstr("a laughable");break;
104       case 19:addstr("an insane");break;
105       }
106       power = -signed(LCSrandom(2));
107    }
108    else if(power<35)
109    {
110       //switch(LCSrandom(1))
111       //{
112       //case 0:addstr("a fair");break;
113       //case 1:addstr("a mainstream");break;
114       //case 2:addstr("a mediocre");break;
115       //case 3:addstr("a middling");break;
116       //case 4:addstr("a passable");break;
117       //case 5:addstr("a regular");break;
118       //case 6:addstr("a normal");break;
119       //case 7:addstr("a standard");break;
120       //case 9:addstr("a reasonable");break;
121       //case 0:addstr("a typical");break;
122       //case 11:addstr("a vanilla");break;
123       //case 12:addstr("a basic");break;
124       //case 13:addstr("a plain");break;
125       //case 14:addstr("a simple");break;
126       /*case 0:*/addstr("a standard");//break;
127       //case 16:addstr("an everyday");break;
128       //case 17:addstr("a stock");break;
129       //case 18:addstr("a stereotypical");break;
130       //case 19:addstr("an okay");break;
131       //case 8:addstr("a respectable");break;
132       //}
133       power = 1;
134    }
135    else if(power<50)
136    {
137       switch(LCSrandom(11))
138       {
139       //case 0:addstr("a solid");break;
140       case 0:addstr("a good");break;
141       //case 2:addstr("an intelligent");break;
142       case 1:addstr("a satisfying");break;
143       //case 4:addstr("an impressive");break;
144       case 2:addstr("a sound");break;
145       //case 6:addstr("a splendid");break;
146       case 3:addstr("a competent");break;
147       case 4:addstr("a clever");break;
148       //case 10:addstr("a skillful");break;
149       //case 11:addstr("a talented");break;
150       case 5:addstr("a persuasive");break;
151       case 6:addstr("a thorough");break;
152       case 7:addstr("a bold");break;
153       //case 15:addstr("a clever");break;
154       case 8:addstr("a fresh");break;
155       case 9:addstr("a pointed");break;
156       case 10:addstr("a sassy");break;
157       //case 19:addstr("a sharp");break;
158       case 11:addstr("a Liberal");break;
159       }
160       power = 2;
161    }
162    else
163    {
164       switch(LCSrandom(10))
165       {
166       case 0:addstr("a great");break;
167       //case 1:addstr("a masterful");break;
168       //case 2:addstr("a penetrating");break;
169       //case 3:addstr("a profound");break;
170       case 1:addstr("a top-quality");break;
171       //case 5:addstr("a very sound");break;
172       case 2:addstr("an excellent");break;
173       //case 7:addstr("a competent");break;
174       case 3:addstr("a brilliant");break;
175       case 4:addstr("a powerful");break;
176       //case 10:addstr("a slick");break;
177       //case 11:addstr("a winning");break;
178       case 5:addstr("an inspiring");break;
179       case 6:addstr("a touching");break;
180       case 7:addstr("an eloquent");break;
181       case 8:addstr("a forceful");break;
182       case 9:addstr("a compelling");break;
183       //case 17:addstr("an impelling");break;
184       //case 18:addstr("a smooth");break;
185       case 10:addstr("an Elite Liberal");break;
186       }
187       power = 3;
188    }
189 }
190
191
192 /* armor repair */
193 void repairarmor(Creature &cr,char &clearformess)
194 {
195    Armor *armor=NULL;
196    Item *pile=NULL;
197    vector<Item *> *pilelist=NULL;
198    int pileindex = 0;
199
200    // Clean yourself up first
201    if(cr.get_armor().is_bloody() || cr.get_armor().is_damaged())
202       armor=&cr.get_armor();
203    else if(cr.squadid!=-1)
204    {
205       int sq=getsquad(cr.squadid);
206       for(int l=0;l<len(squad[sq]->loot);l++)
207          if(squad[sq]->loot[l]->is_armor())
208          {
209             Armor* a = static_cast<Armor*>(squad[sq]->loot[l]); //cast -XML
210             if (a->is_bloody() || a->is_damaged())
211             {
212                armor=a;
213                pile=squad[sq]->loot[l];
214                pileindex=l;
215                pilelist=&squad[sq]->loot;
216                break;
217             }
218          }
219    }
220    // Multiple passes, to find the best item to work on
221    bool dothis = false;
222    for (int passnum=0; passnum < 3 && !dothis; passnum++)
223       if(armor==NULL&&cr.location!=-1)
224          for(int l=0;l<len(location[cr.location]->loot);l++)
225             if(location[cr.location]->loot[l]->is_armor())
226             {
227                Armor* a = static_cast<Armor*>(location[cr.location]->loot[l]);//cast -XML
228                switch (passnum)
229                {
230                   case 0: // Guaranteed to accomplish something
231                      dothis = (a->is_bloody() && a->is_damaged());
232                      break;
233                   case 1: // Find something to clean if low skill, repair if high
234                      dothis =  (a->is_bloody() && armor_makedifficulty(*a,&cr)>4)
235                             || (a->is_damaged() && armor_makedifficulty(*a,&cr)<=4);
236                      break;
237                   case 2: // Anything that needs work
238                      dothis = (a->is_bloody() || a->is_damaged());
239                      break;
240                }
241                if(dothis)
242                {
243                   armor=a;
244                   pile=location[cr.location]->loot[l];
245                   pileindex=l;
246                   pilelist=&location[cr.location]->loot;
247                   break;
248                }
249             }
250
251    if(clearformess) erase();
252    else makedelimiter();
253
254    if(armor==NULL)
255    {
256       move(8,1);
257       addstr(cr.name, gamelog);
258       switch (LCSrandom(4))
259       {
260          case 0: addstr("はアジトを掃除した。", gamelog); break;
261          case 1: addstr("はアーマークローゼットを整理した。", gamelog); break;
262          case 2: addstr("は台所を片付けた。", gamelog); break;
263          case 3:
264             addstr("は手芸雑誌を読みふけった。", gamelog);
265             cr.train(SKILL_TAILORING,1);
266             break;
267       }
268       gamelog.nextMessage();
269
270       getkey();
271    }
272    else
273    {
274       string armorname = armor->get_name();// Get name before we maybe destroy it
275       bool repairfailed=false;
276       bool qualityReduction=!LCSrandom(10);
277       bool armorDestroyed=!armor->decrease_quality(0);
278
279       if(armor->is_damaged())
280       {
281          long dif=armor_makedifficulty(*armor,&cr);
282          dif>>=(armor->get_quality()-1);  // it is easy to patch up rags
283          cr.train(SKILL_TAILORING,dif/2+1);
284
285          if(LCSrandom(1+dif/2)) repairfailed=true;
286       }else{
287          repairfailed=true;
288       }
289       if (armorDestroyed)
290          repairfailed = false;  // Its dead, Jim; stop trying to fix it
291       if (repairfailed)
292          qualityReduction = false; // Low skill repairers shredding your shirts seem too harsh
293
294       set_color(COLOR_WHITE,COLOR_BLACK,1);
295       move(8,1);
296
297       std::string result = "";
298       result += cr.name;
299
300       if (armorDestroyed)
301       {
302          set_color(COLOR_RED,COLOR_BLACK,1);
303          result += " disposes of ";
304       }else if(repairfailed && armor->is_bloody())
305       {
306          set_color(COLOR_CYAN,COLOR_BLACK,1);
307          result += " cleans ";
308       }else if(repairfailed)
309       {
310          set_color(COLOR_WHITE,COLOR_BLACK,1);
311          result += " is working to repair ";
312       }else
313       {
314          if(!qualityReduction)
315          {
316             set_color(COLOR_GREEN,COLOR_BLACK,1);
317             result += " repairs ";
318          }else
319          {
320             armorDestroyed = !armor->decrease_quality(1);
321             if(armorDestroyed)
322             {
323                set_color(COLOR_RED,COLOR_BLACK,1);
324                result += " finds there is no hope of repairing ";
325             }else
326             {
327                set_color(COLOR_YELLOW,COLOR_BLACK,1);
328                result += " repairs what little can be fixed of ";
329             }
330          }
331       }
332
333       if (pile)
334       {
335          result += armor->aan();
336       }
337       else
338          result += cr.hisher();
339
340       if (armorDestroyed)
341          result += " ruined";
342
343       result += " " + armorname + ".";
344
345       addstr(result,gamelog);
346       gamelog.nextMessage();
347
348       if(pile)
349       {
350          if(pile->get_number()>1)
351          {
352             Item *newpile=pile->split(pile->get_number()-1);
353             pilelist->push_back(newpile);
354          }
355       }
356
357       armor->set_bloody(false);
358       if(!repairfailed)
359       {
360          armor->set_damaged(false);
361       }
362       if (armorDestroyed)
363       {
364          if (!pile) // repairer was wearing it
365          {
366             cr.strip(NULL);
367          }
368          else // scrap from stockpile
369          {
370             delete_and_remove(*pilelist, pileindex);
371          }
372       }
373
374       getkey();
375    }
376 }
377
378
379
380 /* armor manufacture */
381 void makearmor(Creature &cr,char &clearformess)
382 {
383    int at=cr.activity.arg;
384
385    int cost=armortype[at]->get_make_price();
386    int hcost=(cost>>1)+1;
387    int dif=armor_makedifficulty(*armortype[at],&cr);
388
389    if(ledger.get_funds()<hcost)
390    {
391       if(clearformess) erase();
392       else makedelimiter();
393
394       set_color(COLOR_WHITE,COLOR_BLACK,1);
395       move(8,1);
396       addstr(cr.name, gamelog);
397       addstr(" cannot afford material for clothing.", gamelog);
398       gamelog.nextMessage();
399
400       getkey();
401       return;
402    }
403    else
404    {
405       char foundcloth=0;
406
407       if(cr.squadid!=-1)
408       {
409          int sq=getsquad(cr.squadid);
410          for(int l=0;l<len(squad[sq]->loot);l++)
411             if(squad[sq]->loot[l]->is_loot()&&
412                static_cast<Loot*>(squad[sq]->loot[l])->is_cloth()) //cast -XML
413             {
414                if(squad[sq]->loot[l]->get_number()==1)
415                   delete_and_remove(squad[sq]->loot,l);
416                else squad[sq]->loot[l]->decrease_number(1);
417                foundcloth=1;
418                break;
419             }
420       }
421       if(!foundcloth) for(int l=0;l<len(location[cr.location]->loot);l++)
422          if(location[cr.location]->loot[l]->is_loot()&&
423             static_cast<Loot*>(location[cr.location]->loot[l])->is_cloth()) //cast -XML
424          {
425             if(location[cr.location]->loot[l]->get_number()==1)
426                delete_and_remove(location[cr.location]->loot,l);
427             else location[cr.location]->loot[l]->decrease_number(1);
428             foundcloth=1;
429             break;
430          }
431
432       if(!foundcloth&&ledger.get_funds()<cost)
433       {
434          if(clearformess) erase();
435          else makedelimiter();
436
437          set_color(COLOR_WHITE,COLOR_BLACK,1);
438          move(8,1);
439          addstr(cr.name, gamelog);
440          addstr(" cannot find enough cloth to reduce clothing costs.", gamelog);
441          gamelog.nextMessage();
442
443          getkey();
444       }
445       else
446       {
447          if(foundcloth) ledger.subtract_funds(hcost,EXPENSE_MANUFACTURE);
448          else ledger.subtract_funds(cost,EXPENSE_MANUFACTURE);
449
450          cr.train(SKILL_TAILORING,dif*2+1);
451
452          int quality = 1;
453          while (LCSrandom(10)<dif && quality <= armortype[at]->get_quality_levels())
454             quality++;
455
456          if(clearformess) erase();
457          else makedelimiter();
458
459          Item *it=new Armor(*armortype[at],quality);
460
461          set_color(COLOR_WHITE,COLOR_BLACK,1);
462          move(8,1);
463          addstr(cr.name, gamelog);
464          if(quality <= ((Armor*)it)->get_quality_levels() )
465          {
466             addstr(" has made a ", gamelog);
467             switch(quality)
468             {
469                case 1:addstr("first-rate", gamelog);break;
470                case 2:addstr("second-rate", gamelog);break;
471                case 3:addstr("third-rate", gamelog);break;
472                case 4:addstr("fourth-rate", gamelog);break;
473                default:addstr(quality,gamelog);addstr("th-rate", gamelog); break;
474             }
475             location[cr.location]->loot.push_back(it);
476          }
477          else
478          {
479             addstr(" wasted the materials for a", gamelog);
480          }
481          addstr(" ", gamelog);
482          addstr(armortype[at]->get_name(), gamelog);
483          addstr(".", gamelog);
484          gamelog.nextMessage();
485
486          getkey();
487       }
488    }
489 }
490
491
492
493 /* search for polls */
494 void survey(Creature *cr)
495 {
496    music.play(MUSIC_ELECTIONS);
497    static const char SURVEY_PAGE_SIZE=14;
498
499    int v,creatureskill=cr->skill_roll(SKILL_COMPUTERS);
500    int misschance=30-creatureskill,noise;
501    if(misschance<5)misschance=5;
502    if(creatureskill<1) noise=18+LCSrandom(3); // 18 to 20
503    else if(creatureskill<2) noise=16+LCSrandom(2); // 16 or 17
504    else if(creatureskill<3) noise=14+LCSrandom(2); // 14 or 15
505    else if(creatureskill<4) noise=12+LCSrandom(2); // 12 or 13
506    else if(creatureskill<5) noise=10+LCSrandom(2); // 10 or 11
507    else if(creatureskill<6) noise=8+LCSrandom(2); // 8 or 9
508    else if(creatureskill<7) noise=7;
509    else if(creatureskill<9) noise=6;
510    else if(creatureskill<11) noise=5;
511    else if(creatureskill<14) noise=4;
512    else if(creatureskill<18) noise=3;
513    else noise=2;
514
515    int survey[VIEWNUM];
516
517    int maxview=-1;
518    for(v=0;v<VIEWNUM;v++)
519    {
520       survey[v]=attitude[v];
521       if(v!=VIEW_LIBERALCRIMESQUAD&&v!=VIEW_LIBERALCRIMESQUADPOS/*&&v!=VIEW_POLITICALVIOLENCE*/)
522       {
523          if(maxview!=-1) { if(public_interest[v]>public_interest[maxview]) maxview=v; }
524          else { if(public_interest[v]>0) maxview=v; }
525       }
526
527       //MAKE SURVEY ACCURATE IF DEBUGGING
528       #ifndef SHOWMECHANICS
529       do { survey[v]+=LCSrandom(noise*2+1)-noise; } while(!LCSrandom(20));
530       #endif
531
532       if(survey[v]<0) survey[v]=0;
533       if(survey[v]>100) survey[v]=100;
534
535       #ifndef SHOWMECHANICS
536       if(LCSrandom(public_interest[v]+100)<int(misschance)) survey[v]=-1;
537       #endif
538
539       if(v==VIEW_LIBERALCRIMESQUAD&&attitude[v]==0) survey[v]=-1;
540       if(v==VIEW_LIBERALCRIMESQUADPOS&&survey[VIEW_LIBERALCRIMESQUAD]<=0) survey[v]=-1;
541    }
542
543    erase();
544
545    //TODO: Sort out the gamelog for this.
546    set_color(COLOR_WHITE,COLOR_BLACK,1);
547    move(0,0);
548    addstr("Survey of Public Opinion, According to Recent Polls");
549
550    int y=8,approval=presidentapproval();
551    move(2,0);
552    set_color(COLOR_WHITE,COLOR_BLACK,0);
553    addstr(approval/10+(LCSrandom(noise*2+1)-noise), gamelog);
554    addstr("% had a favorable opinion of ");
555    set_alignment_color(exec[EXEC_PRESIDENT],true);
556    addstr("President ");
557    addstr(execname[EXEC_PRESIDENT]);
558    set_color(COLOR_WHITE,COLOR_BLACK,0);
559    addstr(".");
560
561    //Top excitement issue
562    if(maxview!=-1)
563    {
564       move(4,0);
565       addstr("The people are most concerned about ");
566       switch(maxview)
567       {
568          case VIEW_GAY:
569             if(attitude[VIEW_GAY]>50) addstr("protecting gay rights.");
570             else addstr("protecting the traditional family.");
571             break;
572          case VIEW_DEATHPENALTY:
573             if(attitude[VIEW_DEATHPENALTY]>50) addstr("the unjust death penalty.");
574             else
575             {
576                if(law[LAW_DEATHPENALTY]==2) addstr("restoring the death penalty.");
577                else addstr("protecting the death penalty.");
578             }
579             break;
580          case VIEW_TAXES:
581             if(attitude[VIEW_TAXES]>50) addstr("the oppressive tax structure.");
582             else addstr("the excessive tax burden.");
583             break;
584          case VIEW_NUCLEARPOWER:
585             if(attitude[VIEW_NUCLEARPOWER]>50) addstr("the dangers of nuclear power.");
586             else
587             {
588                if(law[LAW_NUCLEARPOWER]==2) addstr("legalizing nuclear power.");
589                else  addstr("threats to nuclear power.");
590             }
591             break;
592          case VIEW_ANIMALRESEARCH:
593             if(attitude[VIEW_ANIMALRESEARCH]>50) addstr("brutal animal research practices.");
594             else addstr("excessive regulation of animal research.");
595             break;
596          case VIEW_POLICEBEHAVIOR:
597             if(attitude[VIEW_POLICEBEHAVIOR]>50) addstr("preventing police brutality.");
598             else addstr("expanding police powers.");
599             break;
600          case VIEW_INTELLIGENCE:
601             if(attitude[VIEW_INTELLIGENCE]>50) addstr("civil liberties and personal privacy.");
602             else addstr("national security and intelligence.");
603             break;
604          case VIEW_FREESPEECH:
605             if(attitude[VIEW_FREESPEECH]>50) addstr("protecting free speech.");
606             else addstr("ending hate speech.");
607             break;
608          case VIEW_GENETICS:
609             if(attitude[VIEW_GENETICS]>50) addstr("the dangers of genetic engineering.");
610             else addstr("excessive regulation of genetic research.");
611             break;
612          case VIEW_JUSTICES:
613             if(attitude[VIEW_JUSTICES]>50) addstr("appointing proper Liberal justices.");
614             else addstr("appointing proper Conservative justices.");
615             break;
616          case VIEW_SWEATSHOPS:
617             if(attitude[VIEW_SWEATSHOPS]>50) addstr("threats to labor rights.");
618             else addstr("corrupt union thugs.");
619             break;
620          case VIEW_POLLUTION:
621             if(attitude[VIEW_POLLUTION]>50) addstr("threats to the environment.");
622             else addstr("excessive regulation of industry.");
623             break;
624          case VIEW_CORPORATECULTURE:
625             if(attitude[VIEW_CORPORATECULTURE]>50) addstr("corporate corruption.");
626             else addstr("excessive regulation of corporations.");
627             break;
628          case VIEW_CEOSALARY:
629             if(attitude[VIEW_CEOSALARY]>50) addstr("severe income inequality.");
630             else addstr("resisting communist wage limits.");
631             break;
632          case VIEW_PRISONS:
633             if(attitude[VIEW_PRISONS]>50) addstr("stopping the prisoners' suffering.");
634             else addstr("putting the prisoners in line.");
635             break;
636          //case VIEW_POLITICALVIOLENCE:
637          //   if(attitude[VIEW_POLITICALVIOLENCE]>50) addstr("taking strong action.");
638          //   else addstr("political terrorism.");
639          //   break;
640          case VIEW_IMMIGRATION:
641             if(attitude[VIEW_IMMIGRATION]>50) addstr("immigrant rights.");
642             else
643             {
644                if(law[LAW_IMMIGRATION]>=1) addstr("uncontrolled immigration.");
645                else addstr("illegal immigration.");
646             }
647             break;
648          case VIEW_DRUGS:
649             if(attitude[VIEW_DRUGS]>50) addstr("drug rights.");
650             else addstr("drug abuse.");
651             break;
652          case VIEW_WOMEN:
653             if(attitude[VIEW_WOMEN]>50) addstr("women's equality.");
654             else addstr("women.");
655             break;
656          case VIEW_CIVILRIGHTS:
657             if(attitude[VIEW_CIVILRIGHTS]>50) addstr("civil rights.");
658             else addstr("troublemaking minorities.");
659             break;
660          case VIEW_GUNCONTROL:
661             if(attitude[VIEW_GUNCONTROL]>50) addstr("gun violence.");
662             else addstr("protecting the Second Amendment.");
663             break;
664          case VIEW_MILITARY:
665             if(attitude[VIEW_MILITARY]>50) addstr("military imperialism.");
666             else addstr("defending the nation.");
667             break;
668          case VIEW_LIBERALCRIMESQUAD:
669          case VIEW_LIBERALCRIMESQUADPOS:
670             if(attitude[VIEW_LIBERALCRIMESQUAD]<50) addstr("activist political groups.");
671             else
672             {
673                if(attitude[VIEW_LIBERALCRIMESQUADPOS]>50) addstr("the Liberal Crime Squad.");
674                else addstr("the LCS terrorists.");
675             }
676             break;
677          case VIEW_CONSERVATIVECRIMESQUAD:
678             if(attitude[VIEW_CONSERVATIVECRIMESQUAD]<50) addstr("the Conservative Crime Squad.");
679             else addstr("the CCS terrorists.");
680             break;
681          case VIEW_TORTURE:
682             if(attitude[VIEW_TORTURE]>50)addstr("ending the use of torture.");
683             else addstr("enhancing interrogations.");
684             break;
685          case VIEW_AMRADIO:
686          case VIEW_CABLENEWS:
687             if(attitude[VIEW_AMRADIO]+attitude[VIEW_CABLENEWS]>100) addstr("Conservative Media Bias.");
688             else addstr("Liberal Media Bias.");
689             break;
690       }
691    }
692    else
693    {
694       move(4,0);
695       addstr("The public is not concerned with politics right now.");
696    }
697
698    //Header for issue box
699    move(6,0);
700    addstr("Additional notable findings:");
701    move(7,0);
702    addstr("XX% Issue トトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトト Public Interest");
703
704    //Footer
705    set_color(COLOR_WHITE,COLOR_BLACK,0);
706    move(23,0);
707    addstr("Results are +/- ");
708    addstr(noise);
709    addstr(" Liberal percentage points.");
710    move(24,0);
711    addstr("Enter - Done");
712    move(24,40);
713    addprevpagestr();
714    addstr("    ");
715    addnextpagestr();
716
717    int page=0;
718    const int maxpage=VIEWNUM/SURVEY_PAGE_SIZE;
719    while(true)
720    {
721       //Keep pages within bounds
722       if(page<0) page=maxpage;
723       if(page>maxpage) page=0;
724       //Start from the top
725       y=8;
726       //Draw each line
727       for(v=page*SURVEY_PAGE_SIZE;v<(page+1)*SURVEY_PAGE_SIZE;v++,y++)
728       {
729          if(v>=VIEWNUM || (v==VIEW_CONSERVATIVECRIMESQUAD && (endgamestate>=ENDGAME_CCS_DEFEATED||newscherrybusted<2)))
730          {
731             move(y,0);
732             addstr("                                                                                ");
733             continue;
734          }
735          set_color(COLOR_WHITE,COLOR_BLACK,0);
736          move(y,4);
737          addstr("........................................................");
738          if(noise>=7||survey[v]==-1) addstr("Unknown  ");
739          else if(noise>=4)
740          {
741             if(public_interest[v]>50) addstr("High     ");
742             else addstr("Low      ");
743          }
744          else
745          {
746             if(public_interest[v]>100) addstr("Very High");
747             else if(public_interest[v]>50) addstr("High     ");
748             else if(public_interest[v]>10) addstr("Moderate ");
749             else if(public_interest[v]) addstr("Low      ");
750             else addstr("None     ");
751          }
752
753          if(survey[v]==-1)set_color(COLOR_BLACK,COLOR_BLACK,1);
754          else if(survey[v]<10)set_color(COLOR_RED,COLOR_BLACK,1);
755          else if(survey[v]<30)set_color(COLOR_MAGENTA,COLOR_BLACK,1);
756          else if(survey[v]<50)set_color(COLOR_YELLOW,COLOR_BLACK,1);
757          else if(survey[v]<70)set_color(COLOR_BLUE,COLOR_BLACK,1);
758          else if(survey[v]<90)set_color(COLOR_CYAN,COLOR_BLACK,1);
759          else set_color(COLOR_GREEN,COLOR_BLACK,1);
760
761          move(y,0);
762          if(survey[v]==-1) addstr("??");
763          else
764          {
765             if(survey[v]<10)addchar('0');
766             addstr(survey[v]);
767          }
768          addstr("% ");
769
770          switch(v)
771          {
772          case VIEW_GAY: addstr("were in favor of equal rights for homosexuals"); break;
773          case VIEW_DEATHPENALTY: addstr("opposed the death penalty"); break;
774          case VIEW_TAXES: addstr("were against cutting taxes"); break;
775          case VIEW_NUCLEARPOWER: addstr("were terrified of nuclear power"); break;
776          case VIEW_ANIMALRESEARCH: addstr("deplored animal research"); break;
777          case VIEW_POLICEBEHAVIOR: addstr("were critical of the police"); break;
778          case VIEW_TORTURE: addstr("wanted stronger measures to prevent torture"); break;
779          case VIEW_INTELLIGENCE: addstr("thought the intelligence community invades privacy"); break;
780          case VIEW_FREESPEECH: addstr("believed in unfettered free speech"); break;
781          case VIEW_GENETICS: addstr("abhorred genetically altered food products"); break;
782          case VIEW_JUSTICES: addstr("were for the appointment of Liberal justices"); break;
783          case VIEW_SWEATSHOPS: addstr("would boycott companies that used sweatshops"); break;
784          case VIEW_POLLUTION: addstr("thought industry should lower pollution"); break;
785          case VIEW_CORPORATECULTURE: addstr("were disgusted by corporate malfeasance"); break;
786          case VIEW_CEOSALARY: addstr("believed that CEO salaries are too great"); break;
787          case VIEW_WOMEN: addstr("favored doing more for gender equality"); break;
788          case VIEW_CIVILRIGHTS: addstr("felt more work was needed for racial equality"); break;
789          case VIEW_GUNCONTROL: addstr("are concerned about gun violence"); break;
790          case VIEW_DRUGS: if(law[LAW_DRUGS]>=1) addstr("supported keeping marijuana legal");
791                           else addstr("believed in legalizing marijuana"); break;
792          case VIEW_IMMIGRATION: if(law[LAW_IMMIGRATION]>=1) addstr("condemned unnecessary immigration regulations");
793                                 else addstr("wanted amnesty for illegal immigrants"); break;
794          case VIEW_MILITARY: addstr("opposed increasing military spending"); break;
795          case VIEW_LIBERALCRIMESQUAD: addstr("respected the power of the Liberal Crime Squad"); break;
796          case VIEW_LIBERALCRIMESQUADPOS: addstr("of these held the Liberal Crime Squad in high regard"); break;
797          case VIEW_CONSERVATIVECRIMESQUAD: addstr("held the Conservative Crime Squad in contempt"); break;
798          case VIEW_PRISONS: addstr("wanted to end prisoner abuse and torture"); break;
799          case VIEW_AMRADIO: addstr("do not like AM radio"); break;
800          case VIEW_CABLENEWS: addstr("have a negative opinion of cable news programs"); break;
801          //case VIEW_POLITICALVIOLENCE: addstr("thought political violence was justified");break;
802          }
803       }
804
805       while(true)
806       {
807          int c=getkey();
808
809          if(c=='x'||c==ENTER||c==ESC||c==SPACEBAR) return;
810          else if(c==interface_pgup||c==KEY_UP||c==KEY_LEFT) { page--; break; }
811          else if(c==interface_pgdn||c==KEY_DOWN||c==KEY_RIGHT) { page++; break; }
812       }
813    }
814
815
816 }
817
818 // Police accost your liberal!
819 void attemptarrest(Creature & liberal,const char* string,int clearformess)
820 {
821    if(string)
822    {
823       if(clearformess) erase();
824       else makedelimiter();
825
826       set_color(COLOR_WHITE,COLOR_BLACK,1);
827       move(8,1);
828       addstr(liberal.name, gamelog);
829       addstr(" is accosted by police while ", gamelog);
830       addstr(string, gamelog);
831       addstr("!", gamelog);
832       gamelog.nextMessage();
833
834       getkey();
835    }
836
837    // Chase sequence! Wee!
838    makechasers(-1,5);
839
840    if(!sitestory)
841    {
842       newsstoryst *ns=new newsstoryst;
843       ns->type=NEWSSTORY_WANTEDARREST; // TODO: Make a more generic catch-all arrest story
844       ns->loc=-1;
845       newsstory.push_back(ns);
846       sitestory=ns;
847    }
848
849    chaseseq.clean();
850    chaseseq.location=location[liberal.location]->parent;
851    footchase(liberal);
852 }
853
854 // While galavanting in public, your liberals may be ambushed by police
855 int checkforarrest(Creature & liberal,const char* string,int clearformess)
856 {
857    bool arrest=false;
858
859    if(!liberal.animalgloss && liberal.is_naked() && LCSrandom(2))
860    {
861       criminalize(liberal,LAWFLAG_DISTURBANCE);
862
863       newsstoryst *ns=new newsstoryst;
864       ns->type=NEWSSTORY_NUDITYARREST;
865       ns->loc=-1;
866       newsstory.push_back(ns);
867       sitestory=ns;
868
869       arrest=true;
870    }
871    else if(liberal.heat>liberal.get_skill(SKILL_STREETSENSE)*10)
872    {
873       if(!LCSrandom(50))
874       {
875          newsstoryst *ns=new newsstoryst;
876          ns->type=NEWSSTORY_WANTEDARREST;
877          ns->loc=-1;
878          newsstory.push_back(ns);
879          sitestory=ns;
880
881          arrest=true;
882       }
883    }
884
885    if(arrest) attemptarrest(liberal,string,clearformess);
886    return arrest;
887 }
888
889
890
891 /* misc activation related things */
892 // *JDSRETURN*
893 void funds_and_trouble(char &clearformess)
894 {  //ACTIVITIES FOR INDIVIDUALS
895    vector<Creature *> trouble,hack,bury,solicit,tshirts,art,music,graffiti,brownies,prostitutes,teachers,students;
896
897    for(int p=0;p<len(pool);p++)
898    {
899       if(!pool[p]->alive) continue;
900       if(pool[p]->location==-1)
901       {
902          pool[p]->activity.type=ACTIVITY_NONE;
903          continue;
904       }
905       switch(pool[p]->activity.type)
906       {
907       case ACTIVITY_TEACH_FIGHTING:
908       case ACTIVITY_TEACH_POLITICS:
909       case ACTIVITY_TEACH_COVERT:
910          teachers.push_back(pool[p]);
911          break;
912       case ACTIVITY_CCFRAUD:
913       case ACTIVITY_DOS_RACKET:
914       case ACTIVITY_DOS_ATTACKS:
915       case ACTIVITY_HACKING:
916          hack.push_back(pool[p]);
917          break;
918       case ACTIVITY_GRAFFITI:
919          graffiti.push_back(pool[p]);
920          break;
921       case ACTIVITY_TROUBLE:
922          trouble.push_back(pool[p]);
923          break;
924       case ACTIVITY_COMMUNITYSERVICE:
925          addjuice(*pool[p],1,10);
926          change_public_opinion(VIEW_LIBERALCRIMESQUADPOS,1,0,80);
927          break;
928       case ACTIVITY_SELL_TSHIRTS:
929          tshirts.push_back(pool[p]);
930          break;
931       case ACTIVITY_SELL_ART:
932          art.push_back(pool[p]);
933          break;
934       case ACTIVITY_SELL_MUSIC:
935          music.push_back(pool[p]);
936          break;
937       case ACTIVITY_DONATIONS:
938          solicit.push_back(pool[p]);
939          break;
940       case ACTIVITY_SELL_DRUGS:
941          brownies.push_back(pool[p]);
942          break;
943       case ACTIVITY_PROSTITUTION:
944          prostitutes.push_back(pool[p]);
945          break;
946       case ACTIVITY_BURY:
947          bury.push_back(pool[p]);
948          pool[p]->activity.type=ACTIVITY_NONE;
949          break;
950       case ACTIVITY_CLINIC:
951          hospitalize(find_clinic(*pool[p]),*pool[p]);
952          pool[p]->activity.type=ACTIVITY_NONE;
953          break;
954       case ACTIVITY_STUDY_DEBATING:
955       case ACTIVITY_STUDY_MARTIAL_ARTS:
956       case ACTIVITY_STUDY_DRIVING:
957       case ACTIVITY_STUDY_PSYCHOLOGY:
958       case ACTIVITY_STUDY_FIRST_AID:
959       case ACTIVITY_STUDY_LAW:
960       case ACTIVITY_STUDY_DISGUISE:
961       case ACTIVITY_STUDY_SCIENCE:
962       case ACTIVITY_STUDY_BUSINESS:
963       //case ACTIVITY_STUDY_COOKING:
964       case ACTIVITY_STUDY_GYMNASTICS:
965       case ACTIVITY_STUDY_ART:
966       case ACTIVITY_STUDY_TEACHING:
967       case ACTIVITY_STUDY_MUSIC:
968       case ACTIVITY_STUDY_WRITING:
969       case ACTIVITY_STUDY_LOCKSMITHING:
970          students.push_back(pool[p]);
971          break;
972       case ACTIVITY_SLEEPER_JOINLCS:
973          if(!location[find_homeless_shelter(*pool[p])]->siege.siege)
974          {
975             pool[p]->activity.type=ACTIVITY_NONE;
976             pool[p]->flag &= ~CREATUREFLAG_SLEEPER;
977             pool[p]->location = pool[p]->base = find_homeless_shelter(*pool[p]);
978          }
979          //Letters to the editor
980       case ACTIVITY_WRITE_LETTERS:
981          if(pool[p]->skill_check(SKILL_WRITING,DIFFICULTY_EASY))
982             background_liberal_influence[randomissue()]+=5;
983          pool[p]->train(SKILL_WRITING,LCSrandom(5)+1);
984          break;
985       //Guardian Essays
986       //Basically letters to the editor, but thrice as potent, and can backfire
987       case ACTIVITY_WRITE_GUARDIAN:
988          if(pool[p]->skill_check(SKILL_WRITING,DIFFICULTY_EASY))
989             background_liberal_influence[randomissue()]+=15;
990          else
991             background_liberal_influence[randomissue()]-=15;
992          pool[p]->train(SKILL_WRITING,LCSrandom(5)+1);
993          break;
994       }
995    }
996
997         doActivitySolicitDonations(solicit, clearformess);
998         doActivitySellTshirts(tshirts, clearformess);
999         doActivitySellArt(art, clearformess);
1000         doActivitySellMusic(music, clearformess);
1001         doActivitySellBrownies(brownies, clearformess);
1002         doActivityHacking(hack, clearformess);
1003         doActivityGraffiti(graffiti, clearformess);
1004         doActivityProstitution(prostitutes, clearformess);
1005         doActivityLearn(students, clearformess);
1006         doActivityTrouble(trouble, clearformess);
1007         doActivityTeach(teachers, clearformess);
1008         doActivityBury(bury, clearformess);
1009 }
1010
1011 void doActivitySolicitDonations(vector<Creature *> &solicit, char &clearformess)
1012 {  //SOLICITORS
1013    long total_income=0;
1014    for(int s=0;s<len(solicit);s++)
1015    {
1016       if(!checkforarrest(*solicit[s],"soliciting donations",clearformess))
1017       {
1018          int income=solicit[s]->skill_roll(SKILL_PERSUASION) *
1019                     solicit[s]->get_armor().get_professionalism()+1;
1020
1021          // Country's alignment dramatically affects effectiveness
1022          // The more conservative the country, the more effective
1023          if(publicmood(-1)>90) income/=2;
1024          if(publicmood(-1)>65) income/=2;
1025          if(publicmood(-1)>35) income/=2;
1026          if(publicmood(-1)>10) income/=2;
1027
1028          solicit[s]->income=income;
1029
1030          total_income += income;
1031
1032          solicit[s]->train(SKILL_PERSUASION,max(5-solicit[s]->get_skill(SKILL_PERSUASION),2));
1033       }
1034    }
1035    ledger.add_funds(total_income,INCOME_DONATIONS);
1036 }
1037
1038 void doActivitySellTshirts(vector<Creature *> &tshirts, char &clearformess)
1039 {
1040    for(int s=0;s<len(tshirts);s++)
1041    {
1042       if(!checkforarrest(*tshirts[s],"selling shirts",clearformess))
1043       {
1044          long money = (tshirts[s]->skill_roll(SKILL_TAILORING) +
1045                        tshirts[s]->skill_roll(SKILL_BUSINESS))/2;
1046
1047          // Country's alignment affects effectiveness
1048          // In a Liberal country, there are many competing vendors
1049          if(publicmood(-1)>65) money/=2;
1050          if(publicmood(-1)>35) money/=2;
1051
1052          //If you're selling epic shirts enough they'll have some political impact
1053          if(tshirts[s]->skill_check(SKILL_TAILORING,DIFFICULTY_FORMIDABLE))
1054             background_liberal_influence[randomissue()]+=5;
1055
1056          tshirts[s]->income=money;
1057          ledger.add_funds(money,INCOME_TSHIRTS);
1058
1059          tshirts[s]->train(SKILL_TAILORING,max(7-tshirts[s]->get_skill(SKILL_TAILORING),2));
1060          tshirts[s]->train(SKILL_BUSINESS,max(7-tshirts[s]->get_skill(SKILL_BUSINESS),2));
1061       }
1062    }
1063 }
1064
1065 void doActivitySellArt(vector<Creature *> &art, char &clearformess)
1066 {
1067         for(int s=0;s<len(art);s++)
1068    {
1069       if(!checkforarrest(*art[s],"sketching portraits",clearformess))
1070       {
1071          long money = art[s]->skill_roll(SKILL_ART);
1072
1073          // Country's alignment affects effectiveness
1074          // In a Liberal country, there are many competing vendors
1075          if(publicmood(-1)>65) money/=2;
1076          if(publicmood(-1)>35) money/=2;
1077
1078          //Epic Liberal art may have positive political effect
1079          if(art[s]->skill_check(SKILL_ART,DIFFICULTY_FORMIDABLE))
1080             background_liberal_influence[randomissue()]+=5;
1081
1082          art[s]->income=money;
1083          ledger.add_funds(money,INCOME_SKETCHES);
1084
1085          art[s]->train(SKILL_ART,max(7-art[s]->get_skill(SKILL_ART),4));
1086       }
1087    }
1088 }
1089
1090 void doActivitySellMusic(vector<Creature *> &music, char &clearformess)
1091 {
1092    for(int s=0;s<len(music);s++)
1093    {
1094       if(!checkforarrest(*music[s],"playing music",clearformess))
1095       {
1096          long money = music[s]->skill_roll(SKILL_MUSIC)/2;
1097          bool has_instrument = music[s]->get_weapon().is_instrument();
1098
1099          if(has_instrument) money*=4;
1100
1101          // Country's alignment affects effectiveness
1102          // In a Liberal country, there are many competing vendors
1103          if(publicmood(-1)>65) money/=2;
1104          if(publicmood(-1)>35) money/=2;
1105
1106          //Epic Liberal protest songs
1107          if(music[s]->skill_check(SKILL_MUSIC,DIFFICULTY_FORMIDABLE))
1108             background_liberal_influence[randomissue()]+=has_instrument ? 10 : 5;
1109
1110          ledger.add_funds(money,INCOME_BUSKING);
1111          music[s]->income=money;
1112
1113          if(has_instrument) music[s]->train(SKILL_MUSIC,max(7-music[s]->get_skill(SKILL_MUSIC),4));
1114          else music[s]->train(SKILL_MUSIC,max(5-music[s]->get_skill(SKILL_MUSIC),2));
1115       }
1116    }
1117 }
1118
1119 void doActivitySellBrownies(vector<Creature *> &brownies, char &clearformess)
1120 {
1121    for(int s=0;s<len(brownies);s++)
1122    {
1123       //Check for police search
1124       int dodgelawroll=LCSrandom(1+30*law[LAW_DRUGS]+3);
1125
1126       //Saved by street sense?
1127       if(dodgelawroll==0)
1128          dodgelawroll=brownies[s]->skill_check(SKILL_STREETSENSE,DIFFICULTY_AVERAGE);
1129
1130       if(dodgelawroll==0 && law[LAW_DRUGS]<=0) // Busted!
1131       {
1132          newsstoryst *ns=new newsstoryst;
1133          ns->type=NEWSSTORY_DRUGARREST;
1134          ns->loc=-1;
1135          newsstory.push_back(ns);
1136          sitestory=ns;
1137
1138          criminalize(*brownies[s],LAWFLAG_BROWNIES);
1139          attemptarrest(*brownies[s],"selling brownies",clearformess);
1140       }
1141
1142       long money = brownies[s]->skill_roll(SKILL_PERSUASION) +
1143                    brownies[s]->skill_roll(SKILL_BUSINESS) +
1144                    brownies[s]->skill_roll(SKILL_STREETSENSE);
1145
1146       // more money when more illegal
1147       if(law[LAW_DRUGS]==-2) money*=4;
1148       if(law[LAW_DRUGS]==-1) money*=2;
1149       if(law[LAW_DRUGS]==1) money/=4;
1150       if(law[LAW_DRUGS]==2) money/=8;
1151
1152       brownies[s]->income=money;
1153       ledger.add_funds(money,INCOME_BROWNIES);
1154
1155       // Make the sale
1156       brownies[s]->train(SKILL_PERSUASION,max(4-brownies[s]->get_skill(SKILL_PERSUASION),1));
1157       // Know the streets
1158       brownies[s]->train(SKILL_STREETSENSE,max(7-brownies[s]->get_skill(SKILL_STREETSENSE),3));
1159       // Manage your money
1160       brownies[s]->train(SKILL_BUSINESS,max(10-brownies[s]->get_skill(SKILL_BUSINESS),3));
1161    }
1162
1163 }
1164
1165 void doActivityHacking(vector<Creature *> &hack, char &clearformess)
1166 {
1167    if(len(hack))
1168    {
1169       vector<Creature *> cc,web,ddos,truehack;
1170
1171       //First, do accounting to figure out who's doing what
1172       for(int h=0;h<len(hack);h++)
1173       {
1174          switch(hack[h]->activity.type)
1175          {
1176          case ACTIVITY_CCFRAUD:
1177             hack[h]->train(SKILL_COMPUTERS,2);
1178             cc.push_back(hack[h]);
1179             break;
1180          case ACTIVITY_DOS_ATTACKS:
1181             hack[h]->train(SKILL_COMPUTERS,2);
1182             web.push_back(hack[h]);
1183             break;
1184          case ACTIVITY_DOS_RACKET:
1185             hack[h]->train(SKILL_COMPUTERS,4);
1186             ddos.push_back(hack[h]);
1187             break;
1188          case ACTIVITY_HACKING:
1189             hack[h]->train(SKILL_COMPUTERS,4);
1190             truehack.push_back(hack[h]);
1191             break;
1192          }
1193       }
1194
1195       char msg[200] = {0};
1196
1197       //MAJOR HACKING
1198       int hack_skill=0;
1199       for(int h=0;h<len(truehack);h++)
1200          hack_skill=MAX(hack_skill,truehack[h]->skill_roll(SKILL_COMPUTERS));
1201
1202       if(DIFFICULTY_HEROIC<=hack_skill+len(truehack)-1)
1203       {
1204          if(len(truehack)>1) strcpy(msg,"あなたのハッカー集団は");
1205          else { strcpy(msg,truehack[0]->name); strcat(msg,"は"); }
1206
1207          int trackdif=0,juiceval=0;
1208          int short crime=0;
1209
1210          switch(LCSrandom(11))
1211          {
1212             case 0:
1213             {
1214                strcat(msg,"企業のサーバからファイルを盗み取った");
1215
1216                Item *it=new Loot(*loottype[getloottype("LOOT_CORPFILES")]);
1217                location[hack[0]->location]->loot.push_back(it);
1218
1219                trackdif=DIFFICULTY_SUPERHEROIC;
1220                crime=LAWFLAG_INFORMATION;
1221                juiceval=10;
1222                break;
1223             }
1224             case 1: // *JDS* Penetrated government networks; don't get any loot, but do scare the info community
1225                strcat(msg,"CIAネットワークに侵入して恐怖を与えた");
1226
1227                trackdif=DIFFICULTY_IMPOSSIBLE;
1228                crime=LAWFLAG_INFORMATION;
1229                juiceval=25;
1230                change_public_opinion(VIEW_INTELLIGENCE,10,0,75);
1231                break;
1232             case 2:
1233                strcat(msg,"遺伝子調査会社のネットワークを妨害した");
1234
1235                trackdif=DIFFICULTY_SUPERHEROIC;
1236                crime=LAWFLAG_INFORMATION;
1237                juiceval=10;
1238                change_public_opinion(VIEW_GENETICS,2,0,75);
1239                break;
1240             case 3:
1241             {
1242                strcat(msg,"マスメディアの電子メールを傍受した");
1243
1244                Item *it;
1245                if(LCSrandom(2))it=new Loot(*loottype[getloottype("LOOT_CABLENEWSFILES")]);
1246                else it=new Loot(*loottype[getloottype("LOOT_AMRADIOFILES")]);
1247                location[hack[0]->location]->loot.push_back(it);
1248
1249                trackdif=DIFFICULTY_SUPERHEROIC;
1250                crime=LAWFLAG_INFORMATION;
1251                juiceval=10;
1252                break;
1253             }
1254             case 4:
1255                strcat(msg,"軍用ネットワークに侵入しLCSのスローガンを書き残した");
1256
1257                trackdif=DIFFICULTY_IMPOSSIBLE;
1258                crime=LAWFLAG_INFORMATION;
1259                juiceval=10;
1260                change_public_opinion(VIEW_LIBERALCRIMESQUAD,5,0,75);
1261                break;
1262             case 5:
1263             {
1264                strcat(msg,"問題のある研究の情報を明らかにした");
1265
1266                Item *it=new Loot(*loottype[getloottype("LOOT_RESEARCHFILES")]);
1267                location[hack[0]->location]->loot.push_back(it);
1268
1269                trackdif=DIFFICULTY_SUPERHEROIC;
1270                crime=LAWFLAG_INFORMATION;
1271                juiceval=10;
1272                break;
1273             }
1274             case 6:
1275             {
1276                strcat(msg,"司法の汚職の証拠を発見した");
1277
1278                Item *it=new Loot(*loottype[getloottype("LOOT_JUDGEFILES")]);
1279                location[hack[0]->location]->loot.push_back(it);
1280
1281                trackdif=DIFFICULTY_SUPERHEROIC;
1282                crime=LAWFLAG_INFORMATION;
1283                juiceval=10;
1284                break;
1285             }
1286             case 7:
1287             {
1288                strcat(msg,"保守的家族のフォーラムを攻撃した");
1289
1290                trackdif=DIFFICULTY_SUPERHEROIC;
1291                crime=LAWFLAG_INFORMATION;
1292                juiceval=10;
1293                change_public_opinion(VIEW_GAY,2,0,75);
1294                change_public_opinion(VIEW_WOMEN,2,0,75);
1295                break;
1296             }
1297             case 8:
1298             {
1299                strcat(msg,"人種差別的な警官が暴行する動画を拡散した");
1300
1301                trackdif=DIFFICULTY_SUPERHEROIC;
1302                crime=LAWFLAG_INFORMATION;
1303                juiceval=10;
1304                change_public_opinion(VIEW_POLICEBEHAVIOR,2,0,75);
1305                change_public_opinion(VIEW_CIVILRIGHTS,2,0,75);
1306                break;
1307             }
1308             case 9:
1309             {
1310                strcat(msg,"CEOの税金逃れを暴露する電子メールを送った");
1311                //Scambaiting, except you're baiting a CEO
1312
1313                trackdif=DIFFICULTY_SUPERHEROIC;
1314                crime=LAWFLAG_INFORMATION;
1315                juiceval=10;
1316                change_public_opinion(VIEW_CEOSALARY,2,0,75);
1317                change_public_opinion(VIEW_TAXES,2,0,75);
1318                break;
1319             }
1320             case 10:
1321             {
1322                strcat(msg,"移民帰化局の政治的偏りを暴露した");
1323
1324                trackdif=DIFFICULTY_SUPERHEROIC;
1325                crime=LAWFLAG_INFORMATION;
1326                juiceval=10;
1327                change_public_opinion(VIEW_IMMIGRATION,2,0,75);
1328                change_public_opinion(VIEW_FREESPEECH,2,0,75);
1329                break;
1330             }
1331
1332          }
1333
1334          if(trackdif>hack_skill + LCSrandom(5)-2)
1335             for(int h=0;h<len(truehack);h++)
1336                criminalize(*hack[h],crime);
1337
1338          // Award juice to the hacking team for a job well done
1339          for(int h=0;h<len(truehack);h++)
1340             addjuice(*truehack[h],juiceval,200);
1341       }
1342       else if(DIFFICULTY_FORMIDABLE<=hack_skill+len(truehack)-1)
1343       {
1344          int issue=LCSrandom(VIEWNUM-5),crime=LAWFLAG_INFORMATION;
1345
1346          // Maybe do a switch on issue here to specify which website it was, but I don't feel like
1347          // doing that right now
1348
1349          if(len(truehack)>1) strcpy(msg,"あなたのハッカー集団は");
1350          else { strcpy(msg,truehack[0]->name); strcat(msg,"は"); }
1351
1352          switch(LCSrandom(5))
1353          {
1354          case 0: strcat(msg,"企業のウェブサイト"); break;
1355          case 1: strcat(msg,"保守派のフォーラム");break;
1356          case 2: strcat(msg,"保守派のブログ"); break;
1357          case 3: strcat(msg,"ニュースサイト"); break;
1358          case 4: strcat(msg,"政府のウェブサイト"); break;
1359          }
1360          strcat(msg,"を");
1361          switch(LCSrandom(4))
1362          {
1363          case 0: strcat(msg,"改ざんした");crime=LAWFLAG_INFORMATION; break;
1364          case 1: strcat(msg,"停止させた");crime=LAWFLAG_COMMERCE; break;
1365          case 2: strcat(msg,"脅迫した");crime=LAWFLAG_SPEECH; break;
1366          case 3: strcat(msg,"ハックした");crime=LAWFLAG_INFORMATION; break;
1367          }
1368          strcat(msg,"。");
1369
1370          change_public_opinion(issue,1);
1371
1372          if(DIFFICULTY_HEROIC>hack_skill+LCSrandom(5)-2)
1373             for(int h=0;h<len(truehack);h++)
1374                criminalize(*truehack[h],crime);
1375
1376          // Award juice to the hacking team for a job well done
1377          for(int h=0;h<len(truehack);h++)
1378             addjuice(*truehack[h],5,100);
1379       }
1380
1381       if(msg[0])
1382       {
1383          if(clearformess) erase();
1384          else makedelimiter();
1385
1386          set_color(COLOR_WHITE,COLOR_BLACK,1);
1387          move(8,1);
1388
1389          addstr(msg, gamelog);
1390          gamelog.nextMessage();
1391          msg[0]=0;
1392
1393          getkey();
1394       }
1395
1396       //CREDIT CARD FRAUD
1397       for(int h=0;h<len(cc);h++)
1398       {
1399          hack_skill = cc[h]->skill_roll(SKILL_COMPUTERS);
1400          int difficulty = DIFFICULTY_CHALLENGING;
1401
1402          if(difficulty<=hack_skill)
1403          {
1404             // *JDS* You get between $1 and $100, plus an extra $1-50 every
1405             // time you pass a check against your hacking skill, where chance of
1406             // failure is one over the adjusted hackers' skill divided by four. Once
1407             // a check fails, no more money is gained. This check will be made
1408             // up to 20 times, at which point the loop breaks. The skill check
1409             // here doesn't take into account funding.
1410             int fundgain=LCSrandom(101);
1411             while(difficulty<hack_skill)
1412             {
1413                fundgain+=LCSrandom(51);
1414                difficulty+=2;
1415             }
1416             ledger.add_funds(fundgain,INCOME_CCFRAUD);
1417
1418             cc[h]->income = fundgain / len(cc);
1419
1420             if(fundgain/25>LCSrandom(hack_skill+1))
1421                criminalize(*cc[h],LAWFLAG_CCFRAUD);
1422          }
1423
1424          if(msg[0])
1425          {
1426             if(clearformess) erase();
1427             else makedelimiter();
1428
1429             set_color(COLOR_WHITE,COLOR_BLACK,1);
1430             move(8,1);
1431
1432             addstr(msg, gamelog); //TODO: Log this?
1433             gamelog.nextMessage();
1434             msg[0]=0;
1435
1436             getkey();
1437          }
1438       }
1439    }
1440
1441 }
1442
1443 void doActivityGraffiti(vector<Creature *> &graffiti, char &clearformess)
1444 {
1445         int s;
1446
1447    if(len(graffiti))
1448    {
1449       for(s=0;s<len(graffiti);s++)
1450       {
1451          if(!graffiti[s]->get_weapon().can_graffiti())
1452          {
1453
1454             if(clearformess) erase();
1455             else makedelimiter();
1456
1457             set_color(COLOR_WHITE,COLOR_BLACK,1);
1458             move(8,1);
1459             addstr(graffiti[s]->name, gamelog);
1460
1461             //Check base inventory for a spraycan
1462             bool foundone=false;
1463             for(int i=0;i<len(location[graffiti[s]->base]->loot);i++)
1464             {
1465                if(location[graffiti[s]->base]->loot[i]->is_weapon())
1466                {
1467                   Weapon *w = static_cast<Weapon*>(location[graffiti[s]->base]->loot[i]); //cast -XML
1468                   if(w->can_graffiti())
1469                   {
1470                      addstr("は", gamelog);
1471                      addstr(w->get_name(), gamelog);
1472                      addstr("を", gamelog);
1473                      addstr(location[graffiti[s]->base]->getname()); //TODO: Explicitly log it, or will the game log it?
1474                      addstr("で現地調達した。", gamelog);
1475
1476                      getkey();
1477
1478                      graffiti[s]->give_weapon(*w,&(location[graffiti[s]->base]->loot));
1479
1480                      if(location[graffiti[s]->base]->loot[i]->empty())
1481                         delete_and_remove(location[graffiti[s]->base]->loot,i);
1482                      foundone = true;
1483                      break;
1484                   }
1485                }
1486             }
1487
1488             if(!foundone && ledger.get_funds()>=20)
1489             {
1490                ledger.subtract_funds(20,EXPENSE_SHOPPING);
1491                addstr("は落書きのためにスプレー缶を買った。", gamelog);
1492
1493                getkey();
1494
1495                Weapon spray(*weapontype[getweapontype("WEAPON_SPRAYCAN")]);
1496                graffiti[s]->give_weapon(spray,&location[graffiti[s]->base]->loot);
1497             }
1498             else if (!foundone)
1499             {
1500                addstr("が落書きするにはスプレー缶が必要だ。", gamelog);
1501                graffiti[s]->activity.type=ACTIVITY_NONE;
1502
1503                getkey();
1504             }
1505             gamelog.nextMessage(); //Next message now so that we don't have to type it for every case.
1506          }
1507
1508          int issue=VIEW_LIBERALCRIMESQUAD,power=1;
1509
1510          if(clearformess) erase();
1511          else makedelimiter();
1512
1513          if(!LCSrandom(10) &&
1514             !(graffiti[s]->skill_check(SKILL_STREETSENSE,DIFFICULTY_AVERAGE)))
1515          {
1516             if(clearformess) erase();
1517             else makedelimiter();
1518
1519             set_color(COLOR_WHITE,COLOR_BLACK,1);
1520             move(8,1);
1521
1522             addstr(graffiti[s]->name, gamelog);
1523             addstr("は", gamelog);
1524             criminalize(*graffiti[s],LAWFLAG_VANDALISM);
1525             graffiti[s]->train(SKILL_STREETSENSE,20);
1526
1527             if(graffiti[s]->activity.arg!=-1)
1528             {
1529                addstr("壁絵を描いている", gamelog);
1530                graffiti[s]->activity.arg=-1;
1531             }
1532             else addstr("LCSのマークをスプレーしている", gamelog);
1533             addstr("ところを警官に見られた!", gamelog);
1534             gamelog.nextMessage();
1535
1536             newsstoryst *ns=new newsstoryst;
1537             ns->type=NEWSSTORY_GRAFFITIARREST;
1538             ns->loc=-1;
1539             ns->positive=0;
1540             newsstory.push_back(ns);
1541             sitestory=ns;
1542
1543             getkey();
1544
1545             attemptarrest(*graffiti[s],NULL,clearformess);
1546          }
1547          else if(graffiti[s]->activity.arg!=-1)
1548          {
1549             power=0;
1550             if(!LCSrandom(3))
1551             {
1552                issue=graffiti[s]->activity.arg;
1553                power=graffiti[s]->skill_roll(SKILL_ART)/3;
1554
1555                set_color(COLOR_WHITE,COLOR_BLACK,1);
1556                move(8,1);
1557                addstr(graffiti[s]->name, gamelog);
1558                addstr("は", gamelog);
1559                if(power>3)addstr("すばらしい", gamelog);
1560                addstr(getview(issue,false), gamelog);
1561                addstr("の壁絵を完成させた。", gamelog);
1562                gamelog.nextMessage();
1563
1564                graffiti[s]->activity.arg=-1;
1565                addjuice(*graffiti[s],power,power*20);
1566                change_public_opinion(issue,power);
1567                graffiti[s]->train(SKILL_ART,MAX(10-graffiti[s]->get_skill(SKILL_ART)/2,1));
1568
1569                getkey();
1570             }
1571             else
1572             {
1573                power=0;
1574                set_color(COLOR_WHITE,COLOR_BLACK,1);
1575                move(8,1);
1576                addstr(graffiti[s]->name, gamelog);
1577                addstr("は一晩をかけて巨大な壁絵を描いた。", gamelog);
1578                gamelog.nextMessage();
1579                graffiti[s]->train(SKILL_ART,MAX(10-graffiti[s]->get_skill(SKILL_ART)/2,1));
1580
1581                getkey();
1582             }
1583          }
1584          else if(!LCSrandom(MAX(30-graffiti[s]->get_skill(SKILL_ART)*2,5)))
1585          {
1586             issue=randomissue();
1587             set_color(COLOR_WHITE,COLOR_BLACK,1);
1588             move(8,1);
1589             addstr(graffiti[s]->name, gamelog);
1590             addstr("は", gamelog);
1591             addstr(getview(issue,false), gamelog);
1592             addstr("の巨大な壁絵を描き始めた。", gamelog);
1593             gamelog.nextMessage();
1594             graffiti[s]->activity.arg=issue;
1595             power=0;
1596             graffiti[s]->train(SKILL_ART,MAX(10-graffiti[s]->get_skill(SKILL_ART)/2,1));
1597
1598             getkey();
1599          }
1600
1601          graffiti[s]->train(SKILL_ART,MAX(4-graffiti[s]->get_skill(SKILL_ART),0));
1602          if(issue==VIEW_LIBERALCRIMESQUAD)
1603          {
1604             change_public_opinion(VIEW_LIBERALCRIMESQUAD,LCSrandom(2),0,65);
1605             change_public_opinion(VIEW_LIBERALCRIMESQUADPOS,!LCSrandom(8),0,65);
1606             public_interest[issue]+=power;
1607          }
1608          else
1609          {
1610             change_public_opinion(VIEW_LIBERALCRIMESQUAD,LCSrandom(2)+1,0,85);
1611             change_public_opinion(VIEW_LIBERALCRIMESQUADPOS,!LCSrandom(4),0,65);
1612             public_interest[issue]+=power;
1613             background_liberal_influence[issue]+=power;
1614          }
1615       }
1616    }
1617 }
1618
1619 void doActivityProstitution(vector<Creature *> &prostitutes, char &clearformess)
1620 {
1621    for(int p=len(prostitutes)-1;p>=0;p--)
1622    {
1623       // Business once every three days or so
1624       if(LCSrandom(3)) continue;
1625
1626       //char num[20];
1627
1628       long fundgain=0;
1629       char caught=0;
1630
1631       // Skill determies how much money you get
1632       int performance = prostitutes[p]->skill_roll(SKILL_SEDUCTION);
1633       if(performance>DIFFICULTY_HEROIC)
1634          fundgain=LCSrandom(201)+200;
1635       else
1636          fundgain=LCSrandom(10*performance)+10*performance;
1637
1638       // Street sense check or deal with slimy people that reduce dignity and juice
1639       if(!LCSrandom(3) &&
1640          !(prostitutes[p]->skill_check(SKILL_STREETSENSE,DIFFICULTY_AVERAGE)))
1641       {
1642          addjuice(*prostitutes[p],-!LCSrandom(3), -20);
1643       }
1644
1645       // Gain seduction and street sense
1646       prostitutes[p]->train(SKILL_SEDUCTION,MAX(10-prostitutes[p]->get_skill(SKILL_SEDUCTION),0));
1647       prostitutes[p]->train(SKILL_STREETSENSE,MAX(10-prostitutes[p]->get_skill(SKILL_STREETSENSE),0));
1648
1649
1650       if(!LCSrandom(50)) // Police sting?
1651       {
1652          if(!(prostitutes[p]->skill_check(SKILL_STREETSENSE,DIFFICULTY_AVERAGE))) // Street sense to avoid
1653          {
1654             if(clearformess) erase();
1655             else makedelimiter();
1656
1657             set_color(COLOR_WHITE,COLOR_BLACK,1);
1658             move(8,1);
1659             addstr(prostitutes[p]->name, gamelog);
1660             addstr("は売春の容疑で逮捕された。", gamelog);
1661             gamelog.nextMessage();
1662
1663             addjuice(*prostitutes[p],-7,-30);
1664
1665             getkey();
1666
1667             caught=1;
1668
1669             removesquadinfo(*prostitutes[p]);
1670             prostitutes[p]->carid=-1;
1671             prostitutes[p]->location=find_police_station(*prostitutes[p]);
1672             prostitutes[p]->drop_weapons_and_clips(NULL);
1673             prostitutes[p]->activity.type=ACTIVITY_NONE;
1674             criminalize(*prostitutes[p],LAWFLAG_PROSTITUTION);
1675          }
1676          else
1677          {
1678             if(clearformess) erase();
1679             else makedelimiter();
1680
1681             set_color(COLOR_WHITE,COLOR_BLACK,1);
1682             move(8,1);
1683             addstr(prostitutes[p]->name, gamelog);
1684             addstr("は売春であやうく逮捕されるところだった。", gamelog);
1685             gamelog.nextMessage();
1686
1687             addjuice(*prostitutes[p],5,0);
1688
1689             getkey();
1690          }
1691       }
1692
1693       if(!caught)
1694       {
1695          prostitutes[p]->train(SKILL_STREETSENSE,MAX(5-prostitutes[p]->get_skill(SKILL_STREETSENSE),0));
1696          ledger.add_funds(fundgain,INCOME_PROSTITUTION);
1697          prostitutes[p]->income = fundgain;
1698       }
1699    }
1700 }
1701
1702 void doActivityLearn(vector<Creature *> &students, char &clearformess)
1703 {
1704    for(int s=len(students)-1;s>=0;s--)
1705    {
1706            if(ledger.get_funds()<60) break;
1707            ledger.subtract_funds(60,EXPENSE_TRAINING);
1708            int skill[2] = {-1, -1};
1709            int effectiveness[2] = {20, 20};
1710            switch(students[s]->activity.type)
1711            {
1712                   case ACTIVITY_STUDY_DEBATING:
1713                           skill[0] = SKILL_PERSUASION;
1714                           break;
1715                   case ACTIVITY_STUDY_MARTIAL_ARTS:
1716                           skill[0] = SKILL_HANDTOHAND;
1717                           break;
1718                   case ACTIVITY_STUDY_DRIVING:
1719                           skill[0] = SKILL_DRIVING;
1720                           break;
1721                   case ACTIVITY_STUDY_PSYCHOLOGY:
1722            skill[0] = SKILL_PSYCHOLOGY;
1723                           break;
1724                   case ACTIVITY_STUDY_FIRST_AID:
1725            skill[0] = SKILL_FIRSTAID;
1726                           break;
1727                   case ACTIVITY_STUDY_LAW:
1728                 skill[0] = SKILL_LAW;
1729                           break;
1730                   case ACTIVITY_STUDY_DISGUISE:
1731            skill[0] = SKILL_DISGUISE;
1732                           break;
1733                   case ACTIVITY_STUDY_SCIENCE:
1734            skill[0] = SKILL_SCIENCE;
1735                           break;
1736                   case ACTIVITY_STUDY_BUSINESS:
1737            skill[0] = SKILL_BUSINESS;
1738                           break;
1739         //case ACTIVITY_STUDY_COOKING:
1740         //   skill[0] = SKILL_COOKING;
1741         //   break;
1742                   case ACTIVITY_STUDY_GYMNASTICS:
1743            skill[0] = SKILL_DODGE;
1744                           break;
1745         case ACTIVITY_STUDY_LOCKSMITHING:
1746            skill[0] = SKILL_SECURITY;
1747            break;
1748                   case ACTIVITY_STUDY_MUSIC:
1749            skill[0] = SKILL_MUSIC;
1750                           break;
1751                   case ACTIVITY_STUDY_ART:
1752            skill[0] = SKILL_ART;
1753                           break;
1754                   case ACTIVITY_STUDY_TEACHING:
1755            skill[0] = SKILL_TEACHING;
1756                           break;
1757                   case ACTIVITY_STUDY_WRITING:
1758            skill[0] = SKILL_WRITING;
1759                           break;
1760            }
1761            bool worthcontinuing=false;
1762            for(int i=0; i<2; i++)
1763                    if(skill[i]!=-1)
1764                    {  // rapid decrease in effectiveness as your skill gets higher.
1765             effectiveness[i] /= (students[s]->get_skill(skill[i])+1);
1766                            if(effectiveness[i]<1)
1767                effectiveness[i]=1;
1768                       students[s]->train(skill[i],effectiveness[i]);
1769             if(students[s]->get_skill(skill[i]) < students[s]->skill_cap(skill[i],true))
1770                                    worthcontinuing=true;
1771                    }
1772            if (!worthcontinuing)
1773            {
1774                    students[s]->activity.type=ACTIVITY_NONE;
1775          set_color(COLOR_WHITE,COLOR_BLACK,1);
1776          move(8,1);
1777          addstr(students[s]->name, gamelog);
1778          addstr(" has learned as much as ", gamelog);
1779          addstr(students[s]->heshe(), gamelog);
1780          addstr(" can.", gamelog);
1781          gamelog.nextMessage();
1782
1783          getkey();
1784            }
1785    }
1786 }
1787
1788 void doActivityTrouble(vector<Creature *> &trouble, char &clearformess)
1789 {
1790    if(len(trouble))
1791    {
1792       long juiceval=0;
1793       char done=0;
1794       short crime=0;
1795
1796       if(clearformess) erase();
1797       else makedelimiter();
1798
1799       set_color(COLOR_WHITE,COLOR_BLACK,1);
1800       move(8,1);
1801       if(len(trouble)>1) addstr("攪乱グループは",gamelog);
1802       else { addstr(trouble[0]->name,gamelog); addstr("は",gamelog); }
1803
1804       int power=0;
1805       for(int t=0;t<len(trouble);t++)
1806          power+=trouble[t]->skill_roll(SKILL_PERSUASION)+
1807                 trouble[t]->skill_roll(SKILL_STREETSENSE);
1808
1809       int mod=1;
1810       if(LCSrandom(10)<power) mod++;
1811       if(LCSrandom(20)<power) mod++;
1812       if(LCSrandom(40)<power) mod++;
1813       if(LCSrandom(60)<power) mod++;
1814       if(LCSrandom(80)<power) mod++;
1815       if(LCSrandom(100)<power) mod++;
1816
1817       do
1818       {
1819          switch(LCSrandom(10))
1820          {
1821             case 0:
1822                addstr("住宅街を走り回り、毛皮のコートにペンキをぶちまけた!", gamelog);
1823                juiceval=2;
1824                crime=LAWFLAG_ASSAULT;
1825                change_public_opinion(VIEW_LIBERALCRIMESQUAD,mod);
1826                change_public_opinion(VIEW_LIBERALCRIMESQUADPOS,mod>>1,0,70);
1827                public_interest[VIEW_ANIMALRESEARCH]+=mod;
1828                background_liberal_influence[VIEW_ANIMALRESEARCH]+=mod;
1829                done=1;
1830                break;
1831             case 1:
1832             {
1833                if(law[LAW_GAY]<2)
1834                {
1835                   addstr("教会で伝統的な結婚式を台無しにした!", gamelog);
1836                   change_public_opinion(VIEW_LIBERALCRIMESQUAD,mod);
1837                   change_public_opinion(VIEW_LIBERALCRIMESQUADPOS,mod,0,70);
1838                   public_interest[VIEW_GAY]+=mod;
1839                   background_liberal_influence[VIEW_GAY]+=mod;
1840                   juiceval=2;
1841                   crime=LAWFLAG_DISTURBANCE;
1842                   done=1;
1843                }
1844                break;
1845             }
1846             case 2:
1847             {
1848                if(law[LAW_ABORTION]<2)
1849                {
1850                   addstr("恐ろしい死を遂げた中絶医の写真を街中に張り出した!", gamelog);
1851                   change_public_opinion(VIEW_LIBERALCRIMESQUAD,mod);
1852                   change_public_opinion(VIEW_LIBERALCRIMESQUADPOS,mod,0,70);
1853                   public_interest[VIEW_WOMEN]+=mod;
1854                   background_liberal_influence[VIEW_WOMEN]+=mod;
1855                   juiceval=1;
1856                   done=1;
1857                }
1858                break;
1859             }
1860             case 3:
1861             {
1862                if(law[LAW_POLICEBEHAVIOR]<2)
1863                {
1864                   addstr("街へ向かい、警官による暴力を再現した!", gamelog);
1865                   change_public_opinion(VIEW_LIBERALCRIMESQUAD,mod);
1866                   change_public_opinion(VIEW_LIBERALCRIMESQUADPOS,mod,0,70);
1867                   public_interest[VIEW_POLICEBEHAVIOR]+=mod;
1868                   background_liberal_influence[VIEW_POLICEBEHAVIOR]+=mod;
1869                   juiceval=2;
1870                   crime=LAWFLAG_DISTURBANCE;
1871                   done=1;
1872                }
1873                break;
1874             }
1875             case 4:
1876             {
1877                if(law[LAW_NUCLEARPOWER]<2)
1878                {
1879                   if(len(trouble)>1)addstr("仮装して放射能ミュータントを演じた!", gamelog);
1880                   else addstr("仮装して放射能ミュータントを演じた!", gamelog);
1881                   change_public_opinion(VIEW_LIBERALCRIMESQUAD,mod);
1882                   change_public_opinion(VIEW_LIBERALCRIMESQUADPOS,mod,0,70);
1883                   public_interest[VIEW_NUCLEARPOWER]+=mod;
1884                   background_liberal_influence[VIEW_NUCLEARPOWER]+=mod;
1885                   juiceval=2;
1886                   crime=LAWFLAG_DISTURBANCE;
1887                   done=1;
1888                }
1889                break;
1890             }
1891             case 5:
1892             {
1893                if(law[LAW_POLLUTION]<2)
1894                {
1895                   addstr("会社員に偽物の汚染水を掛けた!", gamelog);
1896                   change_public_opinion(VIEW_LIBERALCRIMESQUAD,mod);
1897                   change_public_opinion(VIEW_LIBERALCRIMESQUADPOS,mod,0,70);
1898                   public_interest[VIEW_POLLUTION]+=mod;
1899                   background_liberal_influence[VIEW_POLLUTION]+=mod;
1900                   juiceval=2;
1901                   crime=LAWFLAG_DISTURBANCE;
1902                   done=1;
1903                }
1904                break;
1905             }
1906             case 6:
1907             {
1908                if(law[LAW_DEATHPENALTY]<2)
1909                {
1910                   addstr("死刑執行を絵で説明したビラをばら撒いた!", gamelog);
1911                   change_public_opinion(VIEW_LIBERALCRIMESQUAD,mod);
1912                   change_public_opinion(VIEW_LIBERALCRIMESQUADPOS,mod,0,70);
1913                   public_interest[VIEW_DEATHPENALTY]+=mod;
1914                   background_liberal_influence[VIEW_DEATHPENALTY]+=mod;
1915                   juiceval=1;
1916                   done=1;
1917                }
1918                break;
1919             }
1920             case 7:
1921             {
1922                addstr("CIAによる拷問を絵で説明したビラをばら撒いた!", gamelog);
1923                change_public_opinion(VIEW_LIBERALCRIMESQUAD,mod);
1924                change_public_opinion(VIEW_LIBERALCRIMESQUADPOS,mod,0,70);
1925                public_interest[VIEW_TORTURE]+=mod;
1926                background_liberal_influence[VIEW_TORTURE]+=mod;
1927                juiceval=1;
1928                done=1;
1929                break;
1930             }
1931             case 8:
1932             {
1933                addstr("企業のマークを焼き払い、資本主義を弾劾した!", gamelog);
1934                change_public_opinion(VIEW_LIBERALCRIMESQUAD,mod);
1935                change_public_opinion(VIEW_LIBERALCRIMESQUADPOS,mod,0,70);
1936                public_interest[VIEW_CORPORATECULTURE]+=mod;
1937                background_liberal_influence[VIEW_CORPORATECULTURE]+=mod;
1938                if(law[LAW_CORPORATE]==-2)
1939                {               // In extreme corporate culture cases this should give a flag burning charge! -- kviiri
1940                   juiceval=2;  // Done -- SlatersQuest
1941                   crime=LAWFLAG_BURNFLAG;
1942                }
1943                else juiceval=1;
1944                done=1;
1945                break;
1946             }
1947             case 9:
1948             {
1949                addstr("商店街の中心に搾取工場の模型を置いた!", gamelog);
1950                change_public_opinion(VIEW_LIBERALCRIMESQUAD,mod);
1951                change_public_opinion(VIEW_LIBERALCRIMESQUADPOS,mod,0,70);
1952                public_interest[VIEW_SWEATSHOPS]+=mod;
1953                background_liberal_influence[VIEW_SWEATSHOPS]+=mod;
1954                juiceval+=1;
1955                done=1;
1956                break;
1957             }
1958          }
1959       } while(!done);
1960
1961       gamelog.nextMessage(); //Do this now so that it doesn't have to be done in every case up there.
1962
1963       getkey();
1964
1965       if(crime!=0)
1966       {
1967          for(int t=0;t<len(trouble);t++)
1968          {
1969             if(!LCSrandom(30) &&
1970                !(trouble[t]->skill_check(SKILL_STREETSENSE,DIFFICULTY_AVERAGE)))
1971             {
1972                if(clearformess) erase();
1973                else makedelimiter();
1974
1975                if(!LCSrandom(4))
1976                {
1977                   newsstoryst *ns=new newsstoryst;
1978                   ns->type=NEWSSTORY_WANTEDARREST; // should probably create a NEWSSTORY_TROUBLEARREST and implement it fully
1979                   ns->loc=-1;                      // but this will have to do for now
1980                   ns->positive=0;
1981                   newsstory.push_back(ns);
1982                   sitestory=ns;
1983                   attemptarrest(*trouble[t],"causing trouble",clearformess);
1984                }
1985                else
1986                {
1987                   set_color(COLOR_WHITE,COLOR_BLACK,1);
1988                   move(8,1);
1989                   addstr(trouble[t]->name, gamelog);
1990                   addstr(" is cornered by a mob of angry rednecks.", gamelog);
1991                   gamelog.nextMessage();
1992
1993                   getkey();
1994
1995                   bool wonfight = false;
1996
1997                   if(trouble[t]->get_weapon().is_threatening())
1998                   {
1999                      if(clearformess) erase();
2000                      else makedelimiter();
2001
2002                      set_color(COLOR_WHITE,COLOR_BLACK,1);
2003                      move(8,1);
2004                      addstr(trouble[t]->name, gamelog);
2005                      addstr(" brandishes the ", gamelog);
2006                      addstr(trouble[t]->get_weapon().get_name(), gamelog);
2007                      addstr("!", gamelog);
2008                      gamelog.nextMessage();
2009
2010                      getkey();
2011
2012                      if(clearformess) erase();
2013                      else makedelimiter();
2014
2015                      set_color(COLOR_WHITE,COLOR_BLACK,1);
2016                      move(8,1);
2017                      addstr("The mob scatters!", gamelog);
2018                      gamelog.nextMessage();
2019
2020                      getkey();
2021
2022                      addjuice(*trouble[t],5,20);
2023
2024                      wonfight = true;
2025                   }
2026                   else
2027                   {
2028                      for(int count=0;count<=LCSrandom(5)+2;count++)
2029                      {
2030                         if(clearformess) erase();
2031                         else makedelimiter();
2032                         if(trouble[t]->skill_roll(SKILL_HANDTOHAND)>LCSrandom(6)+count)
2033                         {
2034                            set_color(COLOR_CYAN,COLOR_BLACK,1);
2035                            move(8,1);
2036                            addstr(trouble[t]->name, gamelog);
2037                            switch(LCSrandom(8))
2038                            {
2039                            case 0:addstr(" breaks the arm of the nearest person!", gamelog);break;
2040                            case 1:addstr(" knees a guy in the balls!", gamelog);break;
2041                            case 2:addstr(" knocks one out with a fist to the face!", gamelog);break;
2042                            case 3:addstr(" bites some hick's ear off!", gamelog);break;
2043                            case 4:addstr(" smashes one of them in the jaw!", gamelog);break;
2044                            case 5:addstr(" shakes off a grab from behind!", gamelog);break;
2045                            case 6:addstr(" yells the slogan!", gamelog);break;
2046                            case 7:addstr(" knocks two of their heads together!", gamelog);break;
2047                            }
2048
2049                            gamelog.nextMessage();
2050
2051                            getkey();
2052
2053                            wonfight=true;
2054                         }
2055                         else
2056                         {
2057                            set_color(COLOR_YELLOW,COLOR_BLACK,1);
2058                            move(8,1);
2059                            addstr(trouble[t]->name, gamelog);
2060                            switch(LCSrandom(8))
2061                            {
2062                            case 0:addstr(" is held down and kicked by three guys!", gamelog);break;
2063                            case 1:addstr(" gets pummeled!", gamelog);break;
2064                            case 2:addstr(" gets hit by a sharp rock!", gamelog);break;
2065                            case 3:addstr(" is thrown against the sidewalk!", gamelog);break;
2066                            case 4:addstr(" is bashed in the face with a shovel!", gamelog);break;
2067                            case 5:addstr(" is forced into a headlock!", gamelog);break;
2068                            case 6:addstr(" crumples under a flurry of blows!", gamelog);break;
2069                            case 7:addstr(" is hit in the chest with a pipe!", gamelog);break;
2070                            }
2071
2072                            gamelog.nextMessage();
2073
2074                            getkey();
2075
2076                            count++; // fight goes faster when you're losing
2077
2078                            wonfight=false;
2079                         }
2080                      }
2081
2082                      if(wonfight)
2083                      {
2084                         if(clearformess) erase();
2085                         else makedelimiter();
2086                         set_color(COLOR_GREEN,COLOR_BLACK,1);
2087                         move(8,1);
2088                         addstr(trouble[t]->name, gamelog);
2089                         addstr(" beat the ", gamelog);
2090                         if(law[LAW_FREESPEECH]==-2)
2091                            addstr("[tar]", gamelog);
2092                         else addstr("shit", gamelog);
2093                         addstr(" out of everyone who got close!", gamelog);
2094
2095                         gamelog.nextMessage();
2096
2097                         getkey();
2098
2099                         addjuice(*trouble[t],30,300);
2100                         if(trouble[t]->blood>70)trouble[t]->blood=70;
2101                      }
2102                   }
2103
2104                   if(!wonfight)
2105                   {
2106                      if(clearformess) erase();
2107                      else makedelimiter();
2108                      set_color(COLOR_RED,COLOR_BLACK,1);
2109                      move(8,1);
2110                      addstr(trouble[t]->name, gamelog);
2111                      addstr(" is severely beaten before the mob is broken up.", gamelog);
2112                      gamelog.nextMessage();
2113
2114                      trouble[t]->activity.type=ACTIVITY_CLINIC;
2115
2116                      getkey();
2117
2118                      addjuice(*trouble[t],-10,-50);
2119                      if(trouble[t]->blood>10)trouble[t]->blood=10;
2120
2121                      if(!LCSrandom(5))
2122                      {
2123                         if(clearformess) erase();
2124                         else makedelimiter();
2125                         switch(LCSrandom(10))
2126                         {
2127                            case 0:
2128                               if(trouble[t]->special[SPECIALWOUND_LOWERSPINE]==1)
2129                               {
2130                                  move(8,1);
2131                                  addstr(trouble[t]->name, gamelog);
2132                                  addstr("'s lower spine has been broken!", gamelog);
2133                                  gamelog.nextMessage();
2134                                  trouble[t]->special[SPECIALWOUND_LOWERSPINE]=0;
2135
2136                                  getkey();
2137                               }
2138                               break;
2139                            case 1:
2140                               if(trouble[t]->special[SPECIALWOUND_UPPERSPINE]==1)
2141                               {
2142                                  move(8,1);
2143                                  addstr(trouble[t]->name, gamelog);
2144                                  addstr("'s upper spine has been broken!", gamelog);
2145                                  gamelog.nextMessage();
2146                                  trouble[t]->special[SPECIALWOUND_UPPERSPINE]=0;
2147
2148                                  getkey();
2149                               }
2150                               break;
2151                            case 2:
2152                               if(trouble[t]->special[SPECIALWOUND_NECK]==1)
2153                               {
2154                                  move(8,1);
2155                                  addstr(trouble[t]->name, gamelog);
2156                                  addstr("'s neck has been broken!", gamelog);
2157                                  gamelog.nextMessage();
2158                                  trouble[t]->special[SPECIALWOUND_NECK]=0;
2159
2160                                  getkey();
2161                               }
2162                               break;
2163                            case 3:
2164                               if(trouble[t]->special[SPECIALWOUND_TEETH]>0)
2165                               {
2166                                  move(8,1);
2167                                  addstr(trouble[t]->name);
2168                                  if(trouble[t]->special[SPECIALWOUND_TEETH]>1)addstr("'s teeth have been smashed out on the curb.", gamelog);
2169                                  else addstr("'s tooth has been pulled out with pliers!", gamelog);
2170                                  gamelog.nextMessage();
2171                                  trouble[t]->special[SPECIALWOUND_TEETH]=0;
2172
2173                                  getkey();
2174                               }
2175                               break;
2176                            default:
2177                            {
2178                               if(trouble[t]->special[SPECIALWOUND_RIBS]>0)
2179                               {
2180                                  int ribminus=LCSrandom(RIBNUM)+1;
2181                                  if(ribminus>trouble[t]->special[SPECIALWOUND_RIBS])ribminus=trouble[t]->special[SPECIALWOUND_RIBS];
2182
2183                                  move(8,1);
2184                                  if(ribminus>1)
2185                                  {
2186                                     if(ribminus==trouble[t]->special[SPECIALWOUND_RIBS])
2187                                        addstr("All ", gamelog);
2188                                     addstr(ribminus, gamelog);
2189                                     addstr(" of ", gamelog);
2190                                     addstr(trouble[t]->name, gamelog);
2191                                     addstr("'s ribs are ", gamelog);
2192                                  }
2193                                  else if(trouble[t]->special[SPECIALWOUND_RIBS]>1)
2194                                  {
2195                                     addstr("One of ", gamelog);
2196                                     addstr(trouble[t]->name, gamelog);
2197                                     addstr("'s rib is ", gamelog);
2198                                  }
2199                                  else
2200                                  {
2201                                     addstr(trouble[t]->name);
2202                                     addstr("'s last unbroken rib is ", gamelog);
2203                                  }
2204
2205                                  addstr("broken!", gamelog);
2206                                  gamelog.nextMessage();
2207
2208                                  getkey();
2209
2210                                  trouble[t]->special[SPECIALWOUND_RIBS]-=ribminus;
2211                               }
2212                               break;
2213                            }
2214                         }
2215                      }
2216                   }
2217                }
2218             }
2219          }
2220       }
2221
2222       for(int h=0;h<len(trouble);h++)
2223          addjuice(*trouble[h],juiceval,40);
2224    }
2225 }
2226
2227 void doActivityTeach(vector<Creature *> &teachers, char &clearformess)
2228 {
2229    for(int t=0;t<len(teachers);t++)
2230    {
2231       int skillarray[14];
2232       int cost=0, students=0;
2233       //Build a list of skills to train and determine the cost for running
2234       //a class depending on what the teacher is teaching
2235       switch(teachers[t]->activity.type)
2236       {
2237       case ACTIVITY_TEACH_POLITICS:
2238          cost=2;
2239          skillarray[0]=SKILL_LAW;
2240          skillarray[1]=SKILL_PERSUASION;
2241          skillarray[2]=SKILL_WRITING;
2242          skillarray[3]=SKILL_RELIGION;
2243          skillarray[4]=SKILL_BUSINESS;
2244          skillarray[5]=SKILL_SCIENCE;
2245          skillarray[6]=SKILL_STREETSENSE;
2246          skillarray[7]=SKILL_MUSIC;
2247          skillarray[8]=SKILL_ART;
2248          skillarray[9]=-1;
2249          break;
2250       case ACTIVITY_TEACH_COVERT:
2251          cost=6;
2252          skillarray[0]=SKILL_SECURITY;
2253          skillarray[1]=SKILL_COMPUTERS;
2254          skillarray[2]=SKILL_DISGUISE;
2255          skillarray[3]=SKILL_TAILORING;
2256          skillarray[4]=SKILL_STEALTH;
2257          skillarray[5]=SKILL_SEDUCTION;
2258          skillarray[6]=SKILL_PSYCHOLOGY;
2259          skillarray[7]=SKILL_DRIVING;
2260          skillarray[8]=-1;
2261          break;
2262       case ACTIVITY_TEACH_FIGHTING:
2263          cost=10;
2264          skillarray[0]=SKILL_KNIFE;
2265          skillarray[1]=SKILL_SWORD;
2266          skillarray[2]=SKILL_CLUB;
2267          skillarray[3]=SKILL_PISTOL;
2268          skillarray[4]=SKILL_RIFLE;
2269          skillarray[5]=SKILL_SHOTGUN;
2270          skillarray[6]=SKILL_HEAVYWEAPONS;
2271          skillarray[7]=SKILL_AXE;
2272          skillarray[8]=SKILL_SMG;
2273          skillarray[9]=SKILL_THROWING;
2274          skillarray[10]=SKILL_HANDTOHAND;
2275          skillarray[11]=SKILL_DODGE;
2276          skillarray[12]=SKILL_FIRSTAID;
2277          skillarray[13]=-1;
2278          break;
2279       }
2280
2281       //Count potential students for this teacher to get an idea of efficiency
2282       for(int p=0;p<len(pool);p++)
2283       {
2284          //If they're at the location
2285          if(pool[p]->location==teachers[t]->location &&
2286             pool[p]->align==ALIGN_LIBERAL &&
2287             pool[p]->alive)
2288          {
2289             //Step through the array of skills to train
2290             for(int i=0;i<13;i++)           //Any reason why we aren't using a while(true) loop or something even more dynamic? --kviiri
2291             {
2292                //If no more skills to train, stop
2293                if(skillarray[i]==-1) break;
2294                //Otherwise, if the student has less skill than the teacher, train the student
2295                //proportional to the difference in skill between teacher and student times the
2296                //teacher's ability at teaching
2297                if(pool[p]->get_skill(skillarray[i])<teachers[t]->get_skill(skillarray[i])-1&&
2298                   pool[p]->get_skill(skillarray[i])<teachers[t]->get_skill(SKILL_TEACHING)+2&&
2299                   pool[p]->get_skill(skillarray[i])<pool[p]->skill_cap(skillarray[i],true))
2300                {
2301                   students++;
2302                }
2303             }
2304          }
2305       }
2306
2307       //Check funds.
2308       if(ledger.get_funds()<min(students,10)*cost)
2309          continue; //Can't afford to teach them. Continue with next teacher.
2310
2311       //Walk through and train people
2312       for(int p=0;p<len(pool);p++)
2313       {
2314          //If they're at the location
2315          if(pool[p]->location==teachers[t]->location &&
2316             pool[p]->align==ALIGN_LIBERAL &&
2317             pool[p]->alive)
2318          {
2319             //Step through the array of skills to train
2320             for(int i=0;i<13;i++)
2321             {
2322                //If no more skills to train, stop
2323                if(skillarray[i]==-1)break;
2324                //Otherwise, if the student has less skill than the teacher, train the student
2325                //proportional to the difference in skill between teacher and student times the
2326                //teacher's ability at teaching
2327                if(pool[p]->get_skill(skillarray[i])<teachers[t]->get_skill(skillarray[i])-1&&
2328                   pool[p]->get_skill(skillarray[i])<teachers[t]->get_skill(SKILL_TEACHING)+2&&
2329                   pool[p]->get_skill(skillarray[i])<pool[p]->skill_cap(skillarray[i],true))
2330                {
2331                   // Teach based on teacher's skill in the topic plus skill in teaching, minus
2332                   // student's skill in the topic
2333                   int teach=teachers[t]->get_skill(skillarray[i])+
2334                             teachers[t]->get_skill(SKILL_TEACHING)-
2335                             pool[p]->get_skill(skillarray[i]);
2336                   //at ten students, cost no longer goes up, but effectiveness goes down.
2337                   if (students > 10)
2338                   {
2339                      //teach = (teach * 10) / students; //teach at 50% speed with twice as many students.
2340                      teach = ((teach * 30 / students) + teach)/4; //62.5% speed with twice as many students.
2341                   }
2342                   if(teach<1)
2343                      teach=1;
2344                   // Cap at 10 points per day
2345                   if(teach>10)
2346                      teach=10;
2347
2348                   pool[p]->train(skillarray[i],teach);
2349
2350                   /*if(students<10)
2351                   {
2352                      students++;
2353                      ledger.subtract_funds(cost,EXPENSE_TRAINING);
2354                      if(students==10)cost=0;
2355                   }*/
2356                }
2357             }
2358          }
2359       }
2360
2361       ledger.subtract_funds( cost*min(students, 10), EXPENSE_TRAINING );
2362       teachers[t]->train(SKILL_TEACHING,min(students, 10));
2363    }
2364 }
2365
2366 void doActivityBury(vector<Creature *> &bury, char &clearformess)
2367 {
2368    if(len(bury))
2369    {
2370       for(int p=len(pool)-1;p>=0;p--)
2371       {
2372          if(pool[p]->alive) continue;
2373
2374          bool arrest_attempted = false;
2375
2376          //MAKE BASE LOOT
2377          makeloot(*pool[p],location[bury[0]->base]->loot);
2378
2379          for(int b=0;b<len(bury);b++)
2380          {
2381             if(!arrest_attempted && !(bury[b]->skill_check(SKILL_STREETSENSE,DIFFICULTY_EASY)))
2382             {
2383                arrest_attempted = true; // Only attempt one burial arrest per body
2384
2385                newsstoryst *ns=new newsstoryst;
2386                ns->type=NEWSSTORY_BURIALARREST;
2387                ns->loc=-1;
2388                newsstory.push_back(ns);
2389                sitestory=ns;
2390
2391                criminalize(*bury[b],LAWFLAG_BURIAL);
2392                char str[100] = "burying ";
2393                strcat(str, pool[p]->name);
2394                strcat(str, "'s body");
2395                attemptarrest(*bury[b],str,clearformess);
2396
2397                // If a liberal is spotted they should not do more burials.
2398                bury.erase(bury.begin() + b--);
2399
2400                break;
2401             }
2402          }
2403
2404          //BURY (even if interrupted)
2405          delete_and_remove(pool,p);
2406
2407          if(!len(bury)) break; //Stop burials if none are left doing them.
2408       }
2409    }
2410
2411 }
2412
2413 /* steal a car */
2414 bool stealcar(Creature &cr,char &clearformess)
2415 {
2416    music.play(MUSIC_CARTHEFT);
2417    clearformess=1;
2418
2419    short cartype;
2420
2421    if(carselect(cr,cartype))
2422    {
2423       int diff=vehicletype[cartype]->steal_difficultytofind()*2;
2424
2425       Vehicle *v=NULL;
2426
2427       int old=cartype;
2428
2429       cr.train(SKILL_STREETSENSE,5);
2430
2431       //THEFT SEQUENCE
2432       erase();
2433       set_color(COLOR_WHITE,COLOR_BLACK,1);
2434       move(0,0);
2435       addstr("Adventures in Liberal Car Theft", gamelog);
2436       gamelog.nextMessage();
2437       printcreatureinfo(&cr);
2438       makedelimiter();
2439
2440       set_color(COLOR_WHITE,COLOR_BLACK,0);
2441       move(10,0);
2442       addstr(cr.name, gamelog);
2443       addstr(" looks around for an accessible vehicle...", gamelog);
2444
2445       getkey();
2446
2447       //ROUGH DAY
2448       if(!cr.skill_check(SKILL_STREETSENSE,diff))
2449          do cartype=LCSrandom(len(vehicletype));
2450          while(cartype==old||LCSrandom(10)<vehicletype[cartype]->steal_difficultytofind());
2451
2452       string carname=(v=new Vehicle(*vehicletype[cartype]))->fullname();
2453
2454       move(11,0);
2455       addstr(cr.name, gamelog);
2456       if(old!=cartype)
2457       {
2458          addstr(" was unable to find a ", gamelog);
2459          addstr(vehicletype[old]->longname(), gamelog);
2460          addstr(" but did find a ", gamelog);
2461       }
2462       else addstr(" found a ", gamelog);
2463       addstr(v->longname(), gamelog);
2464       addstr(".", gamelog);
2465       gamelog.nextMessage();
2466
2467       getkey();
2468
2469       //APPROACH?
2470       erase();
2471       set_color(COLOR_WHITE,COLOR_BLACK,1);
2472       move(0,0);
2473       addstr("Adventures in Liberal Car Theft");
2474       printcreatureinfo(&cr);
2475       makedelimiter();
2476
2477       set_color(COLOR_WHITE,COLOR_BLACK,0);
2478       move(10,0);
2479       addstr(cr.name, gamelog);
2480       addstr(" looks from a distance at an empty ", gamelog);
2481       addstr(carname, gamelog);
2482       addstr(".", gamelog);
2483
2484       gamelog.nextMessage();
2485
2486       move(12,0);
2487       addstr("A - Approach the driver's side door.");
2488       move(13,0);
2489       addstr("Enter - Call it a day.");
2490
2491       while(true)
2492       {
2493          int c=getkey();
2494          if(c=='a')break;
2495          if(c=='x'||c==ENTER||c==ESC||c==SPACEBAR){delete v;return false;}
2496       }
2497
2498       //SECURITY?
2499       bool alarmon=false,sensealarm=LCSrandom(100)<v->sensealarmchance(),
2500            touchalarm=LCSrandom(100)<v->touchalarmchance();
2501       char windowdamage=0;
2502
2503       for(bool entered=false;!entered;)
2504       {
2505          erase();
2506          set_color(COLOR_WHITE,COLOR_BLACK,1);
2507          move(0,0);
2508          addstr("Adventures in Liberal Car Theft");
2509          printcreatureinfo(&cr);
2510          makedelimiter();
2511
2512          if(alarmon)
2513          {
2514             set_color(COLOR_WHITE,COLOR_BLACK,1);
2515             move(10,0);
2516             if(sensealarm)addstr("THE VIPER");
2517             else addstr(carname);
2518             addstr(":   ");
2519             set_color(COLOR_RED,COLOR_BLACK,1);
2520             if(sensealarm)addstr("STAND AWAY FROM THE VEHICLE!   <BEEP!!> <BEEP!!>");
2521             else addstr("<BEEP!!> <BEEP!!> <BEEP!!> <BEEP!!>");
2522          }
2523          else if(sensealarm)
2524          {
2525             set_color(COLOR_WHITE,COLOR_BLACK,1);
2526             move(10,0);
2527             addstr("THE VIPER:   ");
2528             set_color(COLOR_RED,COLOR_BLACK,1);
2529             addstr("THIS IS THE VIPER!   STAND AWAY!", gamelog);
2530             gamelog.nextMessage();
2531          }
2532          else
2533          {
2534             set_color(COLOR_WHITE,COLOR_BLACK,0);
2535             move(10,0);
2536             addstr(cr.name, gamelog);
2537             addstr(" stands by the ", gamelog);
2538             addstr(carname, gamelog);
2539             addstr(".", gamelog);
2540             gamelog.nextMessage();
2541          }
2542
2543          move(12,0);
2544          set_color(COLOR_WHITE,COLOR_BLACK,0);
2545          addstr("A - Pick the lock.");
2546          set_color(COLOR_WHITE,COLOR_BLACK,0);
2547          move(13,0);
2548          addstr("B - Break the window.");
2549          move(14,0);
2550          if(!sensealarm)addstr("Enter - Call it a day.");
2551          else
2552          {
2553             if(!alarmon)
2554             {
2555                addstr("Enter - The Viper?   ");
2556                addstr(cr.name);
2557                addstr(" is deterred.");
2558             }
2559             else
2560             {
2561                addstr("Enter - Yes, the Viper has deterred ");
2562                addstr(cr.name);
2563                addstr(".");
2564             }
2565          }
2566
2567          char method=-1;
2568          while(method==-1)
2569          {
2570             int c=getkey();
2571             if(c=='a')method=0;
2572             if(c=='b')method=1;
2573             if(c=='x'||c==ENTER||c==ESC||c==SPACEBAR){delete v;return false;} /* try again tomorrow */
2574          }
2575
2576          //PICK LOCK
2577          if(method==0)
2578          {
2579             if(cr.skill_check(SKILL_SECURITY,DIFFICULTY_AVERAGE))
2580             {
2581                switch (fieldskillrate)
2582                {
2583                   case FIELDSKILLRATE_FAST:
2584                      cr.train(SKILL_SECURITY, 25);break;
2585                   case FIELDSKILLRATE_CLASSIC:
2586                      cr.train(SKILL_SECURITY, MAX(5 - cr.get_skill(SKILL_SECURITY), 0));break;
2587                   case FIELDSKILLRATE_HARD:
2588                      cr.train(SKILL_SECURITY, 0);break;
2589                }
2590                set_color(COLOR_WHITE,COLOR_BLACK,1);
2591                move(16,0);
2592                addstr(cr.name, gamelog);
2593                addstr(" jimmies the car door open.", gamelog);
2594                gamelog.nextMessage();
2595
2596                getkey();
2597
2598                entered=true;
2599             }
2600             else
2601             {
2602                set_color(COLOR_WHITE,COLOR_BLACK,1);
2603                move(16,0);
2604                addstr(cr.name, gamelog);
2605                addstr(" fiddles with the lock with no luck.", gamelog);
2606                gamelog.nextMessage();
2607
2608                getkey();
2609             }
2610          }
2611          //BREAK WINDOW
2612          if(method==1)
2613          {
2614             int difficulty = static_cast<int>(DIFFICULTY_EASY / cr.get_weapon().get_bashstrengthmod()) - windowdamage;
2615
2616             if(cr.attribute_check(ATTRIBUTE_STRENGTH,difficulty))
2617             {
2618                set_color(COLOR_WHITE,COLOR_BLACK,1);
2619                move(16,0);
2620                addstr(cr.name, gamelog);
2621                addstr(" smashes the window", gamelog);
2622                if(cr.get_weapon().get_bashstrengthmod()>1)
2623                {
2624                   addstr(" with a ", gamelog);
2625                   addstr(cr.get_weapon().get_name(2), gamelog);
2626                }
2627                addstr(".", gamelog);
2628                gamelog.nextMessage();
2629                windowdamage=10;
2630
2631                getkey();
2632
2633                entered=true;
2634             }
2635             else
2636             {
2637                set_color(COLOR_WHITE,COLOR_BLACK,1);
2638                move(16,0);
2639                addstr(cr.name, gamelog);
2640                addstr(" cracks the window", gamelog);
2641                if(cr.get_weapon().get_bashstrengthmod()>1)
2642                {
2643                   addstr(" with a ", gamelog);
2644                   addstr(cr.get_weapon().get_name(2), gamelog);
2645                }
2646                addstr(" but it is still somewhat intact.", gamelog);
2647                gamelog.nextMessage();
2648                windowdamage++;
2649
2650                getkey();
2651             }
2652          }
2653
2654          //ALARM CHECK
2655          int y=17;
2656
2657          if(touchalarm||sensealarm)
2658          {
2659             if(!alarmon)
2660             {
2661                set_color(COLOR_YELLOW,COLOR_BLACK,1);
2662                move(y++,0);
2663                addstr("An alarm suddenly starts blaring!", gamelog);
2664                gamelog.nextMessage();
2665
2666                getkey();
2667
2668                alarmon=true;
2669             }
2670          }
2671
2672          //NOTICE CHECK
2673          if(!LCSrandom(50)||(!LCSrandom(5)&&alarmon))
2674          {
2675             set_color(COLOR_RED,COLOR_BLACK,1);
2676             move(y++,0);
2677             addstr(cr.name, gamelog);
2678             addstr(" has been spotted by a passerby!", gamelog);
2679             gamelog.nextMessage();
2680
2681             getkey();
2682
2683             //FOOT CHASE
2684             chaseseq.clean();
2685             chaseseq.location=location[cr.location]->parent;
2686             newsstoryst *ns=new newsstoryst;
2687             ns->type=NEWSSTORY_CARTHEFT;
2688             newsstory.push_back(ns);
2689             sitestory=ns;
2690             makechasers(-1,5);
2691
2692             if(footchase(cr)){
2693                mode=GAMEMODE_BASE;
2694                delete v;return false;} // Switched to return false; this will cause you to try again tomorrow
2695             else {
2696                mode=GAMEMODE_BASE;
2697                delete v;return false;}
2698          }
2699       }
2700
2701       //START CAR
2702       char keys_in_car=LCSrandom(5)>0,key_search_total=0;
2703       int key_location=LCSrandom(5),nervous_counter=0;
2704       //char ignition_progress=0;
2705
2706       for(bool started=false;!started;)
2707       {
2708          nervous_counter++;
2709          erase();
2710          set_color(COLOR_WHITE,COLOR_BLACK,1);
2711          move(0,0);
2712          addstr("Adventures in Liberal Car Theft");
2713          printcreatureinfo(&cr);
2714          makedelimiter();
2715
2716          int y=10;
2717
2718          set_color(COLOR_WHITE,COLOR_BLACK,0);
2719          move(y++,0);
2720          addstr(cr.name, gamelog);
2721          addstr(" is behind the wheel of a ", gamelog);
2722          addstr(carname, gamelog);
2723          addstr(".", gamelog);
2724          gamelog.nextMessage();
2725
2726          if(alarmon)
2727          {
2728             set_color(COLOR_WHITE,COLOR_BLACK,1);
2729             move(y++,0);
2730             if(sensealarm)addstr("THE VIPER");
2731             else addstr(carname);
2732             addstr(":   ");
2733             set_color(COLOR_RED,COLOR_BLACK,1);
2734             if(sensealarm)addstr("REMOVE YOURSELF FROM THE VEHICLE!   <BEEP!!> <BEEP!!>");
2735             else addstr("<BEEP!!> <BEEP!!> <BEEP!!> <BEEP!!>");
2736          }
2737
2738          move((++y)++,0);
2739          set_color(COLOR_WHITE,COLOR_BLACK,0);
2740          addstr("A - Hotwire the car.");
2741          set_color(COLOR_WHITE,COLOR_BLACK,0);
2742          move(y++,0);
2743          addstr("B - Desperately search for keys.");
2744          move(y++,0);
2745          if(!sensealarm)addstr("Enter - Call it a day.");
2746          else {addstr("Enter - The Viper has finally deterred ");addstr(cr.name);addstr(".");}
2747          y++;
2748
2749          char method=-1;
2750          while(method==-1)
2751          {
2752             int c=getkey();
2753             if(c=='a') method=0;
2754             if(c=='b') method=1;
2755             if(c=='x'||c==ENTER||c==ESC||c==SPACEBAR){delete v;return false;} // Call it a day and try again tomorrow
2756          }
2757
2758          //HOTWIRE CAR
2759          if(method==0)
2760          {
2761             if(cr.skill_check(SKILL_SECURITY,DIFFICULTY_CHALLENGING))
2762             {
2763                switch (fieldskillrate)
2764                {
2765                   case FIELDSKILLRATE_FAST:
2766                      cr.train(SKILL_SECURITY, 50);break;
2767                   case FIELDSKILLRATE_CLASSIC:
2768                      cr.train(SKILL_SECURITY, MAX(10 - cr.get_skill(SKILL_SECURITY), 0));break;
2769                   case FIELDSKILLRATE_HARD:
2770                      cr.train(SKILL_SECURITY, 0);break;
2771                }
2772                set_color(COLOR_WHITE,COLOR_BLACK,1);
2773                move(y++,0);
2774                addstr(cr.name, gamelog);
2775                addstr(" hotwires the car!", gamelog);
2776                gamelog.nextMessage();
2777
2778                getkey();
2779
2780                started=true;
2781             }
2782             else
2783             {
2784                set_color(COLOR_WHITE,COLOR_BLACK,1);
2785                move(y++,0);
2786                addstr(cr.name, gamelog);
2787                int flavor_text;
2788                if(cr.get_skill(SKILL_SECURITY) < 4)
2789                   flavor_text = LCSrandom(3);
2790                else flavor_text = LCSrandom(5);
2791                switch(flavor_text)
2792                {
2793                   case 0:addstr(" fiddles with the ignition, but the car doesn't start.", gamelog);break;
2794                   case 1:addstr(" digs around in the steering column, but the car doesn't start.", gamelog);break;
2795                   case 2:addstr(" touches some wires together, but the car doesn't start.", gamelog);break;
2796                   case 3:addstr(" makes something in the engine click, but the car doesn't start.", gamelog);break;
2797                   case 4:addstr(" manages to turn on some dash lights, but the car doesn't start.", gamelog);break;
2798                }
2799                gamelog.nextMessage();
2800
2801                getkey();
2802             }
2803          }
2804          //KEYS
2805          if(method==1)
2806          {
2807             int difficulty;
2808             const char * location;
2809
2810             if(!keys_in_car)
2811             {
2812                difficulty = DIFFICULTY_IMPOSSIBLE;
2813                location   = "in SPACE. With ALIENS. Seriously.";
2814             }
2815             else switch(key_location)
2816             {
2817             case 0:
2818             default:
2819                difficulty = DIFFICULTY_AUTOMATIC;
2820                location   = "in the ignition.  Damn.";
2821                break;
2822             case 1:
2823                difficulty = DIFFICULTY_EASY;
2824                location   = "above the pull-down sunblock thingy!";
2825                break;
2826             case 2:
2827                difficulty = DIFFICULTY_EASY;
2828                location   = "in the glove compartment!";
2829                break;
2830             case 3:
2831                difficulty = DIFFICULTY_AVERAGE;
2832                location   = "under the front seat!";
2833                break;
2834             case 4:
2835                difficulty = DIFFICULTY_HARD;
2836                location   = "under the back seat!";
2837                break;
2838             }
2839             if(cr.attribute_check(ATTRIBUTE_INTELLIGENCE,difficulty))
2840             {
2841                set_color(COLOR_GREEN,COLOR_BLACK,1);
2842                move(y++,0);
2843                if(law[LAW_FREESPEECH]==-2)addstr("Holy [Car Keys]!  ", gamelog); // Holy car keys Batman!
2844                else addstr("Holy shit!  ", gamelog);
2845                addstr(cr.name, gamelog);
2846                addstr(" found the keys ", gamelog);
2847                addstr(location, gamelog);
2848                gamelog.nextMessage();
2849
2850                getkey();
2851
2852                started=true;
2853             }
2854             else
2855             {
2856                key_search_total++;
2857                set_color(COLOR_WHITE,COLOR_BLACK,1);
2858                move(y++,0);
2859                addstr(cr.name, gamelog);
2860                addstr(": <rummaging> ", gamelog);
2861                set_color(COLOR_GREEN,COLOR_BLACK,1);
2862                if(key_search_total==5)
2863                   addstr("Are they even in here?", gamelog);
2864                else if(key_search_total==10)
2865                   addstr("I don't think they're in here...", gamelog);
2866                else if(key_search_total==15)
2867                   addstr("If they were here, I'd have found them by now.", gamelog);
2868                else if (key_search_total>15)
2869                {
2870                   switch(LCSrandom(5))
2871                   {
2872                   case 0:addstr("This isn't working!", gamelog);break;
2873                   case 1:addstr("Why me?", gamelog);break;
2874                   case 2:addstr("What do I do now?", gamelog);break;
2875                   case 3:addstr("Oh no...", gamelog);break;
2876                   case 4:addstr("I'm going to get arrested, aren't I?", gamelog);break;
2877                   }
2878                }
2879                else
2880                {
2881                   switch(LCSrandom(5))
2882                   {
2883                      case 0:addstr("Please be in here somewhere...", gamelog);break;
2884                      case 1:
2885                         if(law[LAW_FREESPEECH]==-2)addstr("[Shoot]!  Where are they?!", gamelog);
2886                         else addstr("Fuck!  Where are they?!", gamelog);
2887                         break;
2888                      case 2:addstr("Come on, baby, come to me...", gamelog);break;
2889                      case 3:
2890                         if(law[LAW_FREESPEECH]==-2)addstr("[Darn] it...", gamelog);
2891                         else addstr("Dammit...", gamelog);
2892                         break;
2893                      case 4:addstr("I wish I could hotwire this thing...", gamelog);break;
2894                   }
2895                }
2896                gamelog.nextMessage();
2897
2898                getkey();
2899             }
2900          }
2901
2902          //NOTICE CHECK
2903          if(!started&&(!LCSrandom(50)||(!LCSrandom(5)&&alarmon)))
2904          {
2905             set_color(COLOR_RED,COLOR_BLACK,1);
2906             move(y++,0);
2907             addstr(cr.name, gamelog);
2908             addstr(" has been spotted by a passerby!", gamelog);
2909             gamelog.nextMessage();
2910
2911             getkey();
2912
2913             //FOOT CHASE
2914             chaseseq.clean();
2915             chaseseq.location=location[cr.location]->parent;
2916             newsstoryst *ns=new newsstoryst;
2917             ns->type=NEWSSTORY_CARTHEFT;
2918             newsstory.push_back(ns);
2919             sitestory=ns;
2920             makechasers(-1,5);
2921
2922             if(footchase(cr)){
2923                mode=GAMEMODE_BASE;
2924                delete v;return 0;}
2925             else {
2926                mode=GAMEMODE_BASE;
2927                delete v;return 0;}
2928          }
2929
2930          // Nervous message check
2931          else if (!started&&(LCSrandom(7)+5)<nervous_counter)
2932          {
2933             nervous_counter=0;
2934             move(++y,0);y++;
2935             set_color(COLOR_YELLOW,COLOR_BLACK,1);
2936             addstr(cr.name, gamelog);
2937             switch(LCSrandom(3))
2938             {
2939                case 0:addstr(" hears someone nearby making a phone call.", gamelog);break;
2940                case 1:addstr(" is getting nervous being out here this long.", gamelog);break;
2941                case 2:addstr(" sees a police car driving around a few blocks away.", gamelog);break;
2942             }
2943             gamelog.nextMessage();
2944
2945             getkey();
2946          }
2947       }
2948
2949       //CHASE SEQUENCE
2950          //CAR IS OFFICIAL, THOUGH CAN BE DELETE BY chasesequence()
2951       addjuice(cr,v->steal_juice(),100);
2952
2953       vehicle.push_back(v);
2954       v->add_heat(14+v->steal_extraheat());
2955       v->set_location(cr.base);
2956       // Automatically assign this car to this driver, if no other one is present
2957       if(cr.pref_carid==-1)
2958       {
2959          cr.pref_carid = v->id();
2960          cr.pref_is_driver = true;
2961       }
2962
2963       chaseseq.clean();
2964       chaseseq.location=location[cr.location]->parent;
2965       int chaselev=!LCSrandom(13-windowdamage);
2966       if(chaselev>0||(v->vtypeidname()=="POLICECAR"&&LCSrandom(2))) //Identify police cruiser. Temporary solution? -XML
2967       {
2968          v->add_heat(10);
2969          chaselev=1;
2970          newsstoryst *ns=new newsstoryst;
2971          ns->type=NEWSSTORY_CARTHEFT;
2972          newsstory.push_back(ns);
2973          sitestory=ns;
2974          makechasers(-1,chaselev);
2975          if(!chasesequence(cr,*v)) // Caught or killed in the chase. Do not need to delete vehicle.
2976             return 0;
2977       }
2978
2979       return 1;
2980    }
2981
2982    return 0;
2983 }
2984
2985 bool carselect(Creature &cr,short &cartype)
2986 {
2987    cartype=-1;
2988
2989    vector<int> cart;
2990    for(int a=0;a<len(vehicletype);a++)
2991       if(vehicletype[a]->steal_difficultytofind()<10) cart.push_back(a);
2992
2993    int page=0;
2994
2995    while(true)
2996    {
2997       erase();
2998
2999       set_color(COLOR_WHITE,COLOR_BLACK,1);
3000       move(0,0);
3001       addstr("What type of car will ");
3002       addstr(cr.name);
3003       addstr(" try to find and steal today?");
3004       set_color(COLOR_WHITE,COLOR_BLACK,0);
3005       move(1,0);
3006       addstr("トトトトTYPEトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトトDIFFICULTY TO FIND UNATTENDEDトト");
3007
3008       int y=2,difficulty;
3009       for(int p=page*19;p<len(cart)&&p<page*19+19;p++)
3010       {
3011          set_color(COLOR_WHITE,COLOR_BLACK,0);
3012          move(y,0);
3013          addchar(y+'A'-2);addstr(" - ");
3014          addstr(vehicletype[cart[p]]->longname());
3015
3016          move(y++,49);
3017          difficulty=vehicletype[cart[p]]->steal_difficultytofind();
3018          switch(difficulty)
3019          {
3020             case 0:
3021                set_color(COLOR_GREEN,COLOR_BLACK,1);
3022                addstr("Simple");
3023                break;
3024             case 1:
3025                set_color(COLOR_CYAN,COLOR_BLACK,1);
3026                addstr("Very Easy");
3027                break;
3028             case 2:
3029                set_color(COLOR_CYAN,COLOR_BLACK,0);
3030                addstr("Easy");
3031                break;
3032             case 3:
3033                set_color(COLOR_BLUE,COLOR_BLACK,1);
3034                addstr("Below Average");
3035                break;
3036             case 4:
3037                set_color(COLOR_WHITE,COLOR_BLACK,1);
3038                addstr("Average");
3039                break;
3040             case 5:
3041                set_color(COLOR_WHITE,COLOR_BLACK,0);
3042                addstr("Above Average");
3043                break;
3044             case 6:
3045                set_color(COLOR_YELLOW,COLOR_BLACK,1);
3046                addstr("Hard");
3047                break;
3048             case 7:
3049                set_color(COLOR_MAGENTA,COLOR_BLACK,0);
3050                addstr("Very Hard");
3051                break;
3052             case 8:
3053                set_color(COLOR_MAGENTA,COLOR_BLACK,1);
3054                addstr("Extremely Difficult");
3055                break;
3056             case 9:
3057                set_color(COLOR_RED,COLOR_BLACK,0);
3058                addstr("Nearly Impossible");
3059                break;
3060             default:
3061                set_color(COLOR_RED,COLOR_BLACK,1);
3062                addstr("Impossible");
3063                break;
3064          }
3065       }
3066
3067       set_color(COLOR_WHITE,COLOR_BLACK,0);
3068       move(22,0);
3069       addstr("Press a Letter to select a Type of Car");
3070       move(23,0);
3071       addpagestr();
3072
3073       int c=getkey();
3074
3075       //PAGE UP
3076       if((c==interface_pgup||c==KEY_UP||c==KEY_LEFT)&&page>0) page--;
3077       //PAGE DOWN
3078       if((c==interface_pgdn||c==KEY_DOWN||c==KEY_RIGHT)&&(page+1)*19<len(cart)) page++;
3079
3080       if(c>='a'&&c<='s')
3081       {
3082          int p=page*19+c-'a';
3083          if(p<len(cart))
3084          {
3085             cartype=cart[p];
3086             return true;
3087          }
3088       }
3089
3090       // Too easy to accidentally back out
3091       // Not a big problem if this page isn't skippable
3092       // (There's no immediate risk in picking a car)
3093       // - JDS
3094       //if(c=='x'||c==ENTER||c==ESC||c==SPACEBAR)break;
3095    }
3096
3097    return false;
3098 }
3099
3100 /* get a wheelchair */
3101 void getwheelchair(Creature &cr,char &clearformess)
3102 {
3103    if(clearformess) erase();
3104    else makedelimiter();
3105
3106    if(LCSrandom(2))
3107    {
3108       set_color(COLOR_WHITE,COLOR_BLACK,1);
3109       move(8,1);
3110       addstr(cr.name, gamelog);
3111       addstr(" has procured a wheelchair.", gamelog);
3112
3113       cr.flag|=CREATUREFLAG_WHEELCHAIR;
3114    }
3115    else
3116    {
3117       set_color(COLOR_WHITE,COLOR_BLACK,1);
3118       move(8,1);
3119       addstr(cr.name, gamelog);
3120       addstr(" was unable to get a wheelchair.  Maybe tomorrow...", gamelog);
3121    }
3122    gamelog.nextMessage();
3123
3124    getkey();
3125 }