-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathroomservice.defense.js
144 lines (119 loc) · 4.07 KB
/
roomservice.defense.js
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
const ff = require("helper.friendFoeRecognition");
const gateCache = {};
const CACHE_TTL = 30;
/* Defcon level is intended to give an indication about the severeness of
* an attack and can be used to increase response force.
* Defcon 0: Peace
* Defcon 1: Short-lived attack (most often NPCs)
* * Keep turrets supplied
* Defcon 2: Attack that wasn't defeated within short time (strong NPCs?)
* * Spawn guards
* Defcon 3: Guards were not able to defeat intruders
* * Boost guards
* * stop dangerous remote mining
* Defcon 4: This is going to take a long time...
* * Keep walls fortified
* * Decrease non-vital spawn and energy load
* ...
*
* Fetch the current Defcon level using
*
* defense.defcon;
*/
const DEFCONS = [
{ level: 0, escalateAt: 1, cooldown: 0 },
{ level: 1, escalateAt: 50, cooldown: 100 },
{ level: 2, escalateAt: 500, cooldown: 300 },
{ level: 3, escalateAt: 1000, cooldown: 500 },
{ level: 4, escalateAt: null, cooldown: 500 }
]
function escalateDefcon(defcon) {
let reference = DEFCONS[defcon.level];
defcon.progress += 1;
defcon.cooldown = Math.min(defcon.cooldown + 1, reference.cooldown);
if(reference.escalateAt && defcon.progress >= reference.escalateAt) {
defcon.level += 1;
defcon.progress = 0;
defcon.cooldown = DEFCONS[defcon.level].cooldown;
}
}
function deescalateDefcon(defcon) {
if(defcon.level === 0) return;
if(defcon.cooldown > 0) defcon.cooldown -= 1;
if(defcon.cooldown <= 0) {
defcon.level -= 1;
defcon.progress = 0;
defcon.cooldown = DEFCONS[defcon.level].cooldown;
}
}
module.exports = class Defense {
constructor(room) {
this.room = room;
if(this.room.memory.defense) {
this.memory = this.room.memory.defense;
} else {
this.memory = {};
this.room.memory.defense = this.memory;
}
if(!this.memory.defcon) {
this.memory.defcon = {
level: 0,
progress: 0,
cooldown: 0
};
}
}
get hostiles() {
if(!this._hostiles) this._hostiles = ff.findHostiles(this.room);
return this._hostiles;
}
get defcon() {
return this.memory.defcon.level;
}
updateDefcon() {
let defcon = this.memory.defcon;
if(this.hostiles.length > 0) {
escalateDefcon(defcon);
} else {
deescalateDefcon(defcon);
}
}
displayDefcon() {
let defcon = this.memory.defcon;
if(defcon.level === 0) return;
RoomUI.forRoom(this.room).addRoomCaption(`Defcon ${defcon.level} (${defcon.progress} T; CD ${defcon.cooldown} T)`, { color: "#faa"});
}
get gates() {
if(!this._gates) {
this._gates = this.findGates();
}
return this._gates;
}
get walls() {
if(!this._walls) {
this._walls = this.findWalls();
}
return this._walls;
}
get borderStructures() {
return this.gates.concat(this.walls);
}
findGates() {
let cache = gateCache[this.room.name];
if(cache && cache.time > Game.time - CACHE_TTL) return _.compact(_.map(cache.result, (id) => Game.getObjectById(id)));
cache = gateCache[this.room.name] = { time: Game.time };
let result = this.room.find(FIND_MY_STRUCTURES, { filter: function(structure) {
if(structure.structureType !== STRUCTURE_RAMPART) return false;
let otherStructures = structure.pos.lookFor(LOOK_STRUCTURES);
let isBlocked = _.some(otherStructures, (s) => s.structureType !== STRUCTURE_RAMPART && s.structureType !== STRUCTURE_ROAD);
return !isBlocked;
} });
cache.result = _.map(result, (s) => s.id);
return result;
}
findWalls() {
return this.room.find(FIND_STRUCTURES, { filter: (s) => s.structureType === STRUCTURE_WALL });
}
}
const profiler = require("screeps-profiler");
profiler.registerClass(module.exports, 'Defense');