Files
starruler-linux/scripts/definitions/camps.as
T
2018-07-17 14:15:37 +02:00

360 lines
7.8 KiB
ActionScript

#priority init 2001
import pickups;
import statuses;
from pickups import IPickupHook, PickupHook;
import saving;
import hooks;
export CampType;
export getCreepCamp, getCreepCampCount;
export getDistributedCreepCamp;
#section server
from empire import Creeps;
#section all
tidy final class CampType {
uint id = 0;
string ident;
double frequency = 1.0;
double pickupFrequency = 0.0;
int flagshipSize = 0;
double supportOccupation = 1.0;
double targetStrength = 0.0;
array<string> def_region_statuses;
array<const StatusType@> region_statuses;
array<string> def_statuses;
array<const StatusType@> statuses;
array<PickupType@> pickups;
array<string> def_ships;
array<const Design@> ships;
array<string> shipNames;
array<uint> shipMins;
array<uint> shipMaxes;
void init() {
statuses.length = 0;
for(uint i = 0, cnt = def_statuses.length; i < cnt; ++i) {
auto@ type = getStatusType(def_statuses[i]);
if(type is null) {
error("ERROR: Could not find status '"+def_statuses[i]+"' in creep camp '"+ident+"'.");
continue;
}
statuses.insertLast(type);
}
for(uint i = 0, cnt = def_region_statuses.length; i < cnt; ++i) {
auto@ type = getStatusType(def_region_statuses[i]);
if(type is null) {
error("ERROR: Could not find region status '"+def_region_statuses[i]+"' in creep camp '"+ident+"'.");
continue;
}
region_statuses.insertLast(type);
}
#section server
for(uint i = 0, cnt = def_ships.length; i < cnt; ++i) {
string line = def_ships[i];
const Design@ dsg;
uint min = 1, max = 1;
string name;
if(line.findFirst("[") != -1 && line.findFirst("]") != -1) {
int fpos = line.findFirst("[");
int epos = line.findFirst("]");
name = localize(line.substr(fpos+1, epos-fpos-1));
line = line.substr(0, fpos);
}
@dsg = Creeps.getDesign(line.trimmed());
if(dsg is null) {
//Check if we have a number
int pos = line.findFirst(" ");
if(pos == -1) {
error(" Error: invalid design spec "+escape(line.trimmed()));
return;
}
string counts = line.substr(0, pos).trimmed();
string design = line.substr(pos).trimmed();
if(counts[counts.length-1] != 'x') {
error(" Error: could not find design "+escape(line.trimmed()));
return;
}
int dashPos = counts.findFirst("-");
if(dashPos == -1) {
min = max = toUInt(counts.substr(0, counts.length-1));
}
else {
min = toUInt(counts.substr(0, dashPos));
max = toUInt(counts.substr(dashPos+1, counts.length-dashPos-2));
}
@dsg = Creeps.getDesign(design);
if(dsg is null) {
error(" Error: could not find design "+escape(line.trimmed()));
return;
}
}
ships.insertLast(dsg);
shipMins.insertLast(min);
shipMaxes.insertLast(max);
shipNames.insertLast(name);
}
#section all
}
};
void parseLine(string& line, CampType@ c, ReadFile@ file) {
//Try to find the design
if(line.findFirst("(") == -1) {
c.def_ships.insertLast(line);
}
else {
if(c.pickups.length == 0) {
error("Missing 'Pickup:' line for: "+escape(line));
return;
}
//Hook line
auto@ hook = cast<IPickupHook>(parseHook(line, "pickup_effects::", instantiate=false, file=file));
if(hook !is null)
c.pickups[c.pickups.length-1].hooks.insertLast(hook);
}
}
void loadCamps(const string& filename) {
ReadFile file(filename, true);
string key, value;
CampType@ c;
PickupType@ p;
uint index = 0;
while(file++) {
key = file.key;
value = file.value;
if(file.fullLine) {
if(c is null) {
error("Missing 'Camp: ID' line in " + filename);
continue;
}
string line = file.line;
parseLine(line, c, file);
}
else if(key == "Camp") {
if(c !is null)
addCreepCamp(c);
@c = CampType();
c.ident = value;
if(c.ident.length == 0)
c.ident = filename+"__"+index;
@p = null;
++index;
}
else if(c is null) {
error("Missing 'Camp: ID' line in " + filename);
}
else if(key == "Frequency") {
if(p !is null)
p.frequency = toDouble(value);
else
c.frequency = toDouble(value);
}
else if(key == "Pickup") {
@p = PickupType();
p.ident = value;
if(p.ident.length == 0)
p.ident = c.ident+"__"+c.pickups.length;
c.pickups.insertLast(p);
}
else if(key == "DLC") {
if(p is null) {
error("Missing 'Pickup:' line in " + filename);
continue;
}
p.dlc = value;
}
else if(key == "Name") {
if(p is null) {
error("Missing 'Pickup:' line in " + filename);
continue;
}
p.name = localize(value);
}
else if(key == "Verb") {
if(p is null) {
error("Missing 'Pickup:' line in " + filename);
continue;
}
p.verb = localize(value);
}
else if(key == "Description") {
if(p is null) {
error("Missing 'Pickup:' line in " + filename);
continue;
}
p.description = localize(value);
}
else if(key == "Model") {
if(p is null) {
error("Missing 'Pickup:' line in " + filename);
continue;
}
@p.model = getModel(value);
}
else if(key == "Material") {
if(p is null) {
error("Missing 'Pickup:' line in " + filename);
continue;
}
@p.material = getMaterial(value);
}
else if(key == "Physical Size") {
if(p is null) {
error("Missing 'Pickup:' line in " + filename);
continue;
}
p.physicalSize = toDouble(value);
}
else if(key == "Icon Sheet") {
if(p is null) {
error("Missing 'Pickup:' line in " + filename);
continue;
}
@p.iconSheet = getSpriteSheet(value);
}
else if(key == "Icon Index") {
if(p is null) {
error("Missing 'Pickup:' line in " + filename);
continue;
}
p.iconIndex = toUInt(value);
}
else if(key == "Region Status") {
c.def_region_statuses.insertLast(value);
}
else if(key == "Remnant Status") {
c.def_statuses.insertLast(value);
}
else if(key == "Flagship Size") {
c.flagshipSize = toInt(value);
}
else if(key == "Target Strength") {
c.targetStrength = toDouble(value);
}
else if(key == "Support Occupation") {
c.supportOccupation = toDouble(value);
}
else if(key == "Ship") {
parseLine(value, c, file);
}
else {
string line = file.line;
parseLine(line, c, file);
}
}
if(c !is null)
addCreepCamp(c);
}
bool initialized = false;
void initCreepCampTypes() {
if(initialized)
return;
initialized = true;
for(uint i = 0, cnt = campTypes.length; i < cnt; ++i)
campTypes[i].init();
}
void preInit() {
//Load camp types
FileList list("data/creeps", "*.txt", true);
for(uint i = 0, cnt = list.length; i < cnt; ++i)
loadCamps(list.path[i]);
}
void init() {
if(!isLoadedSave)
initCreepCampTypes();
}
CampType@[] campTypes;
dictionary idents;
double totalFrequency = 0;
const CampType@ getCreepCamp(uint id) {
if(id >= campTypes.length)
return null;
return campTypes[id];
}
const CampType@ getCreepCamp(const string& ident) {
CampType@ camp;
if(idents.get(ident, @camp))
return camp;
return null;
}
uint getCreepCampCount() {
return campTypes.length;
}
const CampType@ getDistributedCreepCamp() {
double num = randomd(0, totalFrequency);
for(uint i = 0, cnt = campTypes.length; i < cnt; ++i) {
const CampType@ type = campTypes[i];
double freq = type.frequency;
if(num <= freq)
return type;
num -= freq;
}
return campTypes[campTypes.length-1];
}
void addCreepCamp(CampType@ type) {
type.id = campTypes.length;
campTypes.insertLast(type);
idents.set(type.ident, @type);
type.pickupFrequency = 0.0;
for(uint i = 0, cnt = type.pickups.length; i < cnt; ++i) {
auto@ pu = type.pickups[i];
if(pu.dlc.length != 0 && !hasDLC(pu.dlc))
pu.frequency = 0.0;
addPickupType(pu);
type.pickupFrequency += pu.frequency;
}
if(type.pickupFrequency == 0.0)
type.frequency = 0.0;
totalFrequency += type.frequency;
}
void saveIdentifiers(SaveFile& file) {
for(uint i = 0, cnt = campTypes.length; i < cnt; ++i) {
auto type = campTypes[i];
file.addIdentifier(SI_CreepCamp, type.id, type.ident);
}
}