1--[[ Copyright (c) 2010 Manuel "Roujin" Wolf
2Copyright (c) 2020 lewri
3
4Permission is hereby granted, free of charge, to any person obtaining a copy of
5this software and associated documentation files (the "Software"), to deal in
6the Software without restriction, including without limitation the rights to
7use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8of the Software, and to permit persons to whom the Software is furnished to do
9so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all
12copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20SOFTWARE. --]]
21
22corsixth.require("announcer")
23
24local AnnouncementPriority = _G["AnnouncementPriority"]
25
26--! A holder for all cheats in the game
27class "Cheats"
28
29---@type Cheats
30local Cheats = _G["Cheats"]
31
32-- Cheats System
33function Cheats:Cheats(hospital)
34  self.hospital = hospital
35  -- Cheats to appear specifically in the cheats window
36  -- New cheats require an afterLoad when added
37  self.cheat_list = {
38    {name = "money",          func = self.cheatMoney},
39    {name = "all_research",   func = self.cheatResearch},
40    {name = "emergency",      func = self.cheatEmergency},
41    {name = "epidemic",       func = self.cheatEpidemic},
42    {name = "toggle_infected", func = self.cheatToggleInfected},
43    {name = "vip",            func = self.cheatVip},
44    {name = "earthquake",     func = self.cheatEarthquake},
45    {name = "create_patient", func = self.cheatPatient},
46    {name = "end_month",      func = self.cheatMonth},
47    {name = "end_year",       func = self.cheatYear},
48    {name = "lose_level",     func = self.cheatLose},
49    {name = "win_level",      func = self.cheatWin},
50    {name = "increase_prices", func = self.cheatIncreasePrices},
51    {name = "decrease_prices", func = self.cheatDecreasePrices},
52  }
53end
54
55--! Performs a cheat from the cheat_list
56--!param num (integer) The cheat from the cheat_list called
57--!return true if cheat was successful, false otherwise
58function Cheats:performCheat(num)
59  local cheat_success = self.cheat_list[num].func(self) ~= false
60  return cheat_success and self.cheat_list[num].name ~= "lose_level"
61end
62
63--! Updates the cheated status of the player, with a matching announcement
64function Cheats:announceCheat()
65  local announcements = self.hospital.world.cheat_announcements
66  if announcements then
67    self.hospital.world.ui:playAnnouncement(announcements[math.random(1, #announcements)], AnnouncementPriority.Critical)
68  end
69  self.hospital.cheated = true
70end
71
72function Cheats:cheatMoney()
73  self.hospital:receiveMoney(10000, _S.transactions.cheat)
74end
75
76function Cheats:cheatResearch()
77  local hosp = self.hospital
78  for _, cat in ipairs({"diagnosis", "cure"}) do
79    while hosp.research.research_policy[cat].current do
80      hosp.research:discoverObject(hosp.research.research_policy[cat].current)
81    end
82  end
83end
84
85function Cheats:cheatEmergency()
86  local err = self.hospital:createEmergency()
87  local ui = self.hospital.world.ui
88  if err == "undiscovered_disease" then
89    ui:addWindow(UIInformation(ui, {_S.misc.cant_treat_emergency}))
90  elseif err == "no_heliport" then
91    ui:addWindow(UIInformation(ui, {_S.misc.no_heliport}))
92  -- else 'err == nil', meaning success. The case doesn't need special handling
93  end
94end
95
96--[[ Creates a new contagious patient in the hospital - potentially an epidemic]]
97function Cheats:cheatEpidemic()
98  self.hospital:spawnContagiousPatient()
99end
100
101--[[ Before an epidemic has been revealed toggle the infected icons
102to easily distinguish the infected patients -- will toggle icons
103for ALL future epidemics you cannot distinguish between epidemics
104by disease ]]
105function Cheats:cheatToggleInfected()
106  local hosp = self.hospital
107  if hosp.future_epidemics_pool and #hosp.future_epidemics_pool > 0 then
108    for _, future_epidemic in ipairs(hosp.future_epidemics_pool) do
109      local show_mood = future_epidemic.cheat_always_show_mood
110      future_epidemic.cheat_always_show_mood = not show_mood
111      local mood_action = show_mood and "deactivate" or "activate"
112      for _, patient in ipairs(future_epidemic.infected_patients) do
113        patient:setMood("epidemy4",mood_action)
114      end
115    end
116  else
117    self.hospital.world:gameLog("Unable to toggle icons - no epidemics in progress that are not revealed")
118  end
119end
120
121function Cheats:cheatVip()
122  self.hospital:createVip()
123end
124
125function Cheats:cheatEarthquake()
126  return self.hospital.world:createEarthquake()
127end
128
129function Cheats:cheatPatient()
130  self.hospital.world:spawnPatient()
131end
132
133function Cheats:cheatMonth()
134  self.hospital.world:setEndMonth()
135end
136
137function Cheats:cheatYear()
138  self.hospital.world:setEndYear()
139end
140
141function Cheats:cheatLose()
142  self.hospital.world:loseGame(1) -- TODO adjust for multiplayer
143end
144
145function Cheats:cheatWin()
146  self.hospital.world:winGame(1) -- TODO adjust for multiplayer
147end
148
149function Cheats:cheatIncreasePrices()
150  local hosp = self.hospital
151  for _, casebook in pairs(hosp.disease_casebook) do
152    local new_price = casebook.price + 0.5
153    if new_price > 2 then
154      casebook.price = 2
155    else
156      casebook.price = new_price
157    end
158  end
159end
160
161function Cheats:cheatDecreasePrices()
162  local hosp = self.hospital
163  for _, casebook in pairs(hosp.disease_casebook) do
164    local new_price = casebook.price - 0.5
165    if new_price < 0.5 then
166      casebook.price = 0.5
167    else
168      casebook.price = new_price
169    end
170  end
171end
172