forked from KingofTown/DS-AI
-
Notifications
You must be signed in to change notification settings - Fork 1
/
modmain.lua
392 lines (316 loc) · 14.4 KB
/
modmain.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
local Vector3 = GLOBAL.Vector3
local dlcEnabled = GLOBAL.IsDLCEnabled(GLOBAL.REIGN_OF_GIANTS)
local SEASONS = GLOBAL.SEASONS
local GetPlayer = GLOBAL.GetPlayer
local GetWorld = GLOBAL.GetWorld
local ArtificalWilsonEnabled = false
Assets = {
Asset("IMAGE", "images/map_circle.tex"),
Asset("ATLAS", "images/map_circle.xml"),
}
AddMinimapAtlas("images/map_circle.xml")
-- Stole this from flingomatic range check mod...
PrefabFiles =
{
"range"
}
AddBrainPostInit("artificalwilson",ArtificalWilson)
local function setSelfAI()
print("Enabling Artifical Wilson")
local player = GetPlayer()
--player:RemoveComponent("playercontroller")
player:AddComponent("follower")
player:AddComponent("homeseeker")
player:AddTag("ArtificalWilson")
local brain = GLOBAL.require "brains/artificalwilson"
player:SetBrain(brain)
ArtificalWilsonEnabled = true
--player:ListenForEvent("attacked", OnAttacked)
end
local function setSelfNormal()
print("Disabling Artifical Wilson")
local player = GetPlayer()
local brain = GLOBAL.require "brains/wilsonbrain"
player:SetBrain(brain)
player:RemoveTag("ArtificalWilson")
--player:RemoveComponent("follower")
player:RemoveComponent("homeseeker")
ArtificalWilsonEnabled = false
end
local function spawnAI(sim)
sim.SpawnWilson = function(inst)
wilson = GLOBAL.SpawnPrefab("wilson")
pos = Vector3(GetPlayer().Transform:GetWorldPosition())
if wilson and pos then
wilson:AddComponent("follower")
wilson:AddComponent("homeseeker")
wilson:AddComponent("inventory")
wilson:AddTag("ArtificalWilson")
local brain = GLOBAL.require "brains/artificalwilson"
wilson:SetBrain(brain)
wilson.Transform:SetPosition(pos:Get())
end
end
local function OnAttacked(inst, data)
inst.components.combat:SetTarget(data.attacker)
end
sim.SetSelfAI = setSelfAI
sim.SetSelfNormal = setSelfNormal
sim.Crash = function(inst) local a = inst.components.crashGame.yay end
end
AddComponentPostInit("clock",spawnAI)
GLOBAL.TheInput:AddKeyDownHandler(GLOBAL.KEY_P, function()
local TheInput = GLOBAL.TheInput
if not GLOBAL.IsPaused() and TheInput:IsKeyDown(GLOBAL.KEY_CTRL) and not TheInput:IsKeyDown(GLOBAL.KEY_ALT) then
setSelfAI()
elseif not GLOBAL.IsPaused() and TheInput:IsKeyDown(GLOBAL.KEY_CTRL) and TheInput:IsKeyDown(GLOBAL.KEY_ALT) then
setSelfNormal()
end
end)
local function MakeClickableBrain()
local player = GLOBAL.GetPlayer()
local controls = player.HUD.controls
local status = controls.status
status.brain:SetClickable(true)
local x = 0
local darker = true
local function BrainPulse(self)
if not darker then
x = x+.1
if x >=1 then
darker = true
x = 1
end
else
x = x-.1
if x <=.5 then
darker = false
x = .5
end
end
status.brain.anim:GetAnimState():SetMultColour(x,x,x,1)
self.brainPulse = self:DoTaskInTime(.15,BrainPulse)
end
status.brain.OnMouseButton = function(self,button,down,x,y)
if button == 1001 and down == true then
print("Spawning a wilson")
GLOBAL.GetClock():SpawnWilson()
return
end
if down == true then
if ArtificalWilsonEnabled then
self.owner.brainPulse:Cancel()
status.brain.anim:GetAnimState():SetMultColour(1,1,1,1)
setSelfNormal()
else
BrainPulse(self.owner)
setSelfAI()
end
end
end
status.stomach:SetClickable(true)
status.stomach.OnMouseButton = function(self,button,down,x,y)
if down == true then
GLOBAL.c_give("log",20)
GLOBAL.c_give("twigs",20)
GLOBAL.c_give("cutgrass",20)
GLOBAL.c_give("flint",20)
GLOBAL.c_give("goldnugget",20)
GLOBAL.c_give("rocks",20)
GLOBAL.c_give("charcoal",6)
GLOBAL.c_give("berries",10)
GLOBAL.c_give("carrot",10)
GLOBAL.c_give("acorn_cooked",4)
GLOBAL.c_give("monstermeat",4)
GLOBAL.c_give("smallmeat",4)
GLOBAL.c_give("fish",4)
GLOBAL.c_give("green_cap",4)
end
end
end
AddSimPostInit(MakeClickableBrain)
---------------------------------------------------------------------------------
-- LOCOMOTOR MOD
-- TODO: Make an equivalent non RoG onupdate function and check if DLC enabled
-- to load the right one. Will probabl crash the game if you try to load
-- this w/out expansion
local distsq = GLOBAL.distsq
-- 99% taken directly from locomotor component.
local function RoGOnUpdate(self,dt)
-- Import the local variables (or copy them)
local PATHFIND_PERIOD = 1
local PATHFIND_MAX_RANGE = 40
local STATUS_CALCULATING = 0
local STATUS_FOUNDPATH = 1
local STATUS_NOPATH = 2
local NO_ISLAND = 127
local ARRIVE_STEP = .15
self.OnUpdate = function(self,dt)
if not self.inst:IsValid() then
self:ResetPath()
self.inst:StopUpdatingComponent(self)
return
end
if self.enablegroundspeedmultiplier then
self.creep_check_timeout = self.creep_check_timeout - dt
if self.creep_check_timeout < 0 then
self:UpdateGroundSpeedMultiplier()
self.creep_check_timeout = .5
end
end
if self.dest then
if not self.dest:IsValid() or (self.bufferedaction and not self.bufferedaction:IsValid()) then
self:Clear()
return
end
if self.inst.components.health and self.inst.components.health:IsDead() then
self:Clear()
return
end
local destpos_x, destpos_y, destpos_z = self.dest:GetPoint()
local mypos_x, mypos_y, mypos_z= self.inst.Transform:GetWorldPosition()
local dsq = distsq(destpos_x, destpos_z, mypos_x, mypos_z)
local run_dist = self:GetRunSpeed()*dt*.5
if dsq <= math.max(run_dist*run_dist, self.arrive_dist*self.arrive_dist) then
self.inst:PushEvent("onreachdestination", {target=self.dest.inst, pos=Point(destpos_x, destpos_y, destpos_z)})
if self.atdestfn then
self.atdestfn(self.inst)
end
if self.bufferedaction and self.bufferedaction ~= self.inst.bufferedaction then
if self.bufferedaction.target and self.bufferedaction.target.Transform then
self.inst:FacePoint(self.bufferedaction.target.Transform:GetWorldPosition())
end
self.inst:PushBufferedAction(self.bufferedaction)
end
self:Stop()
self:Clear()
else
--Print(VERBOSITY.DEBUG, "LOCOMOTING")
if self:WaitingForPathSearch() then
local pathstatus = GetWorld().Pathfinder:GetSearchStatus(self.path.handle)
--Print(VERBOSITY.DEBUG, "HAS PATH SEARCH", pathstatus)
--print("HAS PATH SEARCH " .. tostring(pathstatus))
if pathstatus ~= STATUS_CALCULATING then
--Print(VERBOSITY.DEBUG, "PATH CALCULATION complete", pathstatus)
if self.inst:HasTag("player") then print("PATH CALC COMPLETE " .. tostring(pathstatus)) end
if self.inst:HasTag("player") then print("STATUS_FOUNDPATH = " .. tostring(STATUS_FOUNDPATH)) end
if pathstatus == STATUS_FOUNDPATH then
--Print(VERBOSITY.DEBUG, "PATH FOUND")
if self.inst:HasTag("player") then print("PATH FOUND") end
local foundpath = GetWorld().Pathfinder:GetSearchResult(self.path.handle)
if foundpath then
--Print(VERBOSITY.DEBUG, string.format("PATH %d steps ", #foundpath.steps))
if self.inst:HasTag("player") then print(string.format("PATH %d steps ", #foundpath.steps)) end
if #foundpath.steps > 2 then
self.path.steps = foundpath.steps
self.path.currentstep = 2
-- for k,v in ipairs(foundpath.steps) do
-- Print(VERBOSITY.DEBUG, string.format("%d, %s", k, tostring(Point(v.x, v.y, v.z))))
-- end
else
--Print(VERBOSITY.DEBUG, "DISCARDING straight line path")
self.path.steps = nil
self.path.currentstep = nil
end
else
if self.inst:HasTag("player") then print("EMPTY PATH") end
GetWorld().Pathfinder:KillSearch(self.path.handle)
self.path.handle = nil
self.inst:PushEvent("noPathFound", {inst=self.inst, target=self.dest.inst, pos=Point(destpos_x, destpos_y, destpos_z)})
end
else
if pathstatus == nil then
if self.inst:HasTag("player") then print(string.format("LOST PATH SEARCH %u. Maybe it timed out?", self.path.handle)) end
else
if self.inst:HasTag("player") then print("NO PATH") end
GetWorld().Pathfinder:KillSearch(self.path.handle)
self.path.handle = nil
self.inst:PushEvent("noPathFound", {inst=self.inst, target=self.dest.inst, pos=Point(destpos_x, destpos_y, destpos_z)})
end
end
if self.path and self.path.handle then
GetWorld().Pathfinder:KillSearch(self.path.handle)
self.path.handle = nil
end
end
end
if not self.inst.sg or self.inst.sg:HasStateTag("canrotate") then
--Print(VERBOSITY.DEBUG, "CANROTATE")
local facepos_x, facepos_y, facepos_z = destpos_x, destpos_y, destpos_z
if self.path and self.path.steps and self.path.currentstep < #self.path.steps then
--Print(VERBOSITY.DEBUG, "FOLLOW PATH")
--print("FOLLOW PATH")
local step = self.path.steps[self.path.currentstep]
local steppos_x, steppos_y, steppos_z = step.x, step.y, step.z
--Print(VERBOSITY.DEBUG, string.format("CURRENT STEP %d/%d - %s", self.path.currentstep, #self.path.steps, tostring(steppos)))
local step_distsq = distsq(mypos_x, mypos_z, steppos_x, steppos_z)
if step_distsq <= (self.arrive_step_dist)*(self.arrive_step_dist) then
self.path.currentstep = self.path.currentstep + 1
if self.path.currentstep < #self.path.steps then
step = self.path.steps[self.path.currentstep]
steppos_x, steppos_y, steppos_z = step.x, step.y, step.z
else
steppos_x, steppos_y, steppos_z = destpos_x, destpos_y, destpos_z
end
end
facepos_x, facepos_y, facepos_z = steppos_x, steppos_y, steppos_z
end
local x,y,z = self.inst.Physics:GetMotorVel()
if x < 0 then
local angle = self.inst:GetAngleToPoint(facepos_x, facepos_y, facepos_z)
self.inst.Transform:SetRotation(180 + angle)
else
self.inst:FacePoint(facepos_x, facepos_y, facepos_z)
end
end
self.wantstomoveforward = self.wantstomoveforward or not self:WaitingForPathSearch()
end
end
local is_moving = self.inst.sg and self.inst.sg:HasStateTag("moving")
local is_running = self.inst.sg and self.inst.sg:HasStateTag("running")
local should_locomote = (not is_moving ~= not self.wantstomoveforward) or (is_moving and (not is_running ~= not self.wantstorun)) -- 'not' is being used on this line as a cast-to-boolean operator
if not self.inst:IsInLimbo() and should_locomote then
self.inst:PushEvent("locomote")
elseif not self.wantstomoveforward and not self:WaitingForPathSearch() then
self:ResetPath()
self.inst:StopUpdatingComponent(self)
end
local cur_speed = self.inst.Physics:GetMotorSpeed()
if cur_speed > 0 then
local speed_mult = self:GetSpeedMultiplier()
local desired_speed = self.isrunning and self.runspeed or self.walkspeed
if self.dest and self.dest:IsValid() then
local destpos_x, destpos_y, destpos_z = self.dest:GetPoint()
local mypos_x, mypos_y, mypos_z = self.inst.Transform:GetWorldPosition()
local dsq = distsq(destpos_x, destpos_z, mypos_x, mypos_z)
if dsq <= .25 then
speed_mult = math.max(.33, math.sqrt(dsq))
end
end
self.inst.Physics:SetMotorVel((desired_speed + self.bonusspeed) * speed_mult, 0, 0)
end
end
end
AddComponentPostInit("locomotor",RoGOnUpdate)
local function ReallyFull(self)
self.IsTotallyFull = function()
local invFull = self:IsFull()
local overFull = true
if self.overflow then
if self.overflow.components.container then
--print("Is my " .. self.overflow.prefab .. " full?")
overFull = self.overflow.components.container:IsFull()
end
end
return not not invFull and not not overFull
end
end
AddComponentPostInit("inventory", ReallyFull)
-- New components that have OnLoad need to be loaded early!
local function AddNewComponents(player)
player:AddComponent("prioritizer")
--player:AddComponent("cartographer")
player:AddComponent("chef")
--player:AddTag("debugPrint")
end
AddPlayerPostInit(AddNewComponents)