Description:
Add Mass Vandalism event.
Commit status:
[Not Reviewed]
References:
Diff options:
Comments:
0 Commit comments
0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
@@ -0,0 +1,8 | |||
|
1 | ||
|
2 | ||
|
3 | using Encompass; | |
|
4 | ||
|
5 | namespace isometricparkfna.Components | |
|
6 | { | |
|
7 | public struct EventComponent : IComponent { } | |
|
8 | } |
@@ -8,10 +8,10 | |||
|
8 | 8 | - Movement @done(2021-01-27) |
|
9 | 9 | - Close button @done(2021-01-28) |
|
10 | 10 | - Better appearance |
|
11 |
- Money graph @maybe |
|
|
11 | - Money graph @maybe | |
|
12 | 12 | Procgen: |
|
13 | 13 | short phase, maybe? |
|
14 |
- Add some procedurally generated dialog @maybe @milestone(2: Procgen) |
|
|
14 | - Add some procedurally generated dialog @maybe @milestone(2: Procgen) | |
|
15 | 15 | - Add some procedurally generated newspaper @maybe @milestone(2: Procgen) @done(2021-03-15) |
|
16 | 16 | - Basic NEWS tab @milestone(2: Procgen) |
|
17 | 17 | - Different tabs for different sources @done(2021-02-21) |
@@ -33,7 +33,6 | |||
|
33 | 33 | - Add company images @milestone(3: Contracts) @maybe @done(2021-05-21) |
|
34 | 34 | - Contracts should end |
|
35 | 35 | Trees: |
|
36 | ||
|
37 | 36 | - Add basic maintenance cost @milestone(1: Basic Money) @done(2021-01-27) |
|
38 | 37 | - Add basic age simulation |
|
39 | 38 | - Add water @milestone(6: Trees and Tiles) |
@@ -46,7 +45,7 | |||
|
46 | 45 | Reduces cost of vandalism repair? |
|
47 | 46 | - Sell Firewood? |
|
48 | 47 | Staff: |
|
49 |
- Ranger staffing? @maybe @milestone(1: Basic Money) |
|
|
48 | - Ranger staffing? @maybe @milestone(1: Basic Money) | |
|
50 | 49 | - Staffing window |
|
51 | 50 | - Ranger allocation |
|
52 | 51 | - Set employee salaries, leave, etc. @maybe |
@@ -56,7 +55,7 | |||
|
56 | 55 | Leisure: |
|
57 | 56 | - Add way to mark off area for leisure @milestone(7: Leisure) |
|
58 | 57 | - Basic satisfaction @milestone(7: Leisure) |
|
59 |
- Set |
|
|
58 | - Set | |
|
60 | 59 | End games/outcomes: |
|
61 | 60 | - Financial mismanagement @milestone(5: Events) |
|
62 | 61 | - Figure out threshold |
@@ -76,12 +75,11 | |||
|
76 | 75 | - Land repatriation to indigenous @maybe |
|
77 | 76 | Like the acknowledgement, don't want it to be too white savior-y (although obv. player isn't necessarily white) |
|
78 | 77 | - Research center @maybe |
|
79 | - | |
|
80 | 78 | Community: |
|
81 | 79 | Differing reputation with different groups. Could mix more and less political. |
|
82 | 80 | Don't want to go too Democracy 3/4: being able to affect the group size via policy is probably out. (Groups being intersectional might work, but is kind of tricky.) |
|
83 |
Maybe a procedurally generated set of groups with some hard-coded elements? E.g |
|
|
84 | ||
|
81 | Maybe a procedurally generated set of groups with some hard-coded elements? E.g | |
|
82 | ||
|
85 | 83 | Misc: |
|
86 | 84 | - Assistant commentary @milestone(5: Events) |
|
87 | 85 | Need to ensure it's not annoying |
@@ -91,13 +89,13 | |||
|
91 | 89 | - Federal grant |
|
92 | 90 | - Celebrity visit |
|
93 | 91 | - Disasters @maybe |
|
94 |
- Fire |
|
|
92 | - Fire | |
|
95 | 93 | would probably have to animate |
|
96 | 94 | - Disease |
|
97 | 95 | - Photos for dialog? |
|
98 | 96 | - Graphs window |
|
99 | 97 | Could use ImPlot for this |
|
100 | ||
|
98 | ||
|
101 | 99 | Structure: |
|
102 | 100 | - Add modes @milestone(5: Events) |
|
103 | 101 | - Refactor stuff out of FNAGame |
@@ -154,11 +152,11 | |||
|
154 | 152 | - Relocate fonts to central place @done(2021-06-26) |
|
155 | 153 | - Remove fonts from DebugWindow? |
|
156 | 154 | - Adjust window dimensions when font changes |
|
157 |
- Option to Turn off bad outcomes or disasters @maybe |
|
|
155 | - Option to Turn off bad outcomes or disasters @maybe | |
|
158 | 156 | - Dyslexic-friendly font @maybe @done(2021-06-26) |
|
159 | 157 | Cursory research indicates open sans-serif fonts are best, |
|
160 | 158 | although fonts only help so much. (Monospaced fonts are also cited as good options so Iosevka might already be good enough. Still, I added Roboto.) |
|
161 | ||
|
159 | ||
|
162 | 160 | - Screen reader support @maybe |
|
163 | 161 | Would probably be a big undertaking (sort of opposite to the web, where things tend to be accessible unless you start reimplenting things or going more advanced) |
|
164 | 162 | - Investigate .NET support for screen readers |
@@ -172,7 +170,6 | |||
|
172 | 170 | - Linux |
|
173 | 171 | - Look for prior art |
|
174 | 172 | - Add a "describe" button/key that speaks the current scene @maybe |
|
175 | - | |
|
176 | 173 | - No fees when contracts break |
|
177 | 174 | - Contracts go dormant instead of ending. |
|
178 | 175 | Other QoL things: |
@@ -1,17 +1,32 | |||
|
1 | ||
|
2 | VAR playerSwears = 0 | |
|
3 | VAR playerRude = 0 | |
|
1 | 4 | |
|
2 | 5 | VAR GovernorOpinion = 0 |
|
3 | 6 | |
|
7 | ||
|
4 | 8 | //This is needed to make both including and for jumpting to dialog sections work: |
|
5 | 9 | === placeholder === |
|
6 | 10 | |
|
7 | 11 | -> END |
|
8 | 12 | |
|
13 | ||
|
14 | === function alter(ref x, k) === | |
|
15 | ~ x = x + k | |
|
16 | ||
|
17 | ||
|
18 | === function inc(ref x) === | |
|
19 | ~ x = x + 1 | |
|
20 | ||
|
21 | === function dec(ref x) === | |
|
22 | ~ x = x - 1 | |
|
23 | ||
|
9 | 24 | === Once === |
|
10 | 25 | |
|
11 | 26 | Once upon a time... |
|
12 | 27 | |
|
13 |
|
|
|
14 |
|
|
|
28 | + There were two choices. | |
|
29 | + There were four lines of content. | |
|
15 | 30 | |
|
16 | 31 | - They lived happily ever after. |
|
17 | 32 | -> END |
@@ -48,8 +63,6 | |||
|
48 | 63 | * [Nice to meet you.] |
|
49 | 64 | You can use the mouse or arrow keys to move around, and the plus and minus keys to zoom in and out. B opens the budget and F lets you adjust Forest Policy. |
|
50 | 65 | |
|
51 | -> BadNewsReact -> | |
|
52 | ||
|
53 | 66 | * * [Got it, thanks.] |
|
54 | 67 | |
|
55 | 68 | \#assistantName\#: Bye |
@@ -61,9 +74,46 | |||
|
61 | 74 | |
|
62 | 75 | |
|
63 | 76 | === BadNewsReact === |
|
64 | * [Damn.] | |
|
77 | ||
|
78 | ||
|
79 | ||
|
80 | + [Damn.] {inc(playerSwears)} | |
|
81 | ->-> | |
|
82 | + [Fuck.] {inc(playerSwears)} | |
|
83 | ->-> | |
|
84 | + [Shoot.] {inc(playerSwears)} | |
|
85 | ->-> | |
|
86 | + [*Sigh.* Fine.] | |
|
65 | 87 | ->-> |
|
66 | * [Fuck.] | |
|
88 | ||
|
89 | === AssistantAcknowlege === | |
|
90 | + [Thanks.] | |
|
91 | ->-> | |
|
92 | + [Mmmm hmm.] | |
|
93 | ->-> | |
|
94 | + [Get to it.] {inc(playerRude)} | |
|
95 | ->-> | |
|
96 | + [I really appreciate it, \#assistantName\#] | |
|
97 | -> Appreciate | |
|
98 | ||
|
99 | = Appreciate | |
|
100 | \#assistantName\#: Oh, you're welcome. | |
|
67 | 101 | ->-> |
|
68 | * [Shoot.] | |
|
69 | ->-> No newline at end of file | |
|
102 | ||
|
103 | === MassVandalism === | |
|
104 | \#assistantName\#: Bad news, director. | |
|
105 | + [Oh?] | |
|
106 | \#assistantName\#: A number of trees have been seriously damaged overnight. | |
|
107 | + + [How bad are they?] | |
|
108 | ||
|
109 | \#assistantName\#: I'm no botanist, but they're not great. The gouges are pretty deep. | |
|
110 | ||
|
111 | -> BadNewsReact -> | |
|
112 | ||
|
113 | \#assistantName\#: Yeah, it's awful. | |
|
114 | ||
|
115 | I'll see who's around and get to cleaning. | |
|
116 | ||
|
117 | -> AssistantAcknowlege -> | |
|
118 | ||
|
119 | -> END No newline at end of file |
@@ -1,1 +1,1 | |||
|
1 |
{"inkVersion":20,"root":[[["done",{"#f":5,"#n":"g-0"}],null],"done",{"placeholder":["end",{"#f":1}],"Once":[["^Once upon a time...","\n",["ev",{"^->":"Once.0.2.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.^.c-0","flg": |
|
|
1 | {"inkVersion":20,"root":[[["done",{"#f":5,"#n":"g-0"}],null],"done",{"placeholder":["end",{"#f":1}],"Once":[["^Once upon a time...","\n",["ev",{"^->":"Once.0.2.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.^.c-0","flg":2},{"s":["^There were two choices.",{"->":"$r","var":true},null]}],["ev",{"^->":"Once.0.3.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.^.c-1","flg":2},{"s":["^There were four lines of content.",{"->":"$r","var":true},null]}],{"c-0":["ev",{"^->":"Once.0.c-0.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.2.s"},[{"#n":"$r2"}],"\n",{"->":".^.^.g-0"},{"#f":5}],"c-1":["ev",{"^->":"Once.0.c-1.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.3.s"},[{"#n":"$r2"}],"\n",{"->":".^.^.g-0"},{"#f":5}],"g-0":["^They lived happily ever after.","\n","end",{"#f":5}]}],{"#f":1}],"IntroGovernor":[["^Governor: Welcome to your new park, director!","\n","ev","str","^Okay","/str","/ev",{"*":".^.c-0","flg":20},{"c-0":["\n","^Governor: Make sure that you keep visitors happy and the budget in the black! You're currently getting an annual grant out of my budget—it'd sure be nice if you park were self-sufficient so we could drop that expense!","\n",["ev","str","^And I need to keep the forest healthy, too, right?","/str","/ev",{"*":".^.c-0","flg":20},"ev","str","^Sounds good!","/str","/ev",{"*":".^.c-1","flg":20},{"c-0":["^ ","\n","ev",{"VAR?":"GovernorOpinion"},1,"-","/ev",{"VAR=":"GovernorOpinion","re":true},"^Governor: Ummm, yeah","\n",["ev","str","^...","/str","/ev",{"*":".^.c-0","flg":20},{"c-0":["\n","end",{"#f":5}]}],{"#f":5}],"c-1":["\n","ev",{"VAR?":"GovernorOpinion"},1,"+","/ev",{"VAR=":"GovernorOpinion","re":true},"^Governor: I'll check in soon.","\n","end",{"#f":5}]}],{"#f":5}]}],{"#f":1}],"IntroAssistant":[["^#assistantName#: Hello. I'm #assistantName#.","\n","ev","str","^Nice to meet you.","/str","/ev",{"*":".^.c-0","flg":20},{"c-0":["\n","^You can use the mouse or arrow keys to move around, and the plus and minus keys to zoom in and out. B opens the budget and F lets you adjust Forest Policy.","\n",["ev","str","^Got it, thanks.","/str","/ev",{"*":".^.c-0","flg":20},"ev","str","^How are you?","/str","/ev",{"*":".^.c-1","flg":20},{"c-0":["\n","^#assistantName#: Bye","\n","end",{"#f":5}],"c-1":["\n","^#assistantName#: #howdoing#","\n","end",{"#f":5}]}],{"#f":5}]}],{"#f":1}],"BadNewsReact":[["ev","str","^Damn.","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Fuck.","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Shoot.","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^*Sigh.* Fine.","/str","/ev",{"*":".^.c-3","flg":4},{"c-0":["\n","ev","void","/ev","->->",{"#f":5}],"c-1":["\n","ev","void","/ev","->->",{"#f":5}],"c-2":["\n","ev","void","/ev","->->",{"#f":5}],"c-3":["\n","ev","void","/ev","->->",{"#f":5}]}],{"#f":1}],"AssistantAcknowlege":[["ev","str","^Thanks.","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Mmmm hmm.","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Get to it.","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^I really appreciate it, #assistantName#","/str","/ev",{"*":".^.c-3","flg":4},{"c-0":["\n","ev","void","/ev","->->",{"#f":5}],"c-1":["\n","ev","void","/ev","->->",{"#f":5}],"c-2":["\n","ev","void","/ev","->->",{"#f":5}],"c-3":["\n","ev","void","/ev","->->",{"#f":5}]}],{"#f":1}],"MassVandalism":[["^#assistantName#: Bad news, director.","\n","ev","str","^Oh?","/str","/ev",{"*":".^.c-0","flg":4},{"c-0":["\n","^#assistantName#: A number of trees have been seriously damaged overnight.","\n",["ev","str","^How bad are they?","/str","/ev",{"*":".^.c-0","flg":4},{"c-0":["\n","^#assistantName#: I'm no botanist, but they're not great. The gouges are pretty deep.","\n",{"->t->":"BadNewsReact"},"^#assistantName#: Yeah, it's awful.","\n","^I'll see who's around and get to cleaning.","\n",{"->t->":"AssistantAcknowlege"},"end",{"#f":5}]}],{"#f":5}]}],{"#f":1}],"global decl":["ev",0,{"VAR=":"GovernorOpinion"},"/ev","end",null],"#f":1}],"listDefs":{}} No newline at end of file |
@@ -4,6 +4,6 | |||
|
4 | 4 | INCLUDE dialog.ink |
|
5 | 5 | |
|
6 | 6 | |
|
7 | -> IntroAssistant | |
|
7 | -> MassVandalism | |
|
8 | 8 | |
|
9 | 9 | -> END No newline at end of file |
@@ -1,39 +1,75 | |||
|
1 | 1 | using System; |
|
2 | 2 | |
|
3 | using Microsoft.Xna.Framework; | |
|
4 | ||
|
3 | 5 | using Encompass; |
|
4 | 6 | |
|
5 | 7 | using isometricparkfna.Messages; |
|
8 | using isometricparkfna.Components; | |
|
9 | using isometricparkfna.Utils; | |
|
6 | 10 | |
|
7 | 11 | namespace isometricparkfna.Engines |
|
8 | 12 | { |
|
9 | 13 | |
|
10 | 14 | [Receives(typeof(TickMessage))] |
|
11 | 15 | [Sends(typeof(SpawnDialogMessage))] |
|
16 | [Reads(typeof(EventComponent), | |
|
17 | typeof(TreeDeltaComponent))] | |
|
18 | [Writes(typeof(TreeDeltaComponent))] | |
|
12 | 19 | class EventEngine : Engine |
|
13 | 20 | { |
|
14 | ||
|
15 | 21 | Random Random; |
|
16 | 22 | |
|
17 | 23 | public EventEngine() |
|
18 | 24 | { |
|
19 | 25 | this.Random = new Random(); |
|
26 | ||
|
20 | 27 | } |
|
21 | 28 | |
|
22 | 29 | public override void Update(double dt) |
|
23 | 30 | { |
|
31 | ||
|
32 | #region random_events | |
|
24 | 33 | foreach (var tick in ReadMessages<TickMessage>()) |
|
25 | 34 | { |
|
26 | 35 | |
|
27 | if (this.Random.Next(0, 10) == 1) | |
|
36 | #region remove_events | |
|
37 | foreach(var entity in ReadEntities<EventComponent>()) | |
|
38 | { | |
|
39 | Logging.Debug("Destroying Event entity."); | |
|
40 | Destroy(entity); | |
|
41 | } | |
|
42 | #endregion | |
|
43 | if (this.Random.Next(0, 100) == 1) | |
|
28 | 44 | { |
|
29 | 45 | Logging.Debug("Spawning Once dialog."); |
|
30 | 46 | SendMessage(new SpawnDialogMessage { Path = "Once" }); |
|
31 | 47 | } |
|
32 | 48 | |
|
33 | } | |
|
34 |
|
|
|
49 | if (this.Random.Next(0, 10) == 2) | |
|
50 | { | |
|
51 | Logging.Debug("Tree planting campaign!🎉"); | |
|
52 | ||
|
53 | var campaignEntity = CreateEntity(); | |
|
54 | ||
|
55 | AddComponent(campaignEntity, new TreeDeltaComponent{deltaTrees = new Fact<int>(4)}); | |
|
35 | 56 | |
|
36 | ||
|
57 | // AddComponent(campaignEntity, new AreaComponent{squares=final_squares}); | |
|
58 | } | |
|
59 | if (this.Random.Next(0, 10) == 3) | |
|
60 | { | |
|
61 | Logging.Debug("Mass vandalism 😿"); | |
|
62 | ||
|
63 | var campaignEntity = CreateEntity(); | |
|
37 | 64 | |
|
65 | AddComponent(campaignEntity, new TreeDeltaComponent{deltaTrees = new Fact<int>(-100)}); | |
|
66 | AddComponent(campaignEntity, new EventComponent{}); | |
|
67 | ||
|
68 | SendMessage(new SpawnDialogMessage { Path = "MassVandalism" }); | |
|
69 | } | |
|
70 | } | |
|
71 | #endregion | |
|
72 | ||
|
73 | } | |
|
38 | 74 | } |
|
39 | 75 | } |
@@ -1,5 +1,8 | |||
|
1 | 1 | using System; |
|
2 | 2 | using System.Linq; |
|
3 | using System.Collections.Generic; | |
|
4 | ||
|
5 | using Microsoft.Xna.Framework; | |
|
3 | 6 | |
|
4 | 7 | using Encompass; |
|
5 | 8 | |
@@ -23,10 +26,24 | |||
|
23 | 26 | private int ticksToSend; |
|
24 | 27 | private Random random_generator; |
|
25 | 28 | |
|
29 | Vector2[] all_squares; | |
|
30 | ||
|
26 | 31 | public SimulationBridgeEngine(Simulation simulation) |
|
27 | 32 | { |
|
28 | 33 | this.simulation = simulation; |
|
29 | 34 | this.random_generator = new Random(); |
|
35 | ||
|
36 | List<Vector2> squares = new List<Vector2>(); | |
|
37 | ||
|
38 | for(int i = 0; i < simulation.map.MapWidth; i++) | |
|
39 | { | |
|
40 | for(int j = 0; j < simulation.map.MapHeight; j++) | |
|
41 | { | |
|
42 | squares.Add(new Vector2(i,j)); | |
|
43 | } | |
|
44 | } | |
|
45 | this.all_squares = squares.ToArray(); | |
|
46 | ||
|
30 | 47 | } |
|
31 | 48 | |
|
32 | 49 | public int addTick() |
@@ -106,44 +123,52 | |||
|
106 | 123 | |
|
107 | 124 | foreach (ref readonly var entity in ReadEntities<TreeDeltaComponent>()) |
|
108 | 125 | { |
|
109 | var status = GetComponent<ContractStatusComponent>(entity).status; | |
|
110 | var area = GetComponent<AreaComponent>(entity); | |
|
111 | var delta = GetComponent<TreeDeltaComponent>(entity); | |
|
126 | if ((HasComponent<ContractStatusComponent>(entity) && GetComponent<ContractStatusComponent>(entity).status == ContractStatus.Accepted) | |
|
127 | || !(HasComponent<ContractStatusComponent>(entity) )) | |
|
128 | { | |
|
129 | var delta = GetComponent<TreeDeltaComponent>(entity); | |
|
112 | 130 | |
|
113 | if (status == ContractStatus.Accepted) | |
|
114 | { | |
|
115 | var removed = 0; | |
|
116 | var tree_squares = area.squares.Where((square) => simulation.map.cells[(int)square.X][(int)square.Y].hasTree); | |
|
117 | var to_remove = -delta.deltaTrees.Value; | |
|
131 | if (delta.deltaTrees.Value < 0) | |
|
132 | { | |
|
133 | var squares = HasComponent<AreaComponent>(entity) ? GetComponent<AreaComponent>(entity).squares : this.all_squares; | |
|
134 | var removed = 0; | |
|
135 | var tree_squares = squares.Where((square) => simulation.map.cells[(int)square.X][(int)square.Y].hasTree); | |
|
136 | var to_remove = -delta.deltaTrees.Value; | |
|
118 | 137 | |
|
119 |
|
|
|
120 |
|
|
|
121 |
|
|
|
122 |
|
|
|
138 | //calculate the probability in order to get the expected number of removed trees | |
|
139 | var expected = to_remove; | |
|
140 | var trials = tree_squares.Count(); | |
|
141 | double probability = ((double)expected / (double)trials) / 12; | |
|
123 | 142 | |
|
124 |
|
|
|
125 | { | |
|
126 |
|
|
|
127 | if (cell.hasTree | |
|
128 |
|
|
|
129 | { | |
|
130 | cell.removeTree(); | |
|
131 | removed++; | |
|
132 | } | |
|
133 | if (removed >= to_remove) | |
|
134 | { | |
|
135 | // break; | |
|
136 | } | |
|
137 | } | |
|
138 | } | |
|
139 | } | |
|
140 | } | |
|
141 | this.ticksToSend = 0; | |
|
143 | foreach (var square in tree_squares) | |
|
144 | { | |
|
145 | var cell = simulation.map.cells[(int)square.X][(int)square.Y]; | |
|
146 | if (cell.hasTree | |
|
147 | && random_generator.NextDouble() < probability) | |
|
148 | { | |
|
149 | cell.removeTree(); | |
|
150 | removed++; | |
|
151 | } | |
|
152 | if (removed >= to_remove) | |
|
153 | { | |
|
154 | // break; | |
|
155 | } | |
|
156 | } | |
|
157 | Logging.Info(String.Format("Destroyed {0} trees, expected {1}, P(destroy)= {2}", removed, (expected / 12), probability)); | |
|
158 | } | |
|
159 | else | |
|
160 | { | |
|
161 | } | |
|
162 | } | |
|
142 | 163 | |
|
143 | simulation.contracts = new_contract_amount; | |
|
144 | simulation.enforcement = new_enforcement_amount; | |
|
164 | } | |
|
165 | } | |
|
166 | this.ticksToSend = 0; | |
|
145 | 167 | |
|
146 | } | |
|
168 | simulation.contracts = new_contract_amount; | |
|
169 | simulation.enforcement = new_enforcement_amount; | |
|
170 | ||
|
171 | } | |
|
147 | 172 | |
|
148 | 173 | } |
|
149 | 174 | } |
You need to be logged in to leave comments.
Login now