This commit is contained in:
Vick Scarlet
2021-08-15 11:01:01 +08:00
commit cc72b5a6b3
10 changed files with 730 additions and 0 deletions

129
src/condition.js Normal file
View File

@@ -0,0 +1,129 @@
class Condition {
constructor(prop) {
this._prop = prop;
}
parse(condition) {
const conditions = [];
const length = condition.length;
const stack = [];
stack.unshift(conditions);
let cursor = 0;
const catchString = i => {
const str = condition.substring(cursor, i).trim();
cursor = i;
if(str) stack[0].push(str);
};
for(let i=0; i<length; i++) {
switch(condition[i]) {
case ' ': continue;
case '(':
catchString(i);
cursor ++;
const sub = [];
stack[0].push(sub);
stack.unshift(sub);
break;
case ')':
catchString(i);
cursor ++;
stack.shift();
break;
case '|':
case '&':
catchString(i);
catchString(i+1);
break;
default: continue;
}
}
catchString(length);
return conditions;
}
check(condition) {
const conditions = this.parse(condition);
return this.checkParsedConditions(conditions);
}
checkParsedConditions(conditions) {
if(!Array.isArray(conditions)) return this.checkProp(conditions);
if(conditions.length == 0) return true;
if(conditions.length == 1) return this.checkParsedConditions(conditions[0]);
let ret = this.checkParsedConditions(conditions[0]);
for(let i=1; i<conditions.length; i+=2) {
switch(conditions[i]) {
case '&':
if(ret) ret = this.checkParsedConditions(conditions[i+1]);
break;
case '|':
if(ret) return true;
ret = this.checkParsedConditions(conditions[i+1]);
break;
default: return false;
}
}
return ret;
}
checkProp(condition) {
const length = condition.length;
let i = condition.search(/[><\!\?=]/);
const prop = condition.substring(0,i);
const symbol = condition.substring(i, i+=(condition[i+1]=='='?2:1));
const d = condition.substring(i, length);
const propData = this.getProp(prop);
const conditionData = d[0]=='['? JSON.parse(d): Number(d);
switch(symbol) {
case '>': return propData > conditionData;
case '<': return propData < conditionData;
case '>=': return propData >= conditionData;
case '<=': return propData <= conditionData;
case '=':
if(Array.isArray(propData))
return propData.includes(conditionData);
return propData == conditionData;
case '!=':
if(Array.isArray(propData))
return !propData.includes(conditionData);
return propData == conditionData;
case '?':
if(Array.isArray(propData)) {
for(const p of propData)
if(conditionData.includes(p)) return true;
return false;
}
return conditionData.includes(propData);
case '!':
if(Array.isArray(propData)) {
for(const p of propData)
if(conditionData.includes(p)) return false;
return true;
}
return !conditionData.includes(propData);
default: return false;
}
}
getProp(prop) {
return this.prop.get(prop);
}
get prop() {return this._prop;}
set prop(p) {this._prop = p;}
}
export default Condition;

74
src/prop.js Normal file
View File

@@ -0,0 +1,74 @@
class Prop {
constructor(initialData) {
this._data = {};
for(const key in initialData)
this.set(key, initialData[key]);
}
get(prop) {
switch(prop) {
case 'CHR':
case 'INT':
case 'STR':
case 'MNY':
case 'SPR':
case 'LIF':
case 'TLT':
case 'EVT':
return this._data[prop];
default: return 0;
}
}
set(prop, value) {
switch(prop) {
case 'CHR':
case 'INT':
case 'STR':
case 'MNY':
case 'SPR':
case 'LIF':
case 'TLT':
case 'EVT':
this._data[prop] = this.clone(value);
break;
default: return 0;
}
}
change(prop, value) {
switch(prop) {
case 'CHR':
case 'INT':
case 'STR':
case 'MNY':
case 'SPR':
case 'LIF':
this._data[prop] += value;
break;
case 'TLT':
case 'EVT':
const v = this._data[prop];
if(value<0) {
const index = v.indexOf(value);
if(index!=-1) v.splice(index,1);
}
if(!v.includes(value)) v.push(value);
break;
default: return;
}
}
clone(value) {
switch(typeof value) {
case 'object':
if(Array.isArray(value)) return value.map(v=>this.clone(v));
const newObj = {};
for(const key in value) newObj[key] = this.clone(value[key]);
return newObj;
default: return value;
}
}
}
export default Prop;