From 1b9815bb421c87fb1ae02a79426ca1e51ec9c3b0 Mon Sep 17 00:00:00 2001 From: Raffaele Pojer Date: Fri, 28 Aug 2020 00:27:55 +0200 Subject: [PATCH] Now original target are shown, minor fixing, refers to #28 --- src/extensions/botch/index.js | 160 +++++++++++++++++-------------- src/extensions/botch/organism.js | 84 +++++++--------- 2 files changed, 125 insertions(+), 119 deletions(-) diff --git a/src/extensions/botch/index.js b/src/extensions/botch/index.js index 74a4be046de..ddf4c45cc7c 100644 --- a/src/extensions/botch/index.js +++ b/src/extensions/botch/index.js @@ -322,31 +322,45 @@ class Scratch3Botch { */ setAs (args, util) { if (args.TYPE === 'organism') { - this.botchUtil.deleteClones(util.target.id); - this.botchUtil.deleteAllOrgCostumes(util.target); - // check if it is already assigned somewhere - if (this.enemiesMap.size > 0 && + // check if it is already set as organism, if true don't delete the sprites + if (!(this.organismMap.size > 0 && this.organismMap.get(util.target.id))) { + this.botchUtil.deleteClones(util.target.id); + this.botchUtil.deleteAllOrgCostumes(util.target); // TODO mettere nel stop all + this.organismMap = new Map(); + // check if it is already assigned somewhere + if (this.enemiesMap.size > 0 && util.target.id === this.enemiesMap.entries().next().value[0]) { - this.enemiesMap = new Map(); - } - - this.organismMap = new Map(); - const org = new Organism(util.target); - this.organismMap.set(util.target.id, org); - - org.currentName = this.currentOrgCounter.toString(); - - util.target.setVisible(false); - this.createOrganismClone(util.target, 0); + this.enemiesMap = new Map(); + } - const state = this.getBotchState(util.target); - state.type = Scratch3Botch.ORGANISM_TYPE; + // create an organism with the original + const org = new Organism(util.target, this.mass, this.maxForce); + this.organismMap.set(util.target.id, org); + org.setParentVariable(); + org.setOrgDna(); + org.assignOrgCostume(); + + this.currentOrgCounter++; + org.currentName = this.currentOrgCounter.toString(); + const p = this.storeSprite(util.target.id, org.currentName); + util.target.setCustomState('storedMd5', p.md5); + const state = this.getBotchState(util.target); + state.type = Scratch3Botch.ORGANISM_TYPE; + } } if (args.TYPE === 'food') { this.botchUtil.deleteClones(util.target.id); this.botchUtil.deleteAllOrgCostumes(util.target); util.target.setVisible(true); + // if it was set as enemy or organism, reset + if (this.organismMap.size > 0 && this.organismMap.get(util.target.id)) { + this.organismMap = new Map(); + } + if (this.enemiesMap.size > 0 && this.enemiesMap.get(util.target.id)) { + this.enemiesMap = new Map(); + } + const state = this.getBotchState(util.target); state.type = Scratch3Botch.FOOD_TYPE; } @@ -355,25 +369,37 @@ class Scratch3Botch { this.botchUtil.deleteAllOrgCostumes(util.target); util.target.setVisible(true); + // if it was set as enemy or organism, reset + if (this.organismMap.size > 0 && this.organismMap.get(util.target.id)) { + this.organismMap = new Map(); + } + if (this.enemiesMap.size > 0 && this.enemiesMap.get(util.target.id)) { + this.enemiesMap = new Map(); + } + const state = this.getBotchState(util.target); state.type = Scratch3Botch.POISON_TYPE; } if (args.TYPE === 'enemy') { - this.botchUtil.deleteClones(util.target.id); - this.botchUtil.deleteAllOrgCostumes(util.target); - // check if it is already assigned somewhere - if (this.organismMap.size > 0 && + if (!(this.enemiesMap.size > 0 && this.enemiesMap.get(util.target.id))) { + this.botchUtil.deleteClones(util.target.id); + this.botchUtil.deleteAllOrgCostumes(util.target); + // check if it is already assigned somewhere + if (this.organismMap.size > 0 && util.target.id === this.organismMap.entries().next().value[0]) { - this.organismMap = new Map(); - } + this.organismMap = new Map(); + } - this.enemiesMap = new Map(); - this.enemiesMap.set(util.target.id, new Organism(util.target)); - util.target.setVisible(false); - this.createEnemyClone(util.target, 0); + this.enemiesMap = new Map(); + this.enemiesMap.set(util.target.id, new Organism(util.target)); + + const en = new Organism(util.target, this.mass, this.maxForce); + this.enemiesMap.set(util.target.id, en); + en.assignEnemyCostume(); - const state = this.getBotchState(util.target); - state.type = Scratch3Botch.ENEMY_TYPE; + const state = this.getBotchState(util.target); + state.type = Scratch3Botch.ENEMY_TYPE; + } } } @@ -413,10 +439,6 @@ class Scratch3Botch { newClone.setCustomState('storedMd5', p.md5); const state = this.getBotchState(newClone); state.type = Scratch3Botch.ORGANISM_TYPE; - - if (target.isOriginal) { - this.originalOrg = org; - } } } @@ -464,25 +486,25 @@ class Scratch3Botch { * @since botch-0.1 */ generatePopulation (args, util) { + const copies = MathUtil.clamp(Cast.toNumber(args.COPIES), 1, 30); if (this.organismMap.size > 0 && - this.organismMap.get(util.target.id)) { // util.target.id === this.organismMap.entries().next().value[0] - util.target.setVisible(false); // hide the original - const copies = Cast.toNumber(args.COPIES); - if (copies > 0 && copies <= 30) { - for (let i = 1; i < copies; i++) { - this.createOrganismClone(util.target, i); - } + this.organismMap.get(util.target.id)) { + if (this.organismMap.size > 1) { // if there are already organism create one more + this.createOrganismClone(util.target, 1); + } + for (let i = 1; i < copies; i++) { + this.createOrganismClone(util.target, i); } } else if (this.enemiesMap.size > 0 && - util.target.id === this.enemiesMap.entries().next().value[0]) { - const copies = Cast.toNumber(args.COPIES); - if (copies > 0 && copies <= 30) { - for (let i = 0; i < copies - 1; i++) { - this.createEnemyClone(util.target); - } + this.enemiesMap.get(util.target.id)) { + if (this.enemiesMap.size > 1) { // if there are already organism create one more + this.createEnemyClone(util.target, 1); + } + for (let i = 1; i < copies; i++) { + this.createEnemyClone(util.target); } } else { - return 'There is no organism or enemy definition'; + return 'Please, set it first as organism or enemies'; } } @@ -514,47 +536,45 @@ class Scratch3Botch { * now this block works with "when I start as a clone", botch-0.2 * @param {args} args args * @param {util} util util + * @returns {string} message * @since botch-0.2 */ behaveGeneral (args, util) { // check if its an organism or an enemy if (this.organismMap.size > 0 && this.organismMap.get(util.target.id)) { const org = this.organismMap.get(util.target.id); - if (!org.target.isOriginal) { // Only the clones are managed - if (org.health > 0) { - org.stepOrganism(this.enemiesMap); - } + if (org.health > 0) { + org.stepOrganism(this.enemiesMap, this.organismMap); + } - if (org.dead()) { - if (org.deadSignal()) { - this.runtime._hats.botch_isDeadHat.edgeActivated = false; - this.runtime.startHats( - 'botch_isDeadHat', null, org.target); - this.organismMap.delete(org.target.id); - } + if (org.dead()) { + if (org.deadSignal()) { + this.runtime._hats.botch_isDeadHat.edgeActivated = false; + this.runtime.startHats( + 'botch_isDeadHat', null, org.target); + this.organismMap.delete(org.target.id); } } } else if (this.enemiesMap.size > 0 && this.enemiesMap.get(util.target.id)) { const enemy = this.enemiesMap.get(util.target.id); - if (enemy && !enemy.target.isOriginal) { + if (enemy) { enemy.stepEnemy(this.organismMap, this.enemiesMap); } + } else { + return 'Please, set it first as organism or enemies'; } } reproduceChild (args, util) { const mr = MathUtil.clamp(Cast.toNumber(args.MR), 0, 100); if (this.organismMap.size > 0 && this.organismMap.get(util.target.id)) { - let org = this.organismMap.get(util.target.id); - if (util.target.isOriginal) { - org = this.originalOrg; - } + const org = this.organismMap.get(util.target.id); if (org) { if (org.health >= 0) { const newClone = this.botchUtil.createClone(org.target); if (newClone) { this.runtime.addTarget(newClone); - const newOrg = org.clone(mr, newClone); + const newOrg = org.clone(mr, newClone, true); newClone.clearEffects(); org.childNumber++; newOrg.currentName = `${org.currentName}.${org.childNumber}`; @@ -572,11 +592,13 @@ class Scratch3Botch { const newClone = this.botchUtil.createClone(enemy.target); if (newClone) { this.runtime.addTarget(newClone); - const newOrg = enemy.clone(mr, newClone); + const newOrg = enemy.clone(mr, newClone, false); newClone.clearEffects(); this.enemiesMap.set(newClone.id, newOrg); } } + } else { + return 'Please, set it first as organism or enemies'; } } @@ -874,11 +896,9 @@ class Scratch3Botch { let best = null; let max = -1; for (const org of this.organismMap.values()) { - if (!org.target.isOriginal) { - if (org.living > max) { - best = org; - max = org.living; - } + if (org.living > max) { + best = org; + max = org.living; } } return best; diff --git a/src/extensions/botch/organism.js b/src/extensions/botch/organism.js index 9836feb69d3..6f6a0360c6f 100644 --- a/src/extensions/botch/organism.js +++ b/src/extensions/botch/organism.js @@ -20,6 +20,7 @@ class Organism { * @param {RenderedTarget} target_ target (sprite) * @param {number} mass_ mass of the vehicle * @param {number} maxForce_ max force of the vehicle + * @param {boolean} org if true is an organism otherwise is an enemy * @param {Array} svgPoints_ svg points of the organism * @param {number} mutation how the organism can mutate [0 - 100] * @param {number} foodAttraction food attraction @@ -28,7 +29,7 @@ class Organism { * @param {number} enemySight enemy sight * @param {number} orgSize organism size (mass) */ - constructor (target_, mass_ = 1, maxForce_ = 0.5, svgPoints_, mutation, + constructor (target_, mass_ = 1, maxForce_ = 0.5, org, svgPoints_, mutation, foodAttraction, foodSight, enemyAttraction, enemySight, orgSize) { // utils @@ -97,18 +98,18 @@ class Organism { // if is not defined, do not generate if (svgPoints_) { - this.svg = this.svgGen.generateOrgSVG3( - 100, this.foodAttraction, this.enemyAttraction, this.max_att, - this.foodSight, this.enemySight, this.max_perception, svgPoints_, mutation); - this.botchUtil.uploadCostumeEdit(this.svg, this.target.id); - + if (org) { + this.svg = this.svgGen.generateOrgSVG3( + 100, this.foodAttraction, this.enemyAttraction, this.max_att, + this.foodSight, this.enemySight, this.max_perception, svgPoints_, mutation); + this.botchUtil.uploadCostumeEdit(this.svg, this.target.id); + } + this.target.setSize(this.size); /* for (let i = this.target.getCostumes().length - 1; i >= 0; i--) { if (i !== this.target.currentCostume) { this.target.deleteCostume(i); // hack troppo brutta ed instabile } } */ - - this.target.setSize(this.size); } else { this.svg = this.svgGen.generateOrgSVG3(100, this.foodAttraction, this.enemyAttraction, this.max_att, this.foodSight, this.enemySight, this.max_perception); @@ -133,14 +134,16 @@ class Organism { /** * Compute the step needed to move * @param {Map} enemiesMap enemiesMap + * @param {Map} organismMap organismMap * @since botch-0.2 */ - stepOrganism (enemiesMap) { + stepOrganism (enemiesMap, organismMap) { this.refreshArgs(this.mass, this.maxForce); - this.behaveGeneralOrganism(enemiesMap); this.boundaries( this.runtime.constructor.STAGE_WIDTH - 30, this.runtime.constructor.STAGE_HEIGHT - 30); + this.separation(organismMap, 10); + this.behaveGeneralOrganism(enemiesMap); this.update(); this.breathe(); } @@ -153,8 +156,8 @@ class Organism { */ stepEnemy (organismMap, enemiesMap) { this.boundaries( - this.runtime.constructor.STAGE_WIDTH - 150, - this.runtime.constructor.STAGE_HEIGHT - 150); + this.runtime.constructor.STAGE_WIDTH - 50, + this.runtime.constructor.STAGE_HEIGHT - 50); this.separation(enemiesMap, 10); this.refreshArgs(this.mass, this.maxForce); this.behaveEnemy(organismMap); @@ -265,7 +268,7 @@ class Organism { behaveEnemy (organism) { if (organism.size > 0) { const steerO = this.attack(organism); - steerO.mult(0.8); // TO DO, TO DEFINE + steerO.mult(1.1); // TO DO, TO DEFINE this.applyForce(steerO); } } @@ -284,14 +287,12 @@ class Organism { const esc = 10; for (const o of organism.values()) { - if (!o.target.isOriginal) { // do not consider the original - const d = new Vector2(o.target.x, o.target.y).dist(new Vector2(this.target.x, this.target.y)); - if (d < esc) { - o.health -= 0.1; - } else if (d < record && d < perception) { - record = d; - closest = o; - } + const d = new Vector2(o.target.x, o.target.y).dist(new Vector2(this.target.x, this.target.y)); + if (d < esc) { + o.health -= 0.1; + } else if (d < record && d < perception) { + record = d; + closest = o; } } @@ -379,30 +380,17 @@ class Organism { } } - /** - * Create a clone of itself "Parthenogenesis" - * @returns {Organism} new copy Organism - * @since botch-0.1 - */ - cloneProb () { - if (Math.random() < 0.002) { - const newOrg = new Organism(this.target, 1, 0.5, this.svgGen.getOrgPoints(), this.mutation, - this.foodAttraction, this.foodSight, this.enemyAttraction, this.enemySight, this.size); - return newOrg; - } - return null; - } - /** * Create a clone of itself "Parthenogenesis" * when called it return always a new child * @param {number} mutation how the organism will mutate [0 - 100] * @param {target} target new clone target + * @param {boolean} org if true is an organism otherwise is an enemy * @returns {Organism} new copy Organism * @since botch-0.2 */ - clone (mutation, target) { - const newOrg = new Organism(target, this.mass, 0.5, this.svgGen.getOrgPoints(), mutation, + clone (mutation, target, org) { + const newOrg = new Organism(target, this.mass, 0.5, org, this.svgGen.getOrgPoints(), mutation, this.foodAttraction, this.foodSight, this.enemyAttraction, this.enemySight, this.size); return newOrg; } @@ -539,18 +527,16 @@ class Organism { let counter = 0; const steer = new Vector2(0, 0); for (const o of organism.values()) { - if (!o.target.isOriginal) { // do not consider the original - if (o.target.id !== this.target.id) { - const d = new Vector2(o.target.x, o.target.y).dist(new Vector2(this.target.x, this.target.y)); - if (d < radius) { - const diff = Vector2.sub( - new Vector2(this.target.x, this.target.y), new Vector2(o.target.x, o.target.y) - ); - diff.normalize(); - diff.div(d); - steer.add(diff); - counter++; - } + if (o.target.id !== this.target.id) { + const d = new Vector2(o.target.x, o.target.y).dist(new Vector2(this.target.x, this.target.y)); + if (d < radius) { + const diff = Vector2.sub( + new Vector2(this.target.x, this.target.y), new Vector2(o.target.x, o.target.y) + ); + diff.normalize(); + diff.div(d); + steer.add(diff); + counter++; } } }