14 #include "../ai_threads.h" |
14 #include "../ai_threads.h" |
15 |
15 |
16 void AIObject::SetDoCommandDelay(uint ticks) |
16 void AIObject::SetDoCommandDelay(uint ticks) |
17 { |
17 { |
18 assert(ticks > 0); |
18 assert(ticks > 0); |
19 AIObject::GetDoCommandStruct(_current_player)->delay = ticks; |
19 GetDoCommandStruct(_current_player)->delay = ticks; |
20 } |
20 } |
21 |
21 |
22 uint AIObject::GetDoCommandDelay() |
22 uint AIObject::GetDoCommandDelay() |
23 { |
23 { |
24 return AIObject::GetDoCommandStruct(_current_player)->delay; |
24 return GetDoCommandStruct(_current_player)->delay; |
25 } |
25 } |
26 |
26 |
27 void AIObject::SetDoCommandMode(AIModeProc *proc, AIObject *instance) |
27 void AIObject::SetDoCommandMode(AIModeProc *proc, AIObject *instance) |
28 { |
28 { |
29 AIObject::GetDoCommandStruct(_current_player)->mode = proc; |
29 GetDoCommandStruct(_current_player)->mode = proc; |
30 AIObject::GetDoCommandStruct(_current_player)->mode_instance = instance; |
30 GetDoCommandStruct(_current_player)->mode_instance = instance; |
31 } |
31 } |
32 |
32 |
33 AIModeProc *AIObject::GetDoCommandMode() |
33 AIModeProc *AIObject::GetDoCommandMode() |
34 { |
34 { |
35 return AIObject::GetDoCommandStruct(_current_player)->mode; |
35 return GetDoCommandStruct(_current_player)->mode; |
36 } |
36 } |
37 |
37 |
38 AIObject *AIObject::GetDoCommandModeInstance() |
38 AIObject *AIObject::GetDoCommandModeInstance() |
39 { |
39 { |
40 return AIObject::GetDoCommandStruct(_current_player)->mode_instance; |
40 return GetDoCommandStruct(_current_player)->mode_instance; |
41 } |
41 } |
42 |
42 |
43 void AIObject::SetDoCommandCosts(Money value) |
43 void AIObject::SetDoCommandCosts(Money value) |
44 { |
44 { |
45 AIObject::GetDoCommandStruct(_current_player)->costs = CommandCost(value); |
45 GetDoCommandStruct(_current_player)->costs = CommandCost(value); |
46 } |
46 } |
47 |
47 |
48 void AIObject::IncreaseDoCommandCosts(Money value) |
48 void AIObject::IncreaseDoCommandCosts(Money value) |
49 { |
49 { |
50 AIObject::GetDoCommandStruct(_current_player)->costs.AddCost(value); |
50 GetDoCommandStruct(_current_player)->costs.AddCost(value); |
51 } |
51 } |
52 |
52 |
53 Money AIObject::GetDoCommandCosts() |
53 Money AIObject::GetDoCommandCosts() |
54 { |
54 { |
55 return AIObject::GetDoCommandStruct(_current_player)->costs.GetCost(); |
55 return GetDoCommandStruct(_current_player)->costs.GetCost(); |
56 } |
56 } |
57 |
57 |
58 void AIObject::SetLastError(const StringID last_error) |
58 void AIObject::SetLastError(const StringID last_error) |
59 { |
59 { |
60 AIObject::GetDoCommandStruct(_current_player)->last_error = last_error; |
60 GetDoCommandStruct(_current_player)->last_error = last_error; |
61 } |
61 } |
62 |
62 |
63 StringID AIObject::GetLastError() |
63 StringID AIObject::GetLastError() |
64 { |
64 { |
65 return AIObject::GetDoCommandStruct(_current_player)->last_error; |
65 return GetDoCommandStruct(_current_player)->last_error; |
66 } |
66 } |
67 |
67 |
68 void AIObject::SetLastCommandRes(bool res) |
68 void AIObject::SetLastCommandRes(bool res) |
69 { |
69 { |
70 AIObject::GetDoCommandStruct(_current_player)->last_command_res = res; |
70 GetDoCommandStruct(_current_player)->last_command_res = res; |
71 } |
71 } |
72 |
72 |
73 bool AIObject::GetLastCommandRes() |
73 bool AIObject::GetLastCommandRes() |
74 { |
74 { |
75 return AIObject::GetDoCommandStruct(_current_player)->last_command_res; |
75 return GetDoCommandStruct(_current_player)->last_command_res; |
76 } |
76 } |
77 |
77 |
78 void AIObject::SetNewVehicleID(VehicleID vehicle_id) |
78 void AIObject::SetNewVehicleID(VehicleID vehicle_id) |
79 { |
79 { |
80 AIObject::GetDoCommandStruct(_current_player)->new_vehicle_id = vehicle_id; |
80 GetDoCommandStruct(_current_player)->new_vehicle_id = vehicle_id; |
81 } |
81 } |
82 |
82 |
83 VehicleID AIObject::GetNewVehicleID() |
83 VehicleID AIObject::GetNewVehicleID() |
84 { |
84 { |
85 return AIObject::GetDoCommandStruct(_current_player)->new_vehicle_id; |
85 return GetDoCommandStruct(_current_player)->new_vehicle_id; |
86 } |
86 } |
87 |
87 |
88 void AIObject::SetNewSignID(SignID sign_id) |
88 void AIObject::SetNewSignID(SignID sign_id) |
89 { |
89 { |
90 AIObject::GetDoCommandStruct(_current_player)->new_sign_id = sign_id; |
90 GetDoCommandStruct(_current_player)->new_sign_id = sign_id; |
91 } |
91 } |
92 |
92 |
93 SignID AIObject::GetNewSignID() |
93 SignID AIObject::GetNewSignID() |
94 { |
94 { |
95 return AIObject::GetDoCommandStruct(_current_player)->new_sign_id; |
95 return GetDoCommandStruct(_current_player)->new_sign_id; |
96 } |
96 } |
97 |
97 |
98 void *&AIObject::GetEventPointer() |
98 void *&AIObject::GetEventPointer() |
99 { |
99 { |
100 return AIObject::GetDoCommandStruct(_current_player)->event_data; |
100 return GetDoCommandStruct(_current_player)->event_data; |
101 } |
101 } |
102 |
102 |
103 void *&AIObject::GetLogPointer() |
103 void *&AIObject::GetLogPointer() |
104 { |
104 { |
105 return AIObject::GetDoCommandStruct(_current_player)->log_data; |
105 return GetDoCommandStruct(_current_player)->log_data; |
106 } |
106 } |
107 |
107 |
108 AIObject::AIDoCommandStruct *AIObject::GetDoCommandStruct(PlayerID player) |
108 AIObject::AIDoCommandStruct *AIObject::GetDoCommandStruct(PlayerID player) |
109 { |
109 { |
110 /* Storage for data on per-AI level */ |
110 /* Storage for data on per-AI level */ |
111 static AIObject::AIDoCommandStruct command_struct[MAX_PLAYERS]; |
111 static AIDoCommandStruct command_struct[MAX_PLAYERS]; |
112 static bool initialized = false; |
112 static bool initialized = false; |
113 |
113 |
114 /* Make sure all memory is NULL when we start */ |
114 /* Make sure all memory is NULL when we start */ |
115 if (!initialized) { |
115 if (!initialized) { |
116 initialized = true; |
116 initialized = true; |
158 |
158 |
159 /* Restore _cmd_text */ |
159 /* Restore _cmd_text */ |
160 _cmd_text = tmp_cmdtext; |
160 _cmd_text = tmp_cmdtext; |
161 |
161 |
162 /* Check what the callback wants us to do */ |
162 /* Check what the callback wants us to do */ |
163 if (AIObject::GetDoCommandMode() != NULL && !AIObject::GetDoCommandMode()(tile, p1, p2, procc, res)) { |
163 if (GetDoCommandMode() != NULL && !GetDoCommandMode()(tile, p1, p2, procc, res)) { |
164 AIObject::IncreaseDoCommandCosts(res.GetCost()); |
164 IncreaseDoCommandCosts(res.GetCost()); |
165 return true; |
165 return true; |
166 } |
166 } |
167 |
167 |
168 /* If we did a DC_EXEC, and the command did not return an error, execute it |
168 /* If we did a DC_EXEC, and the command did not return an error, execute it |
169 * over the network */ |
169 * over the network */ |
178 _local_player = _current_player; |
178 _local_player = _current_player; |
179 ::NetworkSend_Command(tile, p1, p2, procc, CcAI); |
179 ::NetworkSend_Command(tile, p1, p2, procc, CcAI); |
180 _local_player = old_lp; |
180 _local_player = old_lp; |
181 |
181 |
182 /* Suspend the AI till the command is really executed */ |
182 /* Suspend the AI till the command is really executed */ |
183 AI_SuspendPlayer(_current_player, -(int)AIObject::GetDoCommandDelay()); |
183 ::AI_SuspendPlayer(_current_player, -(int)GetDoCommandDelay()); |
184 /* Check if the callback still agrees with us, else return error */ |
184 /* Check if the callback still agrees with us, else return error */ |
185 if (!AIObject::GetLastCommandRes()) res = CMD_ERROR; |
185 if (!GetLastCommandRes()) res = CMD_ERROR; |
186 } else { |
186 } else { |
187 #else |
187 #else |
188 { |
188 { |
189 #endif |
189 #endif |
190 /* For SinglePlayer we execute the command immediatly */ |
190 /* For SinglePlayer we execute the command immediatly */ |
191 ::DoCommandP(tile, p1, p2, NULL, procc); |
191 ::DoCommandP(tile, p1, p2, NULL, procc); |
192 /* Store some values inside the AIObject static memory */ |
192 /* Store some values inside the AIObject static memory */ |
193 AIObject::SetNewVehicleID(_new_vehicle_id); |
193 SetNewVehicleID(_new_vehicle_id); |
194 AIObject::SetNewSignID(_new_sign_id); |
194 SetNewSignID(_new_sign_id); |
195 |
195 |
196 /* Suspend the AI player for 1 tick, so it simulates MultiPlayer */ |
196 /* Suspend the AI player for 1 tick, so it simulates MultiPlayer */ |
197 AI_SuspendPlayer(_current_player, AIObject::GetDoCommandDelay()); |
197 ::AI_SuspendPlayer(_current_player, GetDoCommandDelay()); |
198 } |
198 } |
199 |
199 |
200 if (::CmdFailed(res)) { |
200 if (::CmdFailed(res)) { |
201 SetLastError(_error_message); |
201 SetLastError(_error_message); |
202 return false; |
202 return false; |
203 } |
203 } |
204 |
204 |
205 AIObject::IncreaseDoCommandCosts(res.GetCost()); |
205 IncreaseDoCommandCosts(res.GetCost()); |
206 return true; |
206 return true; |
207 } |
207 } |