ALMaSS Hare ODDox  1.1
The hare model description following ODdox protocol
PLPotatoes.cpp
Go to the documentation of this file.
1 /*
2 *******************************************************************************************************
3 Copyright (c) 2017, Christopher John Topping, Aarhus University
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without modification, are permitted provided
7 that the following conditions are met:
8 
9 Redistributions of source code must retain the above copyright notice, this list of conditions and the
10 following disclaimer.
11 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
12 the following disclaimer in the documentation and/or other materials provided with the distribution.
13 
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
15 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
17 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
19 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 ********************************************************************************************************
23 */
38 //
39 // PLPotatoes.cpp
40 //
41 
42 
43 #include "../../Landscape/ls.h"
44 #include "../../Landscape/cropprogs/PLPotatoes.h"
45 
46 // Some things that are defined externally - in this case these variables allow
47 // scaling of the percentage application figures for insecticides, herbicides etc..
48 extern CfgBool cfg_pest_potatoes_on;
49 // check if below are needed
50 extern CfgFloat l_pest_insecticide_amount;
51 extern CfgInt cfg_POT_InsecticideDay;
52 extern CfgInt cfg_POT_InsecticideMonth;
53 extern CfgFloat cfg_pest_product_1_amount;
54 
55 
64 bool PLPotatoes::Do(Farm *a_farm, LE *a_field, FarmEvent *a_ev)
65 {
66  bool done = false; // The boolean value done indicates when we are totally finished with this plan (i.e. it is set to true).
67  int d1 = 0;
68  // Depending what event has occured jump to the correct bit of code
69  switch (a_ev->m_todo)
70  {
71  case pl_pot_start:
72  {
73  // pl_pot_start just sets up all the starting conditions and reference dates that are needed to start a pl_pot
74  PL_POT_FERTI_P1 = false;
75  PL_POT_FERTI_S1 = false;
76  PL_POT_STUBBLE_PLOUGH = false;
77  PL_POT_DID_STRIG1 = false;
78  PL_POT_DID_STRIG2 = false;
79  PL_POT_DID_STRIG3 = false;
80  PL_POT_HILL_DATE = 0;
81  PL_POT_DID_HILL = false;
82  PL_POT_DID_DESS = false;
83 
84  // Set up the date management stuff
85  // The next bit of code just allows for altering dates after harvest if it is necessary
86  // to allow for a crop which starts its management early.
87 
88  // 2 start and stop dates for all 'movable' events for this crop
89  int noDates = 2;
90  a_field->SetMDates(0, 0, g_date->DayInYear(25, 9)); // last possible day of harvest
91  a_field->SetMDates(1, 0, g_date->DayInYear(5, 10)); // end day of calcium application
92  a_field->SetMDates(0, 1, 0);
93  a_field->SetMDates(1, 1, g_date->DayInYear(5, 10));
94 
95  a_field->SetMConstants(0, 1);
96 
97  // Check the next crop for early start, unless it is a spring crop
98  // in which case we ASSUME that no checking is necessary!!!!
99  // So DO NOT implement a crop that runs over the year boundary (i.e. from spring to spring!), at least not without fixing this.
100 
101  //new if: do the check only for non-optimising farms and if year>0. (030713 - m_rotation used only in the hidden year, so I modified the condition from >7 to >0)
102  //optimising farms not used for now so most of related code is removed (but not in 'start' case)
103  if (!(a_farm->GetType() == tof_OptimisingFarm && g_date->GetYearNumber() > 0)) {
104 
105  if (a_ev->m_startday > g_date->DayInYear(1, 7)) {
106  if (a_field->GetMDates(0, 0) >= a_ev->m_startday)
107  {
108  g_msg->Warn(WARN_BUG, "PLPotatoes::Do(): ", "Harvest too late for the next crop to start!!!");
109  int almassnum = g_landscape_p->BackTranslateVegTypes(a_ev->m_next_tov);
110  g_msg->Warn("Next Crop ", (double)almassnum); // this causes exit
111  }
112  // Now fix any late finishing problems
113  for (int i = 0; i < noDates; i++) {
114  if (a_field->GetMDates(0, i) >= a_ev->m_startday) {
115  a_field->SetMDates(0, i, a_ev->m_startday - 1); //move the starting date
116  }
117  if (a_field->GetMDates(1, i) >= a_ev->m_startday) {
118  a_field->SetMConstants(i, 0); //change the default value of the MConst (=1) to 0 (necessary to correctly execute farm events in case the finishing date (MDate) was moved)
119  a_field->SetMDates(1, i, a_ev->m_startday - 1); //move the finishing date
120  }
121  }
122  }
123  // Now no operations can be timed after the start of the next crop.
124 
125  if (!a_ev->m_first_year) {
126  // Are we before July 1st?
127  d1 = g_date->OldDays() + g_date->DayInYear(1, 7);
128  if (g_date->Date() < d1) {
129  // Yes, too early. We assumme this is because the last crop was late
130  printf("Poly: %d\n", a_field->GetPoly());
131  g_msg->Warn(WARN_BUG, "PLPotatoes::Do(): ", "Crop start attempt between 1st Jan & 1st July");
132  int prev = g_landscape_p->BackTranslateVegTypes(a_field->GetOwner()->GetPreviousCrop(a_field->GetRotIndex()));
133  g_msg->Warn(WARN_BUG, "Previous Crop ", prev);
134  int almassnum = g_landscape_p->BackTranslateVegTypes(a_ev->m_next_tov);
135  g_msg->Warn("Next Crop ", (double)almassnum); // this causes exit
136  }
137  else {
138  d1 = g_date->OldDays() + m_first_date; // Add 365 for spring crop
139  if (g_date->Date() > d1) {
140  // Yes too late - should not happen - raise an error
141  g_msg->Warn(WARN_BUG, "PLPotatoes::Do(): ", "Crop start attempt after last possible start date");
142  g_msg->Warn(WARN_BUG, "Previous Crop ", "");
143  a_field->GetOwner()->GetPreviousCrop(a_field->GetRotIndex());
144  int almassnum = g_landscape_p->BackTranslateVegTypes(a_ev->m_next_tov);
145  g_msg->Warn("Next Crop ", (double)almassnum); // this causes exit
146  }
147  }
148  }
149  else {
150  // Is the first year
151  // Some special code to cope with that first start-up year in ALMaSS - ignore for all practical purposes
152  // Code for first spring treatment used
153  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(20, 3), pl_pot_spring_harrow, false, a_farm, a_field);
154  break;
155  }
156  }//if
157 
158  // End single block date checking code. Please see next line comment as well.
159  // Reinit d1 to first possible starting date.
160  d1 = g_date->OldDays() + g_date->DayInYear(20, 7);
161  // OK, let's go.
162  // Here we queue up the first event - this differs depending on whether we have a
163  // stock or arable farmer
164  if (a_farm->IsStockFarmer()) { // StockFarmer
165  SimpleEvent_(d1, pl_pot_ferti_s1, false, a_farm, a_field);
166  }
167  else SimpleEvent_(d1, pl_pot_ferti_p1, false, a_farm, a_field);
168  }
169  break;
170 
171  // This is the first real farm operation
172  case pl_pot_ferti_p1:
173  // In total 10% of arable farmers do slurry in the autumn, either before stubble plough/harrow or later before autumn plough/cultivation
174  // We therefore assume that half of them (5%) do it now
175  if (a_ev->m_lock || a_farm->DoIt(5))
176  {
177  if (!a_farm->FP_Slurry(a_field, 0.0, g_date->DayInYear(5, 11) - g_date->DayInYear())) {
178  // If we don't suceed on the first try, then try and try again (until 20/8 when we will suceed)
179  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_p1, true, a_farm, a_field);
180  break;
181  }
182  else
183  {
184  //Rest of farmers do slurry before autumn plough/stubble cultivation so we need to remeber who already did it
185  PL_POT_FERTI_P1 = true;
186  }
187  }
188  // Queue up the next event -in this case stubble ploughing
189  SimpleEvent_(g_date->Date() + 1, pl_pot_stubble_plough, false, a_farm, a_field);
190  break;
191  case pl_pot_ferti_s1:
192  // In total 40% of stock farmers do slurry in the autumn, either before stubble plough/harrow or later before autumn plough/cultivation
193  // We therefore assume that half of them (40%) do it now
194  if (a_ev->m_lock || a_farm->DoIt(40))
195  {
196  if (!a_farm->FA_Slurry(a_field, 0.0, g_date->DayInYear(5, 11) - g_date->DayInYear())) {
197  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_s1, true, a_farm, a_field);
198  break;
199  }
200  else
201  {
202  //Rest of farmers do slurry before autumn plough/stubble cultivation so we need to remeber who already did it
203  PL_POT_FERTI_S1 = true;
204  }
205  }
206  // Queue up the next event -in this case stubble ploughing
207  SimpleEvent_(g_date->Date() + 1, pl_pot_stubble_plough, false, a_farm, a_field);
208  break;
210  // 65% will do stubble plough, but rest will get away with non-inversion cultivation
211  if (a_ev->m_lock || a_farm->DoIt(65))
212  {
213  if (!a_farm->StubblePlough(a_field, 0.0, g_date->DayInYear(5, 11) - g_date->DayInYear())) {
214  SimpleEvent_(g_date->Date() + 1, pl_pot_stubble_plough, true, a_farm, a_field);
215  break;
216  }
217  else
218  {
219  // 50% of farmers will do this, but the other 50% won't so we need to remember whether we are in one or the other group
220  PL_POT_STUBBLE_PLOUGH = true;
221  // Queue up the next event
222  SimpleEvent_(g_date->Date() + 1, pl_pot_autumn_harrow1, false, a_farm, a_field);
223  break;
224  }
225  }
226  SimpleEvent_(g_date->Date() + 1, pl_pot_stubble_harrow, false, a_farm, a_field);
227  break;
229  if (!a_farm->AutumnHarrow(a_field, 0.0, g_date->DayInYear(5, 11) - g_date->DayInYear())) {
230  SimpleEvent_(g_date->Date() + 1, pl_pot_autumn_harrow1, true, a_farm, a_field);
231  break;
232  }
233  SimpleEvent_(g_date->Date() + 2, pl_pot_autumn_harrow2, false, a_farm, a_field);
234  break;
236  if (a_ev->m_lock || a_farm->DoIt(40))
237  {
238  if (!a_farm->AutumnHarrow(a_field, 0.0, g_date->Date() + 7 - g_date->DayInYear())) {
239  SimpleEvent_(g_date->Date() + 1, pl_pot_autumn_harrow2, true, a_farm, a_field);
240  break;
241  }
242  }
243  d1 = g_date->Date() + 1;
244  if (d1 < g_date->OldDays() + g_date->DayInYear(10, 9)) {
245  d1 = g_date->OldDays() + g_date->DayInYear(10, 9);
246  }
247  if (a_farm->IsStockFarmer()) //Stock Farmer
248  {
249  SimpleEvent_(d1, pl_pot_ferti_s2, false, a_farm, a_field);
250  }
251  else SimpleEvent_(d1, pl_pot_ferti_p2, false, a_farm, a_field);
252  break;
254  if (!a_farm->StubbleHarrowing(a_field, 0.0, g_date->DayInYear(10, 11) - g_date->DayInYear())) {
255  SimpleEvent_(g_date->Date() + 1, pl_pot_stubble_harrow, true, a_farm, a_field);
256  break;
257  }
258  d1 = g_date->Date() + 1;
259  if (d1 < g_date->OldDays() + g_date->DayInYear(10, 9)) {
260  d1 = g_date->OldDays() + g_date->DayInYear(10, 9);
261  }
262  if (a_farm->IsStockFarmer()) //Stock Farmer
263  {
264  SimpleEvent_(d1, pl_pot_ferti_s2, false, a_farm, a_field);
265  }
266  else SimpleEvent_(d1, pl_pot_ferti_p2, false, a_farm, a_field);
267  break;
268  case pl_pot_ferti_p2:
269  // In total 10% of arable farmers do slurry in the autumn, either before stubble plough/harrow or later before autumn plough/cultivation
270  // We therefore assume that half of them (5%) do it now (if haven't done before)
271  if ((a_ev->m_lock || a_farm->DoIt(static_cast<int>((5.0 / 95.0) * 100))) && (PL_POT_FERTI_P1 == false))
272  {
273  if (!a_farm->FP_Slurry(a_field, 0.0, g_date->DayInYear(15, 11) - g_date->DayInYear())) {
274  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_p2, true, a_farm, a_field);
275  break;
276  }
277  }
278  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_p3, false, a_farm, a_field);
279  break;
280  case pl_pot_ferti_s2:
281  // In total 80% of stock farmers do slurry in the autumn, either before stubble plough/harrow or later before autumn plough/cultivation
282  // We therefore assume that half of them (40%) do it now (if haven't done before)
283  if ((a_ev->m_lock || a_farm->DoIt(static_cast<int>((40.0 / 60.0) * 100))) && (PL_POT_FERTI_S1 == false))
284  {
285  if (!a_farm->FA_Slurry(a_field, 0.0, g_date->DayInYear(15, 11) - g_date->DayInYear())) {
286  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_s2, true, a_farm, a_field);
287  break;
288  }
289  }
290  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_s3, false, a_farm, a_field);
291  break;
292  case pl_pot_ferti_p3:
293  if (a_ev->m_lock || a_farm->DoIt(7))
294  {
295  if (!a_farm->FP_NPKS(a_field, 0.0, g_date->DayInYear(15, 11) - g_date->DayInYear())) {
296  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_p3, true, a_farm, a_field);
297  break;
298  }
299  }
300  SimpleEvent_(g_date->Date() + 1, pl_pot_winter_plough, false, a_farm, a_field);
301  break;
302  case pl_pot_ferti_s3:
303  if (a_ev->m_lock || a_farm->DoIt(7))
304  {
305  if (!a_farm->FA_NPKS(a_field, 0.0, g_date->DayInYear(15, 11) - g_date->DayInYear())) {
306  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_s3, true, a_farm, a_field);
307  break;
308  }
309  }
310  SimpleEvent_(g_date->Date() + 1, pl_pot_winter_plough, false, a_farm, a_field);
311  break;
313  if (!a_farm->WinterPlough(a_field, 0.0, g_date->DayInYear(15, 11) - g_date->DayInYear())) {
314  SimpleEvent_(g_date->Date() + 1, pl_pot_winter_plough, true, a_farm, a_field);
315  break;
316  }
317 
318  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(20, 3) + 365, pl_pot_spring_harrow, false, a_farm, a_field);
319  break;
321  if ((a_ev->m_lock) || a_farm->DoIt(98))
322  {
323  if (!a_farm->SpringHarrow(a_field, 0.0, g_date->DayInYear(10, 4) - g_date->DayInYear())) {
324  SimpleEvent_(g_date->Date() + 1, pl_pot_spring_harrow, true, a_farm, a_field);
325  break;
326  }
327  }
328  d1 = g_date->Date() + 1;
329  if (d1 < g_date->OldDays() + g_date->DayInYear(1, 4)) {
330  d1 = g_date->OldDays() + g_date->DayInYear(1, 4);
331  }
332  if (a_farm->IsStockFarmer()) //Stock Farmer
333  {
334  SimpleEvent_(d1, pl_pot_ferti_s4, false, a_farm, a_field);
335  }
336  else SimpleEvent_(d1, pl_pot_ferti_p4, false, a_farm, a_field);
337  break;
338  case pl_pot_ferti_p4:
339  if (a_ev->m_lock || a_farm->DoIt(80))
340  {
341  if (!a_farm->FP_AmmoniumSulphate(a_field, 0.0, g_date->DayInYear(20, 4) - g_date->DayInYear())) {
342  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_p4, true, a_farm, a_field);
343  break;
344  }
345  }
346  SimpleEvent_(g_date->Date() + 1, pl_pot_spring_harrow2, false, a_farm, a_field);
347  break;
348  case pl_pot_ferti_s4:
349  if (a_ev->m_lock || a_farm->DoIt(80))
350  {
351  if (!a_farm->FA_AmmoniumSulphate(a_field, 0.0, g_date->DayInYear(20, 4) - g_date->DayInYear())) {
352  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_s4, true, a_farm, a_field);
353  break;
354  }
355  }
356  SimpleEvent_(g_date->Date() + 1, pl_pot_spring_harrow2, false, a_farm, a_field);
357  break;
359  if ((a_ev->m_lock) || a_farm->DoIt(22))
360  {
361  if (!a_farm->SpringHarrow(a_field, 0.0, g_date->DayInYear(20, 4) - g_date->DayInYear())) {
362  SimpleEvent_(g_date->Date() + 1, pl_pot_spring_harrow2, true, a_farm, a_field);
363  break;
364  }
365  }
366  d1 = g_date->Date() + 1;
367  if (d1 < g_date->OldDays() + g_date->DayInYear(5, 4)) {
368  d1 = g_date->OldDays() + g_date->DayInYear(5, 4);
369  }
370  if (a_farm->IsStockFarmer()) //Stock Farmer
371  {
372  SimpleEvent_(d1, pl_pot_ferti_s5, false, a_farm, a_field);
373  }
374  else SimpleEvent_(d1, pl_pot_ferti_p5, false, a_farm, a_field);
375  break;
376  case pl_pot_ferti_p5:
377  if (a_ev->m_lock || a_farm->DoIt(70))
378  {
379  if (!a_farm->FP_PK(a_field, 0.0, g_date->DayInYear(25, 4) - g_date->DayInYear())) {
380  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_p5, true, a_farm, a_field);
381  break;
382  }
383  }
384  SimpleEvent_(g_date->Date() + 1, pl_pot_spring_plough, false, a_farm, a_field);
385  break;
386  case pl_pot_ferti_s5:
387  if (a_ev->m_lock || a_farm->DoIt(70))
388  {
389  if (!a_farm->FA_PK(a_field, 0.0, g_date->DayInYear(25, 4) - g_date->DayInYear())) {
390  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_s5, true, a_farm, a_field);
391  break;
392  }
393  }
394  SimpleEvent_(g_date->Date() + 1, pl_pot_spring_plough, false, a_farm, a_field);
395  break;
397  if (a_ev->m_lock || a_farm->DoIt(92))
398  {
399  if (!a_farm->SpringPlough(a_field, 0.0, g_date->DayInYear(25, 4) - g_date->DayInYear())) {
400  SimpleEvent_(g_date->Date() + 1, pl_pot_spring_plough, true, a_farm, a_field);
401  break;
402  }
403  }
404  d1 = g_date->Date() + 7;
405  if (d1 < g_date->OldDays() + g_date->DayInYear(20, 4)) {
406  d1 = g_date->OldDays() + g_date->DayInYear(20, 4);
407  }
408  SimpleEvent_(d1, pl_pot_bed_forming, false, a_farm, a_field);
409  break;
410  case pl_pot_bed_forming:
411  if (!a_farm->PreseedingCultivator(a_field, 0.0, g_date->DayInYear(5, 5) - g_date->DayInYear())) {
412  SimpleEvent_(g_date->Date() + 1, pl_pot_bed_forming, true, a_farm, a_field);
413  break;
414  }
415  SimpleEvent_(g_date->Date(), pl_pot_spring_planting, false, a_farm, a_field);
416  break;
418  if (!a_farm->SpringSow(a_field, 0.0, g_date->DayInYear(5, 5) - g_date->DayInYear())) {
419  SimpleEvent_(g_date->Date() + 1, pl_pot_spring_planting, true, a_farm, a_field);
420  break;
421  }
422  // Fork of events
423  SimpleEvent_(g_date->Date() + 2, pl_pot_hilling1, false, a_farm, a_field); // Strigling followed by hilling and herbicides
424  if (a_farm->IsStockFarmer()) //Stock Farmer
425  {
426  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_s6, false, a_farm, a_field); // N before emergence
427  }
428  else SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_p6, false, a_farm, a_field);
429  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(10, 6), pl_pot_fungicide1, false, a_farm, a_field); // Fungicide treat = MAIN TREAT
430  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(10, 6), pl_pot_insecticide, false, a_farm, a_field); // Insecticide treat
431  break;
432  case pl_pot_hilling1:
433  if (a_field->GetGreenBiomass() <= 0)
434  {
435  if (a_ev->m_lock || a_farm->DoIt(90))
436  {
437  if (!a_farm->HillingUp(a_field, 0.0, g_date->DayInYear(20, 5) - g_date->DayInYear())) {
438  SimpleEvent_(g_date->Date() + 1, pl_pot_hilling1, true, a_farm, a_field);
439  break;
440  }
441  // 90% of farmers remove weeds with strigling (and hilling), the rest will do herbicide
442  PL_POT_DID_STRIG1 = true;
443  // Queue up the second strigling_hill event after 7 days
444  SimpleEvent_(g_date->Date() + 5, pl_pot_hilling2, false, a_farm, a_field);
445  break;
446  }
447  else {
448  SimpleEvent_(g_date->Date(), pl_pot_herbicide1, false, a_farm, a_field);
449  break;
450  }
451  }
452  SimpleEvent_(g_date->Date() + 1, pl_pot_hilling4, false, a_farm, a_field);
453  break;
454  case pl_pot_hilling2:
455  if (a_field->GetGreenBiomass() <= 0)
456  {
457  if (a_ev->m_lock || (a_farm->DoIt(81) && PL_POT_DID_STRIG1)) // which gives 73% of all farmers
458  {
459  if (!a_farm->HillingUp(a_field, 0.0, g_date->DayInYear(25, 5) - g_date->DayInYear())) {
460  SimpleEvent_(g_date->Date() + 1, pl_pot_hilling2, true, a_farm, a_field);
461  break;
462  }
463  // 81% of farmers do strigling_hill second time, the rest will end up with herbicide
464  PL_POT_DID_STRIG2 = true;
465  // Queue up the third strigling_hill event after 7 days
466  SimpleEvent_(g_date->Date() + 5, pl_pot_hilling3, false, a_farm, a_field);
467  break;
468  }
469  else {
470  SimpleEvent_(g_date->Date(), pl_pot_herbicide1, false, a_farm, a_field);
471  break;
472  }
473  }
474  SimpleEvent_(g_date->Date() + 1, pl_pot_hilling4, false, a_farm, a_field);
475  break;
476  case pl_pot_hilling3:
477  if (a_field->GetGreenBiomass() <= 0)
478  {
479  if (a_ev->m_lock || (a_farm->DoIt(73) && PL_POT_DID_STRIG2)) // which gives 53% of all farmers
480  {
481  if (!a_farm->HillingUp(a_field, 0.0, g_date->DayInYear(31, 5) - g_date->DayInYear())) {
482  SimpleEvent_(g_date->Date() + 1, pl_pot_hilling3, true, a_farm, a_field);
483  break;
484  }
485  // 73% of farmers do strigling_hill third time, the rest will end up with herbicide.
486  PL_POT_DID_STRIG3 = true;
487  }
488  else {
489  SimpleEvent_(g_date->Date()+3, pl_pot_herbicide1, false, a_farm, a_field);
490  break;
491  }
492  }
493  SimpleEvent_(g_date->Date() + 1, pl_pot_hilling4, false, a_farm, a_field);
494  break;
495  case pl_pot_herbicide1:
496  if (a_field->GetGreenBiomass() <= 0)
497  {
498  if (a_ev->m_lock || a_farm->DoIt(93))
499  {
500  if (!a_farm->HerbicideTreat(a_field, 0.0, g_date->DayInYear(5, 6) - g_date->DayInYear())) {
501  SimpleEvent_(g_date->Date() + 1, pl_pot_herbicide1, true, a_farm, a_field);
502  break;
503  }
504  }
505  SimpleEvent_(g_date->Date() + 1, pl_pot_hilling4, false, a_farm, a_field);
506  break;
507  }
508  SimpleEvent_(g_date->Date() + 1, pl_pot_hilling4, false, a_farm, a_field);
509  break;
510  case pl_pot_hilling4:
511  if (a_ev->m_lock || a_farm->DoIt(38))
512  {
513  if (a_field->GetGreenBiomass() <= 0) {
514  SimpleEvent_(g_date->Date() + 1, pl_pot_hilling4, true, a_farm, a_field);
515  }
516  else
517  {
518  if (!a_farm->HillingUp(a_field, 0.0, g_date->DayInYear(10, 6) - g_date->DayInYear())) {
519  SimpleEvent_(g_date->Date() + 1, pl_pot_hilling4, true, a_farm, a_field);
520  break;
521  }
522  PL_POT_HILL_DATE = g_date->Date();
523  SimpleEvent_(g_date->Date() + 7, pl_pot_hilling5, false, a_farm, a_field);
524  break;
525  }
526  }
527  SimpleEvent_(g_date->Date() + 3, pl_pot_herbicide2, false, a_farm, a_field);
528  break;
529  case pl_pot_hilling5:
530  if (!a_farm->HillingUp(a_field, 0.0, g_date->DayInYear(15, 6) - g_date->DayInYear())) {
531  SimpleEvent_(g_date->Date() + 1, pl_pot_hilling5, true, a_farm, a_field);
532  break;
533  }
534  PL_POT_HILL_DATE = g_date->Date();
535  SimpleEvent_(g_date->Date() + 7, pl_pot_hilling6, false, a_farm, a_field);
536  break;
537  case pl_pot_hilling6:
538  if (!a_farm->HillingUp(a_field, 0.0, g_date->DayInYear(20, 6) - g_date->DayInYear())) {
539  SimpleEvent_(g_date->Date() + 1, pl_pot_hilling6, true, a_farm, a_field);
540  break;
541  }
542  PL_POT_HILL_DATE = g_date->Date();
543  PL_POT_DID_HILL = true;
544 
545  SimpleEvent_(g_date->Date() + 7, pl_pot_herbicide2, false, a_farm, a_field);
546  break;
547  case pl_pot_herbicide2:
548  if (a_ev->m_lock || a_farm->DoIt(40))
549  {
550  if (!a_farm->HerbicideTreat(a_field, 0.0, g_date->DayInYear(30, 6) - g_date->DayInYear())) {
551  SimpleEvent_(g_date->Date() + 1, pl_pot_herbicide2, true, a_farm, a_field);
552  break;
553  }
554  }
555  // End of thread
556  break;
557  case pl_pot_ferti_s6:
558  if (a_field->GetGreenBiomass() <= 0)
559  {
560  if (a_ev->m_lock || a_farm->DoIt(80))
561  {
562  if (!a_farm->FA_AmmoniumSulphate(a_field, 0.0, g_date->DayInYear(31, 5) - g_date->DayInYear())) {
563  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_s6, true, a_farm, a_field);
564  break;
565  }
566  }
567  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(15, 6), pl_pot_ferti_s7, false, a_farm, a_field);
568  break;
569  }
570  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(15, 6), pl_pot_ferti_s7, false, a_farm, a_field);
571  break;
572 
573  case pl_pot_ferti_p6:
574  if (a_field->GetGreenBiomass() <= 0)
575  {
576  if (a_ev->m_lock || a_farm->DoIt(80))
577  {
578  if (!a_farm->FP_AmmoniumSulphate(a_field, 0.0, g_date->DayInYear(31, 5) - g_date->DayInYear())) {
579  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_p6, true, a_farm, a_field);
580  break;
581  }
582  }
583  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(15, 6), pl_pot_ferti_p7, false, a_farm, a_field);
584  break;
585  }
586  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(15, 6), pl_pot_ferti_p7, false, a_farm, a_field);
587  break;
588  case pl_pot_ferti_s7:
589  if (a_ev->m_lock || a_farm->DoIt(53))
590  {
591  if (PL_POT_HILL_DATE >= g_date->Date() - 2){ // Should by at least 3 days after hilling
592  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_s7, false, a_farm, a_field); }
593  else
594  {
595  if (!a_farm->FA_ManganeseSulphate(a_field, 0.0, g_date->DayInYear(15, 7) - g_date->DayInYear())) {
596  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_s7, true, a_farm, a_field);
597  break;
598  }
599  }
600  }
601  // End of thread
602  break;
603  case pl_pot_ferti_p7:
604  if (a_ev->m_lock || a_farm->DoIt(53))
605  {
606  if (PL_POT_HILL_DATE >= g_date->Date() - 2) { // Should by at least 3 days after hilling
607  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_p7, false, a_farm, a_field);
608  }
609  else
610  {
611  if (!a_farm->FP_ManganeseSulphate(a_field, 0.0, g_date->DayInYear(15, 7) - g_date->DayInYear())) {
612  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_p7, true, a_farm, a_field);
613  break;
614  }
615  }
616  }
617  // End of thread
618  break;
619  case pl_pot_fungicide1:
620  // Here comes the fungicide thread = MAIN THREAD
621  if (PL_POT_HILL_DATE >= g_date->Date() - 2) { // Should by at least 3 days after hilling
622  SimpleEvent_(g_date->Date() + 1, pl_pot_fungicide1, true, a_farm, a_field);
623  }
624  else
625  {
626  if (a_ev->m_lock || a_farm->DoIt(78))
627  {
628  if (!a_farm->FungicideTreat(a_field, 0.0, g_date->DayInYear(31, 7) - g_date->DayInYear())) {
629  SimpleEvent_(g_date->Date() + 1, pl_pot_fungicide1, true, a_farm, a_field);
630  break;
631  }
632  }
633  SimpleEvent_(g_date->Date() + 10, pl_pot_fungicide2, false, a_farm, a_field);
634  break;
635  }
636  break;
637  case pl_pot_fungicide2:
638  if (a_ev->m_lock || a_farm->DoIt(63))
639  {
640  if (!a_farm->FungicideTreat(a_field, 0.0, g_date->DayInYear(10, 8) - g_date->DayInYear())) {
641  SimpleEvent_(g_date->Date() + 1, pl_pot_fungicide2, true, a_farm, a_field);
642  break;
643  }
644  }
645  SimpleEvent_(g_date->Date() + 10, pl_pot_fungicide3, false, a_farm, a_field);
646  break;
647  case pl_pot_fungicide3:
648  if (a_ev->m_lock || a_farm->DoIt(63))
649  {
650  if (!a_farm->FungicideTreat(a_field, 0.0, g_date->DayInYear(20, 8) - g_date->DayInYear())) {
651  SimpleEvent_(g_date->Date() + 1, pl_pot_fungicide3, true, a_farm, a_field);
652  break;
653  }
654  }
655  SimpleEvent_(g_date->Date() + 10, pl_pot_fungicide4, false, a_farm, a_field);
656  break;
657  case pl_pot_fungicide4:
658  if (a_ev->m_lock || a_farm->DoIt(38))
659  {
660  if (!a_farm->FungicideTreat(a_field, 0.0, g_date->DayInYear(20, 8) - g_date->DayInYear())) {
661  SimpleEvent_(g_date->Date() + 1, pl_pot_fungicide4, true, a_farm, a_field);
662  break;
663  }
664  }
665  SimpleEvent_(g_date->OldDays() + g_date->DayInYear(25, 8), pl_pot_dessication1, false, a_farm, a_field);
666  break;
667  case pl_pot_insecticide:
668  if (a_ev->m_lock || a_farm->DoIt(75))
669  {
670  if (PL_POT_HILL_DATE >= g_date->Date() - 2) {
671  SimpleEvent_(g_date->Date() + 1, pl_pot_insecticide, false, a_farm, a_field);
672  }
673  else
674  {
675  // here we check wheter we are using ERA pesticide or not
676  if (!cfg_pest_potatoes_on.value() ||
677  !g_landscape_p->SupplyShouldSpray()) // Not using pesticide spray
678  {
679  if (!a_farm->InsecticideTreat(a_field, 0.0, g_date->DayInYear(20, 7) - g_date->DayInYear())) {
680  SimpleEvent_(g_date->Date() + 1, pl_pot_insecticide, true, a_farm, a_field);
681  break;
682  }
683  }
684  else {
685  a_farm->ProductApplication(a_field, 0.0, 0, cfg_pest_product_1_amount.value(), ppp_1);
686  }
687  }
688  }
689  // End of thread
690  break;
691  case pl_pot_dessication1:
692  // Here the MAIN thread continues
693  // This is the desiccation thread with glyphosate or diquat
694  if (a_ev->m_lock || a_farm->DoIt(35))
695  {
696  if (!a_farm->HerbicideTreat(a_field, 0.0, g_date->DayInYear(10, 9) - g_date->DayInYear())) {
697  SimpleEvent_(g_date->Date() + 1, pl_pot_dessication1, true, a_farm, a_field);
698  break;
699  }
700  PL_POT_DID_DESS = true;
701  }
702  SimpleEvent_(g_date->Date() + 7, pl_pot_dessication2, false, a_farm, a_field);
703  break;
704  case pl_pot_dessication2:
705  if (a_ev->m_lock || (a_farm->DoIt(17) && PL_POT_DID_DESS)) //which is 6% of all farmers
706  {
707  if (!a_farm->HerbicideTreat(a_field, 0.0, g_date->DayInYear(15, 9) - g_date->DayInYear())) {
708  SimpleEvent_(g_date->Date() + 1, pl_pot_dessication2, true, a_farm, a_field);
709  break;
710  }
711  }
712  SimpleEvent_(g_date->Date() + 14, pl_pot_harvest, false, a_farm, a_field);
713  break;
714  case pl_pot_harvest:
715  // We don't move harvest days
716  if (!a_farm->Harvest(a_field, 0.0, a_field->GetMDates(0, 0) - g_date->DayInYear())) {
717  SimpleEvent_(g_date->Date() + 1, pl_pot_harvest, true, a_farm, a_field);
718  break;
719  }
720  if (a_farm->IsStockFarmer()) //Stock Farmer
721  {
722  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_s8, false, a_farm, a_field);
723  }
724  else SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_p8, false, a_farm, a_field);
725  break;
726  case pl_pot_ferti_p8:
727  if (a_ev->m_lock || a_farm->DoIt(23))
728  {
729  if (a_field->GetMConstants(3) == 0) {
730  if (!a_farm->FP_Calcium(a_field, 0.0, -1)) { // raise an error
731  g_msg->Warn(WARN_BUG, "PLPotatoes::Do(): failure in 'FP_Calcium' execution", "");
732  exit(1);
733  }
734  }
735  else {
736  if (!a_farm->FP_Calcium(a_field, 0.0, a_field->GetMDates(1, 0) - g_date->DayInYear())) {
737  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_p8, true, a_farm, a_field);
738  break;
739  }
740  }
741  }
742  done = true;
743  // So we are done, and somwhere else the farmer will queue up the start event of the next crop
744  // END of MAIN THREAD
745  break;
746  case pl_pot_ferti_s8:
747  if (a_ev->m_lock || a_farm->DoIt(23))
748  {
749  if (a_field->GetMConstants(3) == 0) {
750  if (!a_farm->FA_Calcium(a_field, 0.0, -1)) { // raise an error
751  g_msg->Warn(WARN_BUG, "PLPotatoes::Do(): failure in 'FA_Calcium' execution", "");
752  exit(1);
753  }
754  }
755  else {
756  if (!a_farm->FA_Calcium(a_field, 0.0, a_field->GetMDates(1, 0) - g_date->DayInYear())) {
757  SimpleEvent_(g_date->Date() + 1, pl_pot_ferti_s8, true, a_farm, a_field);
758  break;
759  }
760  }
761  }
762  done = true;
763  // So we are done, and somwhere else the farmer will queue up the start event of the next crop
764  // END of MAIN THREAD
765  break;
766  default:
767  g_msg->Warn(WARN_BUG, "PLPotatoes::Do(): "
768  "Unknown event type! ", "");
769  exit(1);
770  }
771  return done;
772 }
pl_pot_herbicide1
Definition: PLPotatoes.h:69
pl_pot_ferti_s6
Definition: PLPotatoes.h:75
Farm::IsStockFarmer
bool IsStockFarmer(void)
Definition: farm.h:905
pl_pot_fungicide2
Definition: PLPotatoes.h:79
FarmEvent::m_lock
bool m_lock
Definition: farm.h:465
pl_pot_hilling6
Definition: PLPotatoes.h:72
Landscape::SupplyShouldSpray
bool SupplyShouldSpray()
Definition: Landscape.h:357
PLPotatoes::Do
virtual bool Do(Farm *a_farm, LE *a_field, FarmEvent *a_ev)
The one and only method for a crop management plan. All farm actions go through here.
Definition: PLPotatoes.cpp:64
FarmEvent
A struct to hold the information required to trigger a farm event.
Definition: farm.h:463
Farm::DoIt
bool DoIt(double a_probability)
Return chance out of 0 to 100.
Definition: farm.cpp:800
FarmEvent::m_first_year
bool m_first_year
Definition: farm.h:467
tof_OptimisingFarm
Definition: farm.h:273
PL_POT_DID_HILL
#define PL_POT_DID_HILL
Definition: PLPotatoes.h:35
cfg_POT_InsecticideMonth
CfgInt cfg_POT_InsecticideMonth
pl_pot_hilling2
Definition: PLPotatoes.h:67
Landscape::BackTranslateVegTypes
int BackTranslateVegTypes(TTypesOfVegetation VegReference)
Definition: Landscape.h:1669
pl_pot_dessication1
Definition: PLPotatoes.h:83
Farm::GetType
TTypesOfFarm GetType(void)
Definition: farm.h:901
pl_pot_ferti_s5
Definition: PLPotatoes.h:62
pl_pot_harvest
Definition: PLPotatoes.h:85
Crop::m_first_date
int m_first_date
Definition: farm.h:540
FarmEvent::m_startday
int m_startday
Definition: farm.h:466
cfg_pest_product_1_amount
CfgFloat cfg_pest_product_1_amount
PL_POT_DID_DESS
#define PL_POT_DID_DESS
Definition: PLPotatoes.h:36
pl_pot_bed_forming
Definition: PLPotatoes.h:64
pl_pot_autumn_harrow1
Definition: PLPotatoes.h:49
pl_pot_ferti_s4
Definition: PLPotatoes.h:59
PL_POT_STUBBLE_PLOUGH
#define PL_POT_STUBBLE_PLOUGH
Definition: PLPotatoes.h:30
pl_pot_ferti_p8
Definition: PLPotatoes.h:86
pl_pot_ferti_p3
Definition: PLPotatoes.h:54
cfg_pest_potatoes_on
CfgBool cfg_pest_potatoes_on
l_pest_insecticide_amount
CfgFloat l_pest_insecticide_amount
pl_pot_spring_plough
Definition: PLPotatoes.h:63
pl_pot_ferti_s7
Definition: PLPotatoes.h:77
PL_POT_HILL_DATE
#define PL_POT_HILL_DATE
Definition: PLPotatoes.h:34
pl_pot_autumn_harrow2
Definition: PLPotatoes.h:50
pl_pot_stubble_harrow
Definition: PLPotatoes.h:51
pl_pot_ferti_p2
Definition: PLPotatoes.h:52
pl_pot_fungicide1
Definition: PLPotatoes.h:78
FarmEvent::m_next_tov
TTypesOfVegetation m_next_tov
Definition: farm.h:471
pl_pot_fungicide4
Definition: PLPotatoes.h:81
cfg_POT_InsecticideDay
CfgInt cfg_POT_InsecticideDay
pl_pot_ferti_p7
Definition: PLPotatoes.h:76
FarmEvent::m_todo
int m_todo
Definition: farm.h:469
pl_pot_ferti_s1
Definition: PLPotatoes.h:46
pl_pot_start
Definition: PLPotatoes.h:44
pl_pot_hilling1
Definition: PLPotatoes.h:66
pl_pot_insecticide
Definition: PLPotatoes.h:82
pl_pot_herbicide2
Definition: PLPotatoes.h:73
Farm::FP_Slurry
virtual bool FP_Slurry(LE *a_field, double a_user, int a_days)
Apply slurry to a_field owned by an arable farmer.
Definition: farmfuncs.cpp:701
ppp_1
Definition: farm.h:422
pl_pot_ferti_s8
Definition: PLPotatoes.h:87
pl_pot_ferti_p5
Definition: PLPotatoes.h:61
PL_POT_DID_STRIG2
#define PL_POT_DID_STRIG2
Definition: PLPotatoes.h:32
pl_pot_spring_harrow
Definition: PLPotatoes.h:57
pl_pot_hilling5
Definition: PLPotatoes.h:71
Farm
The base class for all farm types.
Definition: farm.h:767
PL_POT_FERTI_S1
#define PL_POT_FERTI_S1
Definition: PLPotatoes.h:29
PL_POT_DID_STRIG1
#define PL_POT_DID_STRIG1
Definition: PLPotatoes.h:31
pl_pot_spring_planting
Definition: PLPotatoes.h:65
pl_pot_stubble_plough
Definition: PLPotatoes.h:48
pl_pot_ferti_p1
Definition: PLPotatoes.h:47
pl_pot_fungicide3
Definition: PLPotatoes.h:80
pl_pot_winter_plough
Definition: PLPotatoes.h:56
pl_pot_ferti_p4
Definition: PLPotatoes.h:58
pl_pot_ferti_s3
Definition: PLPotatoes.h:55
pl_pot_ferti_p6
Definition: PLPotatoes.h:74
pl_pot_hilling3
Definition: PLPotatoes.h:68
pl_pot_spring_harrow2
Definition: PLPotatoes.h:60
pl_pot_ferti_s2
Definition: PLPotatoes.h:53
PL_POT_DID_STRIG3
#define PL_POT_DID_STRIG3
Definition: PLPotatoes.h:33
pl_pot_hilling4
Definition: PLPotatoes.h:70
PL_POT_FERTI_P1
#define PL_POT_FERTI_P1
A flag used to indicate autumn ploughing status.
Definition: PLPotatoes.h:28
g_landscape_p
Landscape * g_landscape_p
Definition: Landscape.cpp:258
Crop::SimpleEvent_
void SimpleEvent_(long a_date, int a_todo, bool a_lock, Farm *a_farm, LE *a_field)
Adds an event to this crop management without relying on member variables.
Definition: farm.cpp:312
pl_pot_dessication2
Definition: PLPotatoes.h:84