From 116a3e36c9be90ed6067304037050e21e44c3fdc Mon Sep 17 00:00:00 2001 From: PineappleBrain <62375288+PineappleBrain@users.noreply.github.com> Date: Thu, 21 Apr 2022 18:38:08 +0800 Subject: [PATCH 1/8] Update ActionComponent.js --- .../components/script/ActionComponent.js | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/gameClasses/components/script/ActionComponent.js b/src/gameClasses/components/script/ActionComponent.js index 0f52ed92..351cad70 100644 --- a/src/gameClasses/components/script/ActionComponent.js +++ b/src/gameClasses/components/script/ActionComponent.js @@ -1204,7 +1204,27 @@ var ActionComponent = IgeEntity.extend({ item.streamUpdateData([{ fireRate: value }]); } break; + + case 'setItemBulletForce': + var item = ige.variable.getValue(action.item, vars); + var value = ige.variable.getValue(action.number, vars); + + if (item && item._category == 'item') { + item.streamUpdateData([{ bulletForce: value }]); + } + break; + case 'setItemBulletStartPosition': + var item = ige.variable.getValue(action.item, vars); + var rotation = ige.variable.getValue(action.number1, vars); + var x = ige.variable.getValue(action.number2, vars); + var y = ige.variable.getValue(action.number3, vars); + + if (item && item._category == 'item') { + item.streamUpdateData([{ bulletStartPosition: { rotation: rotation, x: x, y: y } }]); + } + break; + case 'changeInventorySlotColor': var item = ige.variable.getValue(action.item, vars); var color = ige.variable.getValue(action.string, vars); From c9518879cd9c21e238da000c9acc026ac493736e Mon Sep 17 00:00:00 2001 From: PineappleBrain <62375288+PineappleBrain@users.noreply.github.com> Date: Thu, 21 Apr 2022 23:43:21 +0800 Subject: [PATCH 2/8] Update Item.js --- src/gameClasses/Item.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gameClasses/Item.js b/src/gameClasses/Item.js index 4f31ed34..53342d49 100644 --- a/src/gameClasses/Item.js +++ b/src/gameClasses/Item.js @@ -287,6 +287,8 @@ var Item = IgeEntityPhysics.extend({ if (owner && self._stats.currentBody && self._stats.currentBody.jointType == 'weldJoint') { rotate = owner._rotate.z; } + + rotate += self._stats.bulletStartPosition.rotation * Math.PI / 180; if (self.anchoredOffset == undefined) { self.anchoredOffset = { x: 0, y: 0, rotate: 0 }; From 51a2a318d3756eda471d967e05127129b9d7b870 Mon Sep 17 00:00:00 2001 From: PineappleBrain <62375288+PineappleBrain@users.noreply.github.com> Date: Thu, 21 Apr 2022 23:44:49 +0800 Subject: [PATCH 3/8] Update Item.js --- src/gameClasses/Item.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gameClasses/Item.js b/src/gameClasses/Item.js index 53342d49..ec1cfac8 100644 --- a/src/gameClasses/Item.js +++ b/src/gameClasses/Item.js @@ -287,7 +287,6 @@ var Item = IgeEntityPhysics.extend({ if (owner && self._stats.currentBody && self._stats.currentBody.jointType == 'weldJoint') { rotate = owner._rotate.z; } - rotate += self._stats.bulletStartPosition.rotation * Math.PI / 180; if (self.anchoredOffset == undefined) { From 995a2da3a0dadd7651b0f8c6912d9ff0998154b0 Mon Sep 17 00:00:00 2001 From: PineappleBrain <62375288+PineappleBrain@users.noreply.github.com> Date: Tue, 3 May 2022 21:16:11 +0800 Subject: [PATCH 4/8] Update Item.js --- src/gameClasses/Item.js | 511 ++++++++++++++++++++-------------------- 1 file changed, 259 insertions(+), 252 deletions(-) diff --git a/src/gameClasses/Item.js b/src/gameClasses/Item.js index ec1cfac8..43178ba9 100644 --- a/src/gameClasses/Item.js +++ b/src/gameClasses/Item.js @@ -251,300 +251,307 @@ var Item = IgeEntityPhysics.extend({ var player = owner && owner.getOwner(); var isUsed = false; - // if item has no owner, or item is unusable type, or it cannot be used by its current owner, then return - if (!owner || - (self._stats.canBeUsedBy && self._stats.canBeUsedBy.length > 0 && self._stats.canBeUsedBy.indexOf(owner._stats.type) == -1) || - self._stats.type === 'unusable') { - return; - } + setTimeout(() => { + // if item has no owner, or item is unusable type, or it cannot be used by its current owner, then return + if (!owner || + (self._stats.canBeUsedBy && self._stats.canBeUsedBy.length > 0 && self._stats.canBeUsedBy.indexOf(owner._stats.type) == -1) || + self._stats.type === 'unusable') { + return; + } - if (self.hasQuantityRemaining()) { - ige.game.lastUsedItemId = self.id(); + if (self.hasQuantityRemaining()) { + ige.game.lastUsedItemId = self.id(); - if ((self._stats.lastUsed + self._stats.fireRate < now) || self._stats.type == 'consumable') { - if (!self.canAffordItemCost()) { - ige.devLog('cannot afford item cost'); - return; - } - - isUsed = true; + if ((self._stats.lastUsed - self._stats.delayBeforeUse + self._stats.fireRate < now) || self._stats.type == 'consumable') { + if (!self.canAffordItemCost()) { + ige.devLog('cannot afford item cost'); + return; + } - // item must be ready to fire (accordingly to fire rate), and must have ammo or have infinite ammo - if (ige.isClient && self._stats.type == 'weapon' && self._stats.effects && self._stats.effects.use && self._stats.effects.use.animation) { - self.applyAnimationById(self._stats.effects.use.animation); - } + isUsed = true; - self._stats.lastUsed = ige.now; - ige.trigger && ige.trigger.fire('unitUsesItem', { - unitId: (owner) ? owner.id() : undefined, - itemId: self.id() - }); - - if (ige.physics && self._stats.type == 'weapon') { - if (self._stats.isGun) { - if (self._stats.bulletStartPosition) { - var rotate = this._rotate.z; - if (owner && self._stats.currentBody && self._stats.currentBody.jointType == 'weldJoint') { - rotate = owner._rotate.z; - } - rotate += self._stats.bulletStartPosition.rotation * Math.PI / 180; + // item must be ready to fire (accordingly to fire rate), and must have ammo or have infinite ammo + if (ige.isClient && self._stats.type == 'weapon' && self._stats.effects && self._stats.effects.use && self._stats.effects.use.animation) { + self.applyAnimationById(self._stats.effects.use.animation); + } - if (self.anchoredOffset == undefined) { - self.anchoredOffset = { x: 0, y: 0, rotate: 0 }; - } + self._stats.lastUsed = ige.now; + ige.trigger && ige.trigger.fire('unitUsesItem', { + unitId: (owner) ? owner.id() : undefined, + itemId: self.id() + }); + + if (ige.physics && self._stats.type == 'weapon') { + if (self._stats.isGun) { + if (self._stats.bulletStartPosition) { + var rotate = this._rotate.z; + if (owner && self._stats.currentBody && self._stats.currentBody.jointType == 'weldJoint') { + rotate = owner._rotate.z; + } + + // FIX + // fixed bulletStartPositionRotation + rotate += self._stats.bulletStartPosition.rotation * Math.PI / 180; + // FIX + + if (self.anchoredOffset == undefined) { + self.anchoredOffset = { x: 0, y: 0, rotate: 0 }; + } - var offsetAngle = rotate; - if (self._stats.flip == 1) { - offsetAngle += Math.PI; - } + var offsetAngle = rotate; + if (self._stats.flip == 1) { + offsetAngle += Math.PI; + } - // item is flipped, then mirror the rotation - if (owner._stats.flip == 1) { - var bulletY = -self._stats.bulletStartPosition.y || 0; - } else { - var bulletY = self._stats.bulletStartPosition.y || 0; - } + // item is flipped, then mirror the rotation + if (owner._stats.flip == 1) { + var bulletY = -self._stats.bulletStartPosition.y || 0; + } else { + var bulletY = self._stats.bulletStartPosition.y || 0; + } - var bulletStartPosition = { - x: (owner._translate.x + self.anchoredOffset.x) + (self._stats.bulletStartPosition.x * Math.cos(offsetAngle)) + (bulletY * Math.sin(offsetAngle)), - y: (owner._translate.y + self.anchoredOffset.y) + (self._stats.bulletStartPosition.x * Math.sin(offsetAngle)) - (bulletY * Math.cos(offsetAngle)) - }; - - if ( - this._stats.isGun && - (ige.isServer || (ige.isClient && ige.physics)) // render projectile on clientside if physics is enabled - ) { - var defaultData = { - rotate: rotate, - translate: bulletStartPosition + var bulletStartPosition = { + x: (owner._translate.x + self.anchoredOffset.x) + (self._stats.bulletStartPosition.x * Math.cos(offsetAngle)) + (bulletY * Math.sin(offsetAngle)), + y: (owner._translate.y + self.anchoredOffset.y) + (self._stats.bulletStartPosition.x * Math.sin(offsetAngle)) - (bulletY * Math.cos(offsetAngle)) }; - if (self.projectileData && (ige.isServer || (ige.isClient && !self._stats.projectileStreamMode))) { - defaultData.velocity = { - deployMethod: self._stats.deployMethod, - x: Math.cos(rotate + Math.radians(-90)) * self._stats.bulletForce, - y: Math.sin(rotate + Math.radians(-90)) * self._stats.bulletForce + if ( + this._stats.isGun && + (ige.isServer || (ige.isClient && ige.physics)) // render projectile on clientside if physics is enabled + ) { + var defaultData = { + rotate: rotate, + translate: bulletStartPosition }; - // console.log(self._stats.currentBody.type, "unit: ", angleToTarget, "item's rotate.z: ", self._rotate.z, "facing angle", itemrotate) - var data = Object.assign( - JSON.parse(JSON.stringify(self.projectileData)), - { - type: self._stats.projectileType, - sourceItemId: self.id(), - sourceUnitId: (owner) ? owner.id() : undefined, - defaultData: defaultData, - damageData: { - targetsAffected: this._stats.damage.targetsAffected, - sourceUnitId: owner.id(), - sourceItemId: self.id(), - sourcePlayerId: owner.getOwner().id(), - unitAttributes: this._stats.damage.unitAttributes, - playerAttributes: this._stats.damage.playerAttributes - } - }); - - var projectile = new Projectile(data); - ige.game.lastCreatedProjectileId = projectile.id(); - } - if (this._stats.bulletType == 'raycast') { - // starting from unit center position - var raycastStartPosition = { - x: owner._translate.x + (Math.cos(this._rotate.z + Math.radians(-90))) + (Math.cos(this._rotate.z)), - y: owner._translate.y + (Math.sin(this._rotate.z + Math.radians(-90))) + (Math.sin(this._rotate.z)) - }; - - if (self._stats.currentBody && (self._stats.currentBody.type == 'spriteOnly' || self._stats.currentBody.type == 'none')) { - var unitAnchorX = (self._stats.currentBody.unitAnchor != undefined) ? self._stats.currentBody.unitAnchor.x : 0; - var unitAnchorY = (self._stats.currentBody.unitAnchor != undefined) ? self._stats.currentBody.unitAnchor.y : 0; - - var endPosition = { - x: (owner._translate.x + unitAnchorX) + (this._stats.bulletDistance * Math.cos(owner._rotate.z + Math.radians(-90))), - y: (owner._translate.y + unitAnchorY) + (this._stats.bulletDistance * Math.sin(owner._rotate.z + Math.radians(-90))) - }; - } else { - var endPosition = { - x: (self._translate.x) + (this._stats.bulletDistance * Math.cos(self._rotate.z + Math.radians(-90))), - y: (self._translate.y) + (this._stats.bulletDistance * Math.sin(self._rotate.z + Math.radians(-90))) + if (self.projectileData && (ige.isServer || (ige.isClient && !self._stats.projectileStreamMode))) { + defaultData.velocity = { + deployMethod: self._stats.deployMethod, + x: Math.cos(rotate + Math.radians(-90)) * self._stats.bulletForce, + y: Math.sin(rotate + Math.radians(-90)) * self._stats.bulletForce }; + + // console.log(self._stats.currentBody.type, "unit: ", angleToTarget, "item's rotate.z: ", self._rotate.z, "facing angle", itemrotate) + var data = Object.assign( + JSON.parse(JSON.stringify(self.projectileData)), + { + type: self._stats.projectileType, + sourceItemId: self.id(), + sourceUnitId: (owner) ? owner.id() : undefined, + defaultData: defaultData, + damageData: { + targetsAffected: this._stats.damage.targetsAffected, + sourceUnitId: owner.id(), + sourceItemId: self.id(), + sourcePlayerId: owner.getOwner().id(), + unitAttributes: this._stats.damage.unitAttributes, + playerAttributes: this._stats.damage.playerAttributes + } + }); + + var projectile = new Projectile(data); + ige.game.lastCreatedProjectileId = projectile.id(); } + if (this._stats.bulletType == 'raycast') { + // starting from unit center position + var raycastStartPosition = { + x: owner._translate.x + (Math.cos(this._rotate.z + Math.radians(-90))) + (Math.cos(this._rotate.z)), + y: owner._translate.y + (Math.sin(this._rotate.z + Math.radians(-90))) + (Math.sin(this._rotate.z)) + }; - var raycastMultipleCallback = function () { - var def = {}; - // var e_maxCount = 3; - var raycastCollidesWith = self._stats.raycastCollidesWith; - def.m_points = []; - def.m_normals = []; - - def.ReportFixture = function (fixture, point, normal, fraction) { - var fixtureList = fixture.m_body.m_fixtureList; - var entity = fixtureList && fixtureList.igeId && ige.$(fixtureList.igeId); - if (entity) { - entity.lastRaycastCollisionPosition = { - x: point.x * self.scaleRatio, - y: point.y * self.scaleRatio - }; - entity.raycastFraction = fraction; - self.raycastTargets.push(entity); - } + if (self._stats.currentBody && (self._stats.currentBody.type == 'spriteOnly' || self._stats.currentBody.type == 'none')) { + var unitAnchorX = (self._stats.currentBody.unitAnchor != undefined) ? self._stats.currentBody.unitAnchor.x : 0; + var unitAnchorY = (self._stats.currentBody.unitAnchor != undefined) ? self._stats.currentBody.unitAnchor.y : 0; + + var endPosition = { + x: (owner._translate.x + unitAnchorX) + (this._stats.bulletDistance * Math.cos(owner._rotate.z + Math.radians(-90))), + y: (owner._translate.y + unitAnchorY) + (this._stats.bulletDistance * Math.sin(owner._rotate.z + Math.radians(-90))) + }; + } else { + var endPosition = { + x: (self._translate.x) + (this._stats.bulletDistance * Math.cos(self._rotate.z + Math.radians(-90))), + y: (self._translate.y) + (this._stats.bulletDistance * Math.sin(self._rotate.z + Math.radians(-90))) + }; + } - // var body = fixture.getBody(); - // var userData = body.getUserData(); - // if (userData) { - // if (userData == 0) { - // // By returning -1, we instruct the calling code to ignore this fixture - // // and continue the ray-cast to the next fixture. - // return -1.0; - // } - // } - - def.m_points.push(point); - def.m_normals.push(normal); - // By returning 1, we instruct the caller to continue without clipping the - // ray. - return 1.0; + var raycastMultipleCallback = function () { + var def = {}; + // var e_maxCount = 3; + var raycastCollidesWith = self._stats.raycastCollidesWith; + def.m_points = []; + def.m_normals = []; + + def.ReportFixture = function (fixture, point, normal, fraction) { + var fixtureList = fixture.m_body.m_fixtureList; + var entity = fixtureList && fixtureList.igeId && ige.$(fixtureList.igeId); + if (entity) { + entity.lastRaycastCollisionPosition = { + x: point.x * self.scaleRatio, + y: point.y * self.scaleRatio + }; + entity.raycastFraction = fraction; + self.raycastTargets.push(entity); + } + + // var body = fixture.getBody(); + // var userData = body.getUserData(); + // if (userData) { + // if (userData == 0) { + // // By returning -1, we instruct the calling code to ignore this fixture + // // and continue the ray-cast to the next fixture. + // return -1.0; + // } + // } + + def.m_points.push(point); + def.m_normals.push(normal); + // By returning 1, we instruct the caller to continue without clipping the + // ray. + return 1.0; + }; + + return def; }; - return def; - }; + var callback = raycastMultipleCallback(); + + // ige.physics.world().rayCast(, callback.ReportFixture); + ige.physics.world().rayCast( + callback.ReportFixture, + { + x: raycastStartPosition.x / self.scaleRatio, + y: raycastStartPosition.y / self.scaleRatio + }, + { + x: endPosition.x / self.scaleRatio, + y: endPosition.y / self.scaleRatio + } + ); - var callback = raycastMultipleCallback(); - - // ige.physics.world().rayCast(, callback.ReportFixture); - ige.physics.world().rayCast( - callback.ReportFixture, - { - x: raycastStartPosition.x / self.scaleRatio, - y: raycastStartPosition.y / self.scaleRatio - }, - { - x: endPosition.x / self.scaleRatio, - y: endPosition.y / self.scaleRatio + // if (!self._stats.penetration) { + ige.game.entitiesCollidingWithLastRaycast = _.orderBy(self.raycastTargets, ['raycastFraction'], ['asc']); + // } + ige.trigger && ige.trigger.fire('raycastItemFired', { + itemId: self.id() + }); + } + self.raycastTargets = []; + + if (self._stats.recoilForce) { + // apply recoil on its owner if item itself doesn't have physical body + if (self._stats.currentBody == undefined || self._stats.currentBody.type == 'none' || self._stats.currentBody.type == 'spriteOnly') { + owner.applyForce(self._stats.recoilForce * Math.cos(owner._rotate.z + Math.radians(90)), self._stats.recoilForce * Math.sin(owner._rotate.z + Math.radians(90))); + } else { // apply recoil on item + self.applyForce(self._stats.recoilForce * Math.cos(this._rotate.z + Math.radians(90)), self._stats.recoilForce * Math.sin(this._rotate.z + Math.radians(90))); } - ); - - // if (!self._stats.penetration) { - ige.game.entitiesCollidingWithLastRaycast = _.orderBy(self.raycastTargets, ['raycastFraction'], ['asc']); - // } - ige.trigger && ige.trigger.fire('raycastItemFired', { - itemId: self.id() - }); - } - self.raycastTargets = []; - - if (self._stats.recoilForce) { - // apply recoil on its owner if item itself doesn't have physical body - if (self._stats.currentBody == undefined || self._stats.currentBody.type == 'none' || self._stats.currentBody.type == 'spriteOnly') { - owner.applyForce(self._stats.recoilForce * Math.cos(owner._rotate.z + Math.radians(90)), self._stats.recoilForce * Math.sin(owner._rotate.z + Math.radians(90))); - } else { // apply recoil on item - self.applyForce(self._stats.recoilForce * Math.cos(this._rotate.z + Math.radians(90)), self._stats.recoilForce * Math.sin(this._rotate.z + Math.radians(90))); } } } - } - } else { // melee weapon - var hitboxData = this._stats.damageHitBox; - - if (hitboxData) { - // console.log(hitboxData); - var rotate = (owner.angleToTarget) ? owner.angleToTarget : 0; - var hitboxPosition = { - x: (owner._translate.x) + (hitboxData.offsetX * Math.cos(rotate)) + (hitboxData.offsetY * Math.sin(rotate)), - y: (owner._translate.y) + (hitboxData.offsetX * Math.sin(rotate)) - (hitboxData.offsetY * Math.cos(rotate)) - }; - - var hitbox = { - x: hitboxPosition.x - hitboxData.width, - y: hitboxPosition.y - hitboxData.width, - width: hitboxData.width * 2, - height: hitboxData.width * 2 // width is used as a radius - }; - - var damageData = { - targetsAffected: this._stats.damage.targetsAffected, - sourceUnitId: owner.id(), - sourceItemId: self.id(), - sourcePlayerId: owner.getOwner().id(), - unitAttributes: this._stats.damage.unitAttributes, - playerAttributes: this._stats.damage.playerAttributes - }; - // console.log(owner._translate.x, owner._translate.y, hitbox); //////////Hitbox log - - entities = ige.physics.getBodiesInRegion(hitbox); - - while (entities.length > 0) { - var entity = entities.shift(); - if (entity && entity._category == 'unit') { - entity.inflictDamage(damageData); + } else { // melee weapon + var hitboxData = this._stats.damageHitBox; + + if (hitboxData) { + // console.log(hitboxData); + var rotate = (owner.angleToTarget) ? owner.angleToTarget : 0; + var hitboxPosition = { + x: (owner._translate.x) + (hitboxData.offsetX * Math.cos(rotate)) + (hitboxData.offsetY * Math.sin(rotate)), + y: (owner._translate.y) + (hitboxData.offsetX * Math.sin(rotate)) - (hitboxData.offsetY * Math.cos(rotate)) + }; + + var hitbox = { + x: hitboxPosition.x - hitboxData.width, + y: hitboxPosition.y - hitboxData.width, + width: hitboxData.width * 2, + height: hitboxData.width * 2 // width is used as a radius + }; + + var damageData = { + targetsAffected: this._stats.damage.targetsAffected, + sourceUnitId: owner.id(), + sourceItemId: self.id(), + sourcePlayerId: owner.getOwner().id(), + unitAttributes: this._stats.damage.unitAttributes, + playerAttributes: this._stats.damage.playerAttributes + }; + // console.log(owner._translate.x, owner._translate.y, hitbox); //////////Hitbox log + + entities = ige.physics.getBodiesInRegion(hitbox); + + while (entities.length > 0) { + var entity = entities.shift(); + if (entity && entity._category == 'unit') { + entity.inflictDamage(damageData); + } } } } - } - } else if (self._stats.type == 'consumable') { // item is not a gun (e.g. consumable) - // if cost quantity of consumable item is not defined or 0 - // it should be 1 by default. Bcz 1 item will be consumed when fire. - // currently we dont have cost quantity setting in consumable items so - // this is handler for it. - - if (!self.quantityCost) { - self.quantityCost = 1; - } + } else if (self._stats.type == 'consumable') { // item is not a gun (e.g. consumable) + // if cost quantity of consumable item is not defined or 0 + // it should be 1 by default. Bcz 1 item will be consumed when fire. + // currently we dont have cost quantity setting in consumable items so + // this is handler for it. + + if (!self.quantityCost) { + self.quantityCost = 1; + } - attrData = { attributes: {} }; - if (self._stats.bonus && self._stats.bonus.consume) { - // apply unit bonuses - var unitAttributeBonuses = self._stats.bonus.consume.unitAttribute; - if (unitAttributeBonuses) { - for (var attrId in unitAttributeBonuses) { - if (attrData.attributes) { - var newValue = owner.attribute.getValue(attrId) + parseFloat(unitAttributeBonuses[attrId]); - attrData.attributes[attrId] = owner.attribute.update(attrId, newValue, true); + attrData = { attributes: {} }; + if (self._stats.bonus && self._stats.bonus.consume) { + // apply unit bonuses + var unitAttributeBonuses = self._stats.bonus.consume.unitAttribute; + if (unitAttributeBonuses) { + for (var attrId in unitAttributeBonuses) { + if (attrData.attributes) { + var newValue = owner.attribute.getValue(attrId) + parseFloat(unitAttributeBonuses[attrId]); + attrData.attributes[attrId] = owner.attribute.update(attrId, newValue, true); + } } } - } - if (player && player.attribute) { - // apply player bonuses - var playerAttributeBonuses = self._stats.bonus.consume.playerAttribute; - if (playerAttributeBonuses) { - for (attrId in playerAttributeBonuses) { - var newValue = player.attribute.getValue(attrId) + parseFloat(playerAttributeBonuses[attrId]); - attrData.attributes[attrId] = player.attribute.update(attrId, newValue, true); + if (player && player.attribute) { + // apply player bonuses + var playerAttributeBonuses = self._stats.bonus.consume.playerAttribute; + if (playerAttributeBonuses) { + for (attrId in playerAttributeBonuses) { + var newValue = player.attribute.getValue(attrId) + parseFloat(playerAttributeBonuses[attrId]); + attrData.attributes[attrId] = player.attribute.update(attrId, newValue, true); + } + } + + if (ige.isServer && self._stats && self._stats.bonus && self._stats.bonus.consume && self._stats.bonus.consume.coin) { + // ige.server.giveCoinToUser(player, self._stats.bonus.consume.coin, self._stats.name); + // player.streamUpdateData([{ + // coins: self._stats.bonus.consume.coin + player._stats.coins + // }]); } } - if (ige.isServer && self._stats && self._stats.bonus && self._stats.bonus.consume && self._stats.bonus.consume.coin) { - // ige.server.giveCoinToUser(player, self._stats.bonus.consume.coin, self._stats.name); - // player.streamUpdateData([{ - // coins: self._stats.bonus.consume.coin + player._stats.coins - // }]); + if (ige.isServer) { + owner.streamUpdateData(attrData); } } - if (ige.isServer) { - owner.streamUpdateData(attrData); - } + self.stopUsing(); // stop using immediately after use. } - - self.stopUsing(); // stop using immediately after use. } - } - // lowering the quantity by self.quantityCost - } else { // quantity is 0 - self.stopUsing(); - } + // lowering the quantity by self.quantityCost + } else { // quantity is 0 + self.stopUsing(); + } - if (isUsed && ige.isClient) { - this.playEffect('use'); - } + if (isUsed && ige.isClient) { + this.playEffect('use'); + } - if (self._stats.quantity != null || self._stats.quantity != undefined) { - // ige.devLog(isUsed, self._stats.quantity , self._stats.quantity > 0) - if (isUsed && self._stats.quantity > 0) { - self.updateQuantity(self._stats.quantity - self.quantityCost); + if (self._stats.quantity != null || self._stats.quantity != undefined) { + // ige.devLog(isUsed, self._stats.quantity , self._stats.quantity > 0) + if (isUsed && self._stats.quantity > 0) { + self.updateQuantity(self._stats.quantity - self.quantityCost); + } } - } + + }, self._stats.delayBeforeUse); }, updateQuantity: function (qty) { From 78f2edf01c32c707881a9c5dda4160f83247655a Mon Sep 17 00:00:00 2001 From: PineappleBrain <62375288+PineappleBrain@users.noreply.github.com> Date: Tue, 3 May 2022 21:25:11 +0800 Subject: [PATCH 5/8] Update Item.js --- src/gameClasses/Item.js | 510 ++++++++++++++++++++-------------------- 1 file changed, 251 insertions(+), 259 deletions(-) diff --git a/src/gameClasses/Item.js b/src/gameClasses/Item.js index 43178ba9..4f31ed34 100644 --- a/src/gameClasses/Item.js +++ b/src/gameClasses/Item.js @@ -251,307 +251,299 @@ var Item = IgeEntityPhysics.extend({ var player = owner && owner.getOwner(); var isUsed = false; - setTimeout(() => { - // if item has no owner, or item is unusable type, or it cannot be used by its current owner, then return - if (!owner || - (self._stats.canBeUsedBy && self._stats.canBeUsedBy.length > 0 && self._stats.canBeUsedBy.indexOf(owner._stats.type) == -1) || - self._stats.type === 'unusable') { - return; - } + // if item has no owner, or item is unusable type, or it cannot be used by its current owner, then return + if (!owner || + (self._stats.canBeUsedBy && self._stats.canBeUsedBy.length > 0 && self._stats.canBeUsedBy.indexOf(owner._stats.type) == -1) || + self._stats.type === 'unusable') { + return; + } - if (self.hasQuantityRemaining()) { - ige.game.lastUsedItemId = self.id(); + if (self.hasQuantityRemaining()) { + ige.game.lastUsedItemId = self.id(); - if ((self._stats.lastUsed - self._stats.delayBeforeUse + self._stats.fireRate < now) || self._stats.type == 'consumable') { - if (!self.canAffordItemCost()) { - ige.devLog('cannot afford item cost'); - return; - } + if ((self._stats.lastUsed + self._stats.fireRate < now) || self._stats.type == 'consumable') { + if (!self.canAffordItemCost()) { + ige.devLog('cannot afford item cost'); + return; + } - isUsed = true; + isUsed = true; - // item must be ready to fire (accordingly to fire rate), and must have ammo or have infinite ammo - if (ige.isClient && self._stats.type == 'weapon' && self._stats.effects && self._stats.effects.use && self._stats.effects.use.animation) { - self.applyAnimationById(self._stats.effects.use.animation); - } + // item must be ready to fire (accordingly to fire rate), and must have ammo or have infinite ammo + if (ige.isClient && self._stats.type == 'weapon' && self._stats.effects && self._stats.effects.use && self._stats.effects.use.animation) { + self.applyAnimationById(self._stats.effects.use.animation); + } - self._stats.lastUsed = ige.now; - ige.trigger && ige.trigger.fire('unitUsesItem', { - unitId: (owner) ? owner.id() : undefined, - itemId: self.id() - }); - - if (ige.physics && self._stats.type == 'weapon') { - if (self._stats.isGun) { - if (self._stats.bulletStartPosition) { - var rotate = this._rotate.z; - if (owner && self._stats.currentBody && self._stats.currentBody.jointType == 'weldJoint') { - rotate = owner._rotate.z; - } - - // FIX - // fixed bulletStartPositionRotation - rotate += self._stats.bulletStartPosition.rotation * Math.PI / 180; - // FIX - - if (self.anchoredOffset == undefined) { - self.anchoredOffset = { x: 0, y: 0, rotate: 0 }; - } + self._stats.lastUsed = ige.now; + ige.trigger && ige.trigger.fire('unitUsesItem', { + unitId: (owner) ? owner.id() : undefined, + itemId: self.id() + }); - var offsetAngle = rotate; - if (self._stats.flip == 1) { - offsetAngle += Math.PI; - } + if (ige.physics && self._stats.type == 'weapon') { + if (self._stats.isGun) { + if (self._stats.bulletStartPosition) { + var rotate = this._rotate.z; + if (owner && self._stats.currentBody && self._stats.currentBody.jointType == 'weldJoint') { + rotate = owner._rotate.z; + } - // item is flipped, then mirror the rotation - if (owner._stats.flip == 1) { - var bulletY = -self._stats.bulletStartPosition.y || 0; - } else { - var bulletY = self._stats.bulletStartPosition.y || 0; - } + if (self.anchoredOffset == undefined) { + self.anchoredOffset = { x: 0, y: 0, rotate: 0 }; + } + + var offsetAngle = rotate; + if (self._stats.flip == 1) { + offsetAngle += Math.PI; + } - var bulletStartPosition = { - x: (owner._translate.x + self.anchoredOffset.x) + (self._stats.bulletStartPosition.x * Math.cos(offsetAngle)) + (bulletY * Math.sin(offsetAngle)), - y: (owner._translate.y + self.anchoredOffset.y) + (self._stats.bulletStartPosition.x * Math.sin(offsetAngle)) - (bulletY * Math.cos(offsetAngle)) + // item is flipped, then mirror the rotation + if (owner._stats.flip == 1) { + var bulletY = -self._stats.bulletStartPosition.y || 0; + } else { + var bulletY = self._stats.bulletStartPosition.y || 0; + } + + var bulletStartPosition = { + x: (owner._translate.x + self.anchoredOffset.x) + (self._stats.bulletStartPosition.x * Math.cos(offsetAngle)) + (bulletY * Math.sin(offsetAngle)), + y: (owner._translate.y + self.anchoredOffset.y) + (self._stats.bulletStartPosition.x * Math.sin(offsetAngle)) - (bulletY * Math.cos(offsetAngle)) + }; + + if ( + this._stats.isGun && + (ige.isServer || (ige.isClient && ige.physics)) // render projectile on clientside if physics is enabled + ) { + var defaultData = { + rotate: rotate, + translate: bulletStartPosition }; - if ( - this._stats.isGun && - (ige.isServer || (ige.isClient && ige.physics)) // render projectile on clientside if physics is enabled - ) { - var defaultData = { - rotate: rotate, - translate: bulletStartPosition + if (self.projectileData && (ige.isServer || (ige.isClient && !self._stats.projectileStreamMode))) { + defaultData.velocity = { + deployMethod: self._stats.deployMethod, + x: Math.cos(rotate + Math.radians(-90)) * self._stats.bulletForce, + y: Math.sin(rotate + Math.radians(-90)) * self._stats.bulletForce }; - if (self.projectileData && (ige.isServer || (ige.isClient && !self._stats.projectileStreamMode))) { - defaultData.velocity = { - deployMethod: self._stats.deployMethod, - x: Math.cos(rotate + Math.radians(-90)) * self._stats.bulletForce, - y: Math.sin(rotate + Math.radians(-90)) * self._stats.bulletForce - }; - - // console.log(self._stats.currentBody.type, "unit: ", angleToTarget, "item's rotate.z: ", self._rotate.z, "facing angle", itemrotate) - var data = Object.assign( - JSON.parse(JSON.stringify(self.projectileData)), - { - type: self._stats.projectileType, + // console.log(self._stats.currentBody.type, "unit: ", angleToTarget, "item's rotate.z: ", self._rotate.z, "facing angle", itemrotate) + var data = Object.assign( + JSON.parse(JSON.stringify(self.projectileData)), + { + type: self._stats.projectileType, + sourceItemId: self.id(), + sourceUnitId: (owner) ? owner.id() : undefined, + defaultData: defaultData, + damageData: { + targetsAffected: this._stats.damage.targetsAffected, + sourceUnitId: owner.id(), sourceItemId: self.id(), - sourceUnitId: (owner) ? owner.id() : undefined, - defaultData: defaultData, - damageData: { - targetsAffected: this._stats.damage.targetsAffected, - sourceUnitId: owner.id(), - sourceItemId: self.id(), - sourcePlayerId: owner.getOwner().id(), - unitAttributes: this._stats.damage.unitAttributes, - playerAttributes: this._stats.damage.playerAttributes - } - }); - - var projectile = new Projectile(data); - ige.game.lastCreatedProjectileId = projectile.id(); - } - if (this._stats.bulletType == 'raycast') { - // starting from unit center position - var raycastStartPosition = { - x: owner._translate.x + (Math.cos(this._rotate.z + Math.radians(-90))) + (Math.cos(this._rotate.z)), - y: owner._translate.y + (Math.sin(this._rotate.z + Math.radians(-90))) + (Math.sin(this._rotate.z)) - }; - - if (self._stats.currentBody && (self._stats.currentBody.type == 'spriteOnly' || self._stats.currentBody.type == 'none')) { - var unitAnchorX = (self._stats.currentBody.unitAnchor != undefined) ? self._stats.currentBody.unitAnchor.x : 0; - var unitAnchorY = (self._stats.currentBody.unitAnchor != undefined) ? self._stats.currentBody.unitAnchor.y : 0; - - var endPosition = { - x: (owner._translate.x + unitAnchorX) + (this._stats.bulletDistance * Math.cos(owner._rotate.z + Math.radians(-90))), - y: (owner._translate.y + unitAnchorY) + (this._stats.bulletDistance * Math.sin(owner._rotate.z + Math.radians(-90))) - }; - } else { - var endPosition = { - x: (self._translate.x) + (this._stats.bulletDistance * Math.cos(self._rotate.z + Math.radians(-90))), - y: (self._translate.y) + (this._stats.bulletDistance * Math.sin(self._rotate.z + Math.radians(-90))) - }; - } + sourcePlayerId: owner.getOwner().id(), + unitAttributes: this._stats.damage.unitAttributes, + playerAttributes: this._stats.damage.playerAttributes + } + }); - var raycastMultipleCallback = function () { - var def = {}; - // var e_maxCount = 3; - var raycastCollidesWith = self._stats.raycastCollidesWith; - def.m_points = []; - def.m_normals = []; - - def.ReportFixture = function (fixture, point, normal, fraction) { - var fixtureList = fixture.m_body.m_fixtureList; - var entity = fixtureList && fixtureList.igeId && ige.$(fixtureList.igeId); - if (entity) { - entity.lastRaycastCollisionPosition = { - x: point.x * self.scaleRatio, - y: point.y * self.scaleRatio - }; - entity.raycastFraction = fraction; - self.raycastTargets.push(entity); - } - - // var body = fixture.getBody(); - // var userData = body.getUserData(); - // if (userData) { - // if (userData == 0) { - // // By returning -1, we instruct the calling code to ignore this fixture - // // and continue the ray-cast to the next fixture. - // return -1.0; - // } - // } - - def.m_points.push(point); - def.m_normals.push(normal); - // By returning 1, we instruct the caller to continue without clipping the - // ray. - return 1.0; - }; - - return def; - }; + var projectile = new Projectile(data); + ige.game.lastCreatedProjectileId = projectile.id(); + } + if (this._stats.bulletType == 'raycast') { + // starting from unit center position + var raycastStartPosition = { + x: owner._translate.x + (Math.cos(this._rotate.z + Math.radians(-90))) + (Math.cos(this._rotate.z)), + y: owner._translate.y + (Math.sin(this._rotate.z + Math.radians(-90))) + (Math.sin(this._rotate.z)) + }; - var callback = raycastMultipleCallback(); - - // ige.physics.world().rayCast(, callback.ReportFixture); - ige.physics.world().rayCast( - callback.ReportFixture, - { - x: raycastStartPosition.x / self.scaleRatio, - y: raycastStartPosition.y / self.scaleRatio - }, - { - x: endPosition.x / self.scaleRatio, - y: endPosition.y / self.scaleRatio - } - ); + if (self._stats.currentBody && (self._stats.currentBody.type == 'spriteOnly' || self._stats.currentBody.type == 'none')) { + var unitAnchorX = (self._stats.currentBody.unitAnchor != undefined) ? self._stats.currentBody.unitAnchor.x : 0; + var unitAnchorY = (self._stats.currentBody.unitAnchor != undefined) ? self._stats.currentBody.unitAnchor.y : 0; - // if (!self._stats.penetration) { - ige.game.entitiesCollidingWithLastRaycast = _.orderBy(self.raycastTargets, ['raycastFraction'], ['asc']); - // } - ige.trigger && ige.trigger.fire('raycastItemFired', { - itemId: self.id() - }); - } - self.raycastTargets = []; - - if (self._stats.recoilForce) { - // apply recoil on its owner if item itself doesn't have physical body - if (self._stats.currentBody == undefined || self._stats.currentBody.type == 'none' || self._stats.currentBody.type == 'spriteOnly') { - owner.applyForce(self._stats.recoilForce * Math.cos(owner._rotate.z + Math.radians(90)), self._stats.recoilForce * Math.sin(owner._rotate.z + Math.radians(90))); - } else { // apply recoil on item - self.applyForce(self._stats.recoilForce * Math.cos(this._rotate.z + Math.radians(90)), self._stats.recoilForce * Math.sin(this._rotate.z + Math.radians(90))); - } + var endPosition = { + x: (owner._translate.x + unitAnchorX) + (this._stats.bulletDistance * Math.cos(owner._rotate.z + Math.radians(-90))), + y: (owner._translate.y + unitAnchorY) + (this._stats.bulletDistance * Math.sin(owner._rotate.z + Math.radians(-90))) + }; + } else { + var endPosition = { + x: (self._translate.x) + (this._stats.bulletDistance * Math.cos(self._rotate.z + Math.radians(-90))), + y: (self._translate.y) + (this._stats.bulletDistance * Math.sin(self._rotate.z + Math.radians(-90))) + }; } - } - } - } else { // melee weapon - var hitboxData = this._stats.damageHitBox; - - if (hitboxData) { - // console.log(hitboxData); - var rotate = (owner.angleToTarget) ? owner.angleToTarget : 0; - var hitboxPosition = { - x: (owner._translate.x) + (hitboxData.offsetX * Math.cos(rotate)) + (hitboxData.offsetY * Math.sin(rotate)), - y: (owner._translate.y) + (hitboxData.offsetX * Math.sin(rotate)) - (hitboxData.offsetY * Math.cos(rotate)) - }; - var hitbox = { - x: hitboxPosition.x - hitboxData.width, - y: hitboxPosition.y - hitboxData.width, - width: hitboxData.width * 2, - height: hitboxData.width * 2 // width is used as a radius - }; + var raycastMultipleCallback = function () { + var def = {}; + // var e_maxCount = 3; + var raycastCollidesWith = self._stats.raycastCollidesWith; + def.m_points = []; + def.m_normals = []; + + def.ReportFixture = function (fixture, point, normal, fraction) { + var fixtureList = fixture.m_body.m_fixtureList; + var entity = fixtureList && fixtureList.igeId && ige.$(fixtureList.igeId); + if (entity) { + entity.lastRaycastCollisionPosition = { + x: point.x * self.scaleRatio, + y: point.y * self.scaleRatio + }; + entity.raycastFraction = fraction; + self.raycastTargets.push(entity); + } - var damageData = { - targetsAffected: this._stats.damage.targetsAffected, - sourceUnitId: owner.id(), - sourceItemId: self.id(), - sourcePlayerId: owner.getOwner().id(), - unitAttributes: this._stats.damage.unitAttributes, - playerAttributes: this._stats.damage.playerAttributes - }; - // console.log(owner._translate.x, owner._translate.y, hitbox); //////////Hitbox log + // var body = fixture.getBody(); + // var userData = body.getUserData(); + // if (userData) { + // if (userData == 0) { + // // By returning -1, we instruct the calling code to ignore this fixture + // // and continue the ray-cast to the next fixture. + // return -1.0; + // } + // } + + def.m_points.push(point); + def.m_normals.push(normal); + // By returning 1, we instruct the caller to continue without clipping the + // ray. + return 1.0; + }; - entities = ige.physics.getBodiesInRegion(hitbox); + return def; + }; - while (entities.length > 0) { - var entity = entities.shift(); - if (entity && entity._category == 'unit') { - entity.inflictDamage(damageData); + var callback = raycastMultipleCallback(); + + // ige.physics.world().rayCast(, callback.ReportFixture); + ige.physics.world().rayCast( + callback.ReportFixture, + { + x: raycastStartPosition.x / self.scaleRatio, + y: raycastStartPosition.y / self.scaleRatio + }, + { + x: endPosition.x / self.scaleRatio, + y: endPosition.y / self.scaleRatio + } + ); + + // if (!self._stats.penetration) { + ige.game.entitiesCollidingWithLastRaycast = _.orderBy(self.raycastTargets, ['raycastFraction'], ['asc']); + // } + ige.trigger && ige.trigger.fire('raycastItemFired', { + itemId: self.id() + }); + } + self.raycastTargets = []; + + if (self._stats.recoilForce) { + // apply recoil on its owner if item itself doesn't have physical body + if (self._stats.currentBody == undefined || self._stats.currentBody.type == 'none' || self._stats.currentBody.type == 'spriteOnly') { + owner.applyForce(self._stats.recoilForce * Math.cos(owner._rotate.z + Math.radians(90)), self._stats.recoilForce * Math.sin(owner._rotate.z + Math.radians(90))); + } else { // apply recoil on item + self.applyForce(self._stats.recoilForce * Math.cos(this._rotate.z + Math.radians(90)), self._stats.recoilForce * Math.sin(this._rotate.z + Math.radians(90))); } } } } - } else if (self._stats.type == 'consumable') { // item is not a gun (e.g. consumable) - // if cost quantity of consumable item is not defined or 0 - // it should be 1 by default. Bcz 1 item will be consumed when fire. - // currently we dont have cost quantity setting in consumable items so - // this is handler for it. - - if (!self.quantityCost) { - self.quantityCost = 1; - } - - attrData = { attributes: {} }; - if (self._stats.bonus && self._stats.bonus.consume) { - // apply unit bonuses - var unitAttributeBonuses = self._stats.bonus.consume.unitAttribute; - if (unitAttributeBonuses) { - for (var attrId in unitAttributeBonuses) { - if (attrData.attributes) { - var newValue = owner.attribute.getValue(attrId) + parseFloat(unitAttributeBonuses[attrId]); - attrData.attributes[attrId] = owner.attribute.update(attrId, newValue, true); - } + } else { // melee weapon + var hitboxData = this._stats.damageHitBox; + + if (hitboxData) { + // console.log(hitboxData); + var rotate = (owner.angleToTarget) ? owner.angleToTarget : 0; + var hitboxPosition = { + x: (owner._translate.x) + (hitboxData.offsetX * Math.cos(rotate)) + (hitboxData.offsetY * Math.sin(rotate)), + y: (owner._translate.y) + (hitboxData.offsetX * Math.sin(rotate)) - (hitboxData.offsetY * Math.cos(rotate)) + }; + + var hitbox = { + x: hitboxPosition.x - hitboxData.width, + y: hitboxPosition.y - hitboxData.width, + width: hitboxData.width * 2, + height: hitboxData.width * 2 // width is used as a radius + }; + + var damageData = { + targetsAffected: this._stats.damage.targetsAffected, + sourceUnitId: owner.id(), + sourceItemId: self.id(), + sourcePlayerId: owner.getOwner().id(), + unitAttributes: this._stats.damage.unitAttributes, + playerAttributes: this._stats.damage.playerAttributes + }; + // console.log(owner._translate.x, owner._translate.y, hitbox); //////////Hitbox log + + entities = ige.physics.getBodiesInRegion(hitbox); + + while (entities.length > 0) { + var entity = entities.shift(); + if (entity && entity._category == 'unit') { + entity.inflictDamage(damageData); } } + } + } + } else if (self._stats.type == 'consumable') { // item is not a gun (e.g. consumable) + // if cost quantity of consumable item is not defined or 0 + // it should be 1 by default. Bcz 1 item will be consumed when fire. + // currently we dont have cost quantity setting in consumable items so + // this is handler for it. + + if (!self.quantityCost) { + self.quantityCost = 1; + } - if (player && player.attribute) { - // apply player bonuses - var playerAttributeBonuses = self._stats.bonus.consume.playerAttribute; - if (playerAttributeBonuses) { - for (attrId in playerAttributeBonuses) { - var newValue = player.attribute.getValue(attrId) + parseFloat(playerAttributeBonuses[attrId]); - attrData.attributes[attrId] = player.attribute.update(attrId, newValue, true); - } + attrData = { attributes: {} }; + if (self._stats.bonus && self._stats.bonus.consume) { + // apply unit bonuses + var unitAttributeBonuses = self._stats.bonus.consume.unitAttribute; + if (unitAttributeBonuses) { + for (var attrId in unitAttributeBonuses) { + if (attrData.attributes) { + var newValue = owner.attribute.getValue(attrId) + parseFloat(unitAttributeBonuses[attrId]); + attrData.attributes[attrId] = owner.attribute.update(attrId, newValue, true); } + } + } - if (ige.isServer && self._stats && self._stats.bonus && self._stats.bonus.consume && self._stats.bonus.consume.coin) { - // ige.server.giveCoinToUser(player, self._stats.bonus.consume.coin, self._stats.name); - // player.streamUpdateData([{ - // coins: self._stats.bonus.consume.coin + player._stats.coins - // }]); + if (player && player.attribute) { + // apply player bonuses + var playerAttributeBonuses = self._stats.bonus.consume.playerAttribute; + if (playerAttributeBonuses) { + for (attrId in playerAttributeBonuses) { + var newValue = player.attribute.getValue(attrId) + parseFloat(playerAttributeBonuses[attrId]); + attrData.attributes[attrId] = player.attribute.update(attrId, newValue, true); } } - if (ige.isServer) { - owner.streamUpdateData(attrData); + if (ige.isServer && self._stats && self._stats.bonus && self._stats.bonus.consume && self._stats.bonus.consume.coin) { + // ige.server.giveCoinToUser(player, self._stats.bonus.consume.coin, self._stats.name); + // player.streamUpdateData([{ + // coins: self._stats.bonus.consume.coin + player._stats.coins + // }]); } } - self.stopUsing(); // stop using immediately after use. + if (ige.isServer) { + owner.streamUpdateData(attrData); + } } - } - // lowering the quantity by self.quantityCost - } else { // quantity is 0 - self.stopUsing(); + self.stopUsing(); // stop using immediately after use. + } } - if (isUsed && ige.isClient) { - this.playEffect('use'); - } + // lowering the quantity by self.quantityCost + } else { // quantity is 0 + self.stopUsing(); + } - if (self._stats.quantity != null || self._stats.quantity != undefined) { - // ige.devLog(isUsed, self._stats.quantity , self._stats.quantity > 0) - if (isUsed && self._stats.quantity > 0) { - self.updateQuantity(self._stats.quantity - self.quantityCost); - } + if (isUsed && ige.isClient) { + this.playEffect('use'); + } + + if (self._stats.quantity != null || self._stats.quantity != undefined) { + // ige.devLog(isUsed, self._stats.quantity , self._stats.quantity > 0) + if (isUsed && self._stats.quantity > 0) { + self.updateQuantity(self._stats.quantity - self.quantityCost); } - - }, self._stats.delayBeforeUse); + } }, updateQuantity: function (qty) { From 9b14c5dc9912328f304fda28cedf287dd8797e14 Mon Sep 17 00:00:00 2001 From: PineappleBrain <62375288+PineappleBrain@users.noreply.github.com> Date: Tue, 3 May 2022 21:26:25 +0800 Subject: [PATCH 6/8] Update Item.js --- src/gameClasses/Item.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gameClasses/Item.js b/src/gameClasses/Item.js index 4f31ed34..ec1cfac8 100644 --- a/src/gameClasses/Item.js +++ b/src/gameClasses/Item.js @@ -287,6 +287,7 @@ var Item = IgeEntityPhysics.extend({ if (owner && self._stats.currentBody && self._stats.currentBody.jointType == 'weldJoint') { rotate = owner._rotate.z; } + rotate += self._stats.bulletStartPosition.rotation * Math.PI / 180; if (self.anchoredOffset == undefined) { self.anchoredOffset = { x: 0, y: 0, rotate: 0 }; From 71cbcc4215519265812dddcaf5b54bb0dc6b7945 Mon Sep 17 00:00:00 2001 From: PineappleBrain <62375288+PineappleBrain@users.noreply.github.com> Date: Tue, 3 May 2022 21:38:15 +0800 Subject: [PATCH 7/8] delay before use --- src/gameClasses/Item.js | 511 ++++++++++++++++++++-------------------- 1 file changed, 259 insertions(+), 252 deletions(-) diff --git a/src/gameClasses/Item.js b/src/gameClasses/Item.js index ec1cfac8..43178ba9 100644 --- a/src/gameClasses/Item.js +++ b/src/gameClasses/Item.js @@ -251,300 +251,307 @@ var Item = IgeEntityPhysics.extend({ var player = owner && owner.getOwner(); var isUsed = false; - // if item has no owner, or item is unusable type, or it cannot be used by its current owner, then return - if (!owner || - (self._stats.canBeUsedBy && self._stats.canBeUsedBy.length > 0 && self._stats.canBeUsedBy.indexOf(owner._stats.type) == -1) || - self._stats.type === 'unusable') { - return; - } + setTimeout(() => { + // if item has no owner, or item is unusable type, or it cannot be used by its current owner, then return + if (!owner || + (self._stats.canBeUsedBy && self._stats.canBeUsedBy.length > 0 && self._stats.canBeUsedBy.indexOf(owner._stats.type) == -1) || + self._stats.type === 'unusable') { + return; + } - if (self.hasQuantityRemaining()) { - ige.game.lastUsedItemId = self.id(); + if (self.hasQuantityRemaining()) { + ige.game.lastUsedItemId = self.id(); - if ((self._stats.lastUsed + self._stats.fireRate < now) || self._stats.type == 'consumable') { - if (!self.canAffordItemCost()) { - ige.devLog('cannot afford item cost'); - return; - } - - isUsed = true; + if ((self._stats.lastUsed - self._stats.delayBeforeUse + self._stats.fireRate < now) || self._stats.type == 'consumable') { + if (!self.canAffordItemCost()) { + ige.devLog('cannot afford item cost'); + return; + } - // item must be ready to fire (accordingly to fire rate), and must have ammo or have infinite ammo - if (ige.isClient && self._stats.type == 'weapon' && self._stats.effects && self._stats.effects.use && self._stats.effects.use.animation) { - self.applyAnimationById(self._stats.effects.use.animation); - } + isUsed = true; - self._stats.lastUsed = ige.now; - ige.trigger && ige.trigger.fire('unitUsesItem', { - unitId: (owner) ? owner.id() : undefined, - itemId: self.id() - }); - - if (ige.physics && self._stats.type == 'weapon') { - if (self._stats.isGun) { - if (self._stats.bulletStartPosition) { - var rotate = this._rotate.z; - if (owner && self._stats.currentBody && self._stats.currentBody.jointType == 'weldJoint') { - rotate = owner._rotate.z; - } - rotate += self._stats.bulletStartPosition.rotation * Math.PI / 180; + // item must be ready to fire (accordingly to fire rate), and must have ammo or have infinite ammo + if (ige.isClient && self._stats.type == 'weapon' && self._stats.effects && self._stats.effects.use && self._stats.effects.use.animation) { + self.applyAnimationById(self._stats.effects.use.animation); + } - if (self.anchoredOffset == undefined) { - self.anchoredOffset = { x: 0, y: 0, rotate: 0 }; - } + self._stats.lastUsed = ige.now; + ige.trigger && ige.trigger.fire('unitUsesItem', { + unitId: (owner) ? owner.id() : undefined, + itemId: self.id() + }); + + if (ige.physics && self._stats.type == 'weapon') { + if (self._stats.isGun) { + if (self._stats.bulletStartPosition) { + var rotate = this._rotate.z; + if (owner && self._stats.currentBody && self._stats.currentBody.jointType == 'weldJoint') { + rotate = owner._rotate.z; + } + + // FIX + // fixed bulletStartPositionRotation + rotate += self._stats.bulletStartPosition.rotation * Math.PI / 180; + // FIX + + if (self.anchoredOffset == undefined) { + self.anchoredOffset = { x: 0, y: 0, rotate: 0 }; + } - var offsetAngle = rotate; - if (self._stats.flip == 1) { - offsetAngle += Math.PI; - } + var offsetAngle = rotate; + if (self._stats.flip == 1) { + offsetAngle += Math.PI; + } - // item is flipped, then mirror the rotation - if (owner._stats.flip == 1) { - var bulletY = -self._stats.bulletStartPosition.y || 0; - } else { - var bulletY = self._stats.bulletStartPosition.y || 0; - } + // item is flipped, then mirror the rotation + if (owner._stats.flip == 1) { + var bulletY = -self._stats.bulletStartPosition.y || 0; + } else { + var bulletY = self._stats.bulletStartPosition.y || 0; + } - var bulletStartPosition = { - x: (owner._translate.x + self.anchoredOffset.x) + (self._stats.bulletStartPosition.x * Math.cos(offsetAngle)) + (bulletY * Math.sin(offsetAngle)), - y: (owner._translate.y + self.anchoredOffset.y) + (self._stats.bulletStartPosition.x * Math.sin(offsetAngle)) - (bulletY * Math.cos(offsetAngle)) - }; - - if ( - this._stats.isGun && - (ige.isServer || (ige.isClient && ige.physics)) // render projectile on clientside if physics is enabled - ) { - var defaultData = { - rotate: rotate, - translate: bulletStartPosition + var bulletStartPosition = { + x: (owner._translate.x + self.anchoredOffset.x) + (self._stats.bulletStartPosition.x * Math.cos(offsetAngle)) + (bulletY * Math.sin(offsetAngle)), + y: (owner._translate.y + self.anchoredOffset.y) + (self._stats.bulletStartPosition.x * Math.sin(offsetAngle)) - (bulletY * Math.cos(offsetAngle)) }; - if (self.projectileData && (ige.isServer || (ige.isClient && !self._stats.projectileStreamMode))) { - defaultData.velocity = { - deployMethod: self._stats.deployMethod, - x: Math.cos(rotate + Math.radians(-90)) * self._stats.bulletForce, - y: Math.sin(rotate + Math.radians(-90)) * self._stats.bulletForce + if ( + this._stats.isGun && + (ige.isServer || (ige.isClient && ige.physics)) // render projectile on clientside if physics is enabled + ) { + var defaultData = { + rotate: rotate, + translate: bulletStartPosition }; - // console.log(self._stats.currentBody.type, "unit: ", angleToTarget, "item's rotate.z: ", self._rotate.z, "facing angle", itemrotate) - var data = Object.assign( - JSON.parse(JSON.stringify(self.projectileData)), - { - type: self._stats.projectileType, - sourceItemId: self.id(), - sourceUnitId: (owner) ? owner.id() : undefined, - defaultData: defaultData, - damageData: { - targetsAffected: this._stats.damage.targetsAffected, - sourceUnitId: owner.id(), - sourceItemId: self.id(), - sourcePlayerId: owner.getOwner().id(), - unitAttributes: this._stats.damage.unitAttributes, - playerAttributes: this._stats.damage.playerAttributes - } - }); - - var projectile = new Projectile(data); - ige.game.lastCreatedProjectileId = projectile.id(); - } - if (this._stats.bulletType == 'raycast') { - // starting from unit center position - var raycastStartPosition = { - x: owner._translate.x + (Math.cos(this._rotate.z + Math.radians(-90))) + (Math.cos(this._rotate.z)), - y: owner._translate.y + (Math.sin(this._rotate.z + Math.radians(-90))) + (Math.sin(this._rotate.z)) - }; - - if (self._stats.currentBody && (self._stats.currentBody.type == 'spriteOnly' || self._stats.currentBody.type == 'none')) { - var unitAnchorX = (self._stats.currentBody.unitAnchor != undefined) ? self._stats.currentBody.unitAnchor.x : 0; - var unitAnchorY = (self._stats.currentBody.unitAnchor != undefined) ? self._stats.currentBody.unitAnchor.y : 0; - - var endPosition = { - x: (owner._translate.x + unitAnchorX) + (this._stats.bulletDistance * Math.cos(owner._rotate.z + Math.radians(-90))), - y: (owner._translate.y + unitAnchorY) + (this._stats.bulletDistance * Math.sin(owner._rotate.z + Math.radians(-90))) - }; - } else { - var endPosition = { - x: (self._translate.x) + (this._stats.bulletDistance * Math.cos(self._rotate.z + Math.radians(-90))), - y: (self._translate.y) + (this._stats.bulletDistance * Math.sin(self._rotate.z + Math.radians(-90))) + if (self.projectileData && (ige.isServer || (ige.isClient && !self._stats.projectileStreamMode))) { + defaultData.velocity = { + deployMethod: self._stats.deployMethod, + x: Math.cos(rotate + Math.radians(-90)) * self._stats.bulletForce, + y: Math.sin(rotate + Math.radians(-90)) * self._stats.bulletForce }; + + // console.log(self._stats.currentBody.type, "unit: ", angleToTarget, "item's rotate.z: ", self._rotate.z, "facing angle", itemrotate) + var data = Object.assign( + JSON.parse(JSON.stringify(self.projectileData)), + { + type: self._stats.projectileType, + sourceItemId: self.id(), + sourceUnitId: (owner) ? owner.id() : undefined, + defaultData: defaultData, + damageData: { + targetsAffected: this._stats.damage.targetsAffected, + sourceUnitId: owner.id(), + sourceItemId: self.id(), + sourcePlayerId: owner.getOwner().id(), + unitAttributes: this._stats.damage.unitAttributes, + playerAttributes: this._stats.damage.playerAttributes + } + }); + + var projectile = new Projectile(data); + ige.game.lastCreatedProjectileId = projectile.id(); } + if (this._stats.bulletType == 'raycast') { + // starting from unit center position + var raycastStartPosition = { + x: owner._translate.x + (Math.cos(this._rotate.z + Math.radians(-90))) + (Math.cos(this._rotate.z)), + y: owner._translate.y + (Math.sin(this._rotate.z + Math.radians(-90))) + (Math.sin(this._rotate.z)) + }; - var raycastMultipleCallback = function () { - var def = {}; - // var e_maxCount = 3; - var raycastCollidesWith = self._stats.raycastCollidesWith; - def.m_points = []; - def.m_normals = []; - - def.ReportFixture = function (fixture, point, normal, fraction) { - var fixtureList = fixture.m_body.m_fixtureList; - var entity = fixtureList && fixtureList.igeId && ige.$(fixtureList.igeId); - if (entity) { - entity.lastRaycastCollisionPosition = { - x: point.x * self.scaleRatio, - y: point.y * self.scaleRatio - }; - entity.raycastFraction = fraction; - self.raycastTargets.push(entity); - } + if (self._stats.currentBody && (self._stats.currentBody.type == 'spriteOnly' || self._stats.currentBody.type == 'none')) { + var unitAnchorX = (self._stats.currentBody.unitAnchor != undefined) ? self._stats.currentBody.unitAnchor.x : 0; + var unitAnchorY = (self._stats.currentBody.unitAnchor != undefined) ? self._stats.currentBody.unitAnchor.y : 0; + + var endPosition = { + x: (owner._translate.x + unitAnchorX) + (this._stats.bulletDistance * Math.cos(owner._rotate.z + Math.radians(-90))), + y: (owner._translate.y + unitAnchorY) + (this._stats.bulletDistance * Math.sin(owner._rotate.z + Math.radians(-90))) + }; + } else { + var endPosition = { + x: (self._translate.x) + (this._stats.bulletDistance * Math.cos(self._rotate.z + Math.radians(-90))), + y: (self._translate.y) + (this._stats.bulletDistance * Math.sin(self._rotate.z + Math.radians(-90))) + }; + } - // var body = fixture.getBody(); - // var userData = body.getUserData(); - // if (userData) { - // if (userData == 0) { - // // By returning -1, we instruct the calling code to ignore this fixture - // // and continue the ray-cast to the next fixture. - // return -1.0; - // } - // } - - def.m_points.push(point); - def.m_normals.push(normal); - // By returning 1, we instruct the caller to continue without clipping the - // ray. - return 1.0; + var raycastMultipleCallback = function () { + var def = {}; + // var e_maxCount = 3; + var raycastCollidesWith = self._stats.raycastCollidesWith; + def.m_points = []; + def.m_normals = []; + + def.ReportFixture = function (fixture, point, normal, fraction) { + var fixtureList = fixture.m_body.m_fixtureList; + var entity = fixtureList && fixtureList.igeId && ige.$(fixtureList.igeId); + if (entity) { + entity.lastRaycastCollisionPosition = { + x: point.x * self.scaleRatio, + y: point.y * self.scaleRatio + }; + entity.raycastFraction = fraction; + self.raycastTargets.push(entity); + } + + // var body = fixture.getBody(); + // var userData = body.getUserData(); + // if (userData) { + // if (userData == 0) { + // // By returning -1, we instruct the calling code to ignore this fixture + // // and continue the ray-cast to the next fixture. + // return -1.0; + // } + // } + + def.m_points.push(point); + def.m_normals.push(normal); + // By returning 1, we instruct the caller to continue without clipping the + // ray. + return 1.0; + }; + + return def; }; - return def; - }; + var callback = raycastMultipleCallback(); + + // ige.physics.world().rayCast(, callback.ReportFixture); + ige.physics.world().rayCast( + callback.ReportFixture, + { + x: raycastStartPosition.x / self.scaleRatio, + y: raycastStartPosition.y / self.scaleRatio + }, + { + x: endPosition.x / self.scaleRatio, + y: endPosition.y / self.scaleRatio + } + ); - var callback = raycastMultipleCallback(); - - // ige.physics.world().rayCast(, callback.ReportFixture); - ige.physics.world().rayCast( - callback.ReportFixture, - { - x: raycastStartPosition.x / self.scaleRatio, - y: raycastStartPosition.y / self.scaleRatio - }, - { - x: endPosition.x / self.scaleRatio, - y: endPosition.y / self.scaleRatio + // if (!self._stats.penetration) { + ige.game.entitiesCollidingWithLastRaycast = _.orderBy(self.raycastTargets, ['raycastFraction'], ['asc']); + // } + ige.trigger && ige.trigger.fire('raycastItemFired', { + itemId: self.id() + }); + } + self.raycastTargets = []; + + if (self._stats.recoilForce) { + // apply recoil on its owner if item itself doesn't have physical body + if (self._stats.currentBody == undefined || self._stats.currentBody.type == 'none' || self._stats.currentBody.type == 'spriteOnly') { + owner.applyForce(self._stats.recoilForce * Math.cos(owner._rotate.z + Math.radians(90)), self._stats.recoilForce * Math.sin(owner._rotate.z + Math.radians(90))); + } else { // apply recoil on item + self.applyForce(self._stats.recoilForce * Math.cos(this._rotate.z + Math.radians(90)), self._stats.recoilForce * Math.sin(this._rotate.z + Math.radians(90))); } - ); - - // if (!self._stats.penetration) { - ige.game.entitiesCollidingWithLastRaycast = _.orderBy(self.raycastTargets, ['raycastFraction'], ['asc']); - // } - ige.trigger && ige.trigger.fire('raycastItemFired', { - itemId: self.id() - }); - } - self.raycastTargets = []; - - if (self._stats.recoilForce) { - // apply recoil on its owner if item itself doesn't have physical body - if (self._stats.currentBody == undefined || self._stats.currentBody.type == 'none' || self._stats.currentBody.type == 'spriteOnly') { - owner.applyForce(self._stats.recoilForce * Math.cos(owner._rotate.z + Math.radians(90)), self._stats.recoilForce * Math.sin(owner._rotate.z + Math.radians(90))); - } else { // apply recoil on item - self.applyForce(self._stats.recoilForce * Math.cos(this._rotate.z + Math.radians(90)), self._stats.recoilForce * Math.sin(this._rotate.z + Math.radians(90))); } } } - } - } else { // melee weapon - var hitboxData = this._stats.damageHitBox; - - if (hitboxData) { - // console.log(hitboxData); - var rotate = (owner.angleToTarget) ? owner.angleToTarget : 0; - var hitboxPosition = { - x: (owner._translate.x) + (hitboxData.offsetX * Math.cos(rotate)) + (hitboxData.offsetY * Math.sin(rotate)), - y: (owner._translate.y) + (hitboxData.offsetX * Math.sin(rotate)) - (hitboxData.offsetY * Math.cos(rotate)) - }; - - var hitbox = { - x: hitboxPosition.x - hitboxData.width, - y: hitboxPosition.y - hitboxData.width, - width: hitboxData.width * 2, - height: hitboxData.width * 2 // width is used as a radius - }; - - var damageData = { - targetsAffected: this._stats.damage.targetsAffected, - sourceUnitId: owner.id(), - sourceItemId: self.id(), - sourcePlayerId: owner.getOwner().id(), - unitAttributes: this._stats.damage.unitAttributes, - playerAttributes: this._stats.damage.playerAttributes - }; - // console.log(owner._translate.x, owner._translate.y, hitbox); //////////Hitbox log - - entities = ige.physics.getBodiesInRegion(hitbox); - - while (entities.length > 0) { - var entity = entities.shift(); - if (entity && entity._category == 'unit') { - entity.inflictDamage(damageData); + } else { // melee weapon + var hitboxData = this._stats.damageHitBox; + + if (hitboxData) { + // console.log(hitboxData); + var rotate = (owner.angleToTarget) ? owner.angleToTarget : 0; + var hitboxPosition = { + x: (owner._translate.x) + (hitboxData.offsetX * Math.cos(rotate)) + (hitboxData.offsetY * Math.sin(rotate)), + y: (owner._translate.y) + (hitboxData.offsetX * Math.sin(rotate)) - (hitboxData.offsetY * Math.cos(rotate)) + }; + + var hitbox = { + x: hitboxPosition.x - hitboxData.width, + y: hitboxPosition.y - hitboxData.width, + width: hitboxData.width * 2, + height: hitboxData.width * 2 // width is used as a radius + }; + + var damageData = { + targetsAffected: this._stats.damage.targetsAffected, + sourceUnitId: owner.id(), + sourceItemId: self.id(), + sourcePlayerId: owner.getOwner().id(), + unitAttributes: this._stats.damage.unitAttributes, + playerAttributes: this._stats.damage.playerAttributes + }; + // console.log(owner._translate.x, owner._translate.y, hitbox); //////////Hitbox log + + entities = ige.physics.getBodiesInRegion(hitbox); + + while (entities.length > 0) { + var entity = entities.shift(); + if (entity && entity._category == 'unit') { + entity.inflictDamage(damageData); + } } } } - } - } else if (self._stats.type == 'consumable') { // item is not a gun (e.g. consumable) - // if cost quantity of consumable item is not defined or 0 - // it should be 1 by default. Bcz 1 item will be consumed when fire. - // currently we dont have cost quantity setting in consumable items so - // this is handler for it. - - if (!self.quantityCost) { - self.quantityCost = 1; - } + } else if (self._stats.type == 'consumable') { // item is not a gun (e.g. consumable) + // if cost quantity of consumable item is not defined or 0 + // it should be 1 by default. Bcz 1 item will be consumed when fire. + // currently we dont have cost quantity setting in consumable items so + // this is handler for it. + + if (!self.quantityCost) { + self.quantityCost = 1; + } - attrData = { attributes: {} }; - if (self._stats.bonus && self._stats.bonus.consume) { - // apply unit bonuses - var unitAttributeBonuses = self._stats.bonus.consume.unitAttribute; - if (unitAttributeBonuses) { - for (var attrId in unitAttributeBonuses) { - if (attrData.attributes) { - var newValue = owner.attribute.getValue(attrId) + parseFloat(unitAttributeBonuses[attrId]); - attrData.attributes[attrId] = owner.attribute.update(attrId, newValue, true); + attrData = { attributes: {} }; + if (self._stats.bonus && self._stats.bonus.consume) { + // apply unit bonuses + var unitAttributeBonuses = self._stats.bonus.consume.unitAttribute; + if (unitAttributeBonuses) { + for (var attrId in unitAttributeBonuses) { + if (attrData.attributes) { + var newValue = owner.attribute.getValue(attrId) + parseFloat(unitAttributeBonuses[attrId]); + attrData.attributes[attrId] = owner.attribute.update(attrId, newValue, true); + } } } - } - if (player && player.attribute) { - // apply player bonuses - var playerAttributeBonuses = self._stats.bonus.consume.playerAttribute; - if (playerAttributeBonuses) { - for (attrId in playerAttributeBonuses) { - var newValue = player.attribute.getValue(attrId) + parseFloat(playerAttributeBonuses[attrId]); - attrData.attributes[attrId] = player.attribute.update(attrId, newValue, true); + if (player && player.attribute) { + // apply player bonuses + var playerAttributeBonuses = self._stats.bonus.consume.playerAttribute; + if (playerAttributeBonuses) { + for (attrId in playerAttributeBonuses) { + var newValue = player.attribute.getValue(attrId) + parseFloat(playerAttributeBonuses[attrId]); + attrData.attributes[attrId] = player.attribute.update(attrId, newValue, true); + } + } + + if (ige.isServer && self._stats && self._stats.bonus && self._stats.bonus.consume && self._stats.bonus.consume.coin) { + // ige.server.giveCoinToUser(player, self._stats.bonus.consume.coin, self._stats.name); + // player.streamUpdateData([{ + // coins: self._stats.bonus.consume.coin + player._stats.coins + // }]); } } - if (ige.isServer && self._stats && self._stats.bonus && self._stats.bonus.consume && self._stats.bonus.consume.coin) { - // ige.server.giveCoinToUser(player, self._stats.bonus.consume.coin, self._stats.name); - // player.streamUpdateData([{ - // coins: self._stats.bonus.consume.coin + player._stats.coins - // }]); + if (ige.isServer) { + owner.streamUpdateData(attrData); } } - if (ige.isServer) { - owner.streamUpdateData(attrData); - } + self.stopUsing(); // stop using immediately after use. } - - self.stopUsing(); // stop using immediately after use. } - } - // lowering the quantity by self.quantityCost - } else { // quantity is 0 - self.stopUsing(); - } + // lowering the quantity by self.quantityCost + } else { // quantity is 0 + self.stopUsing(); + } - if (isUsed && ige.isClient) { - this.playEffect('use'); - } + if (isUsed && ige.isClient) { + this.playEffect('use'); + } - if (self._stats.quantity != null || self._stats.quantity != undefined) { - // ige.devLog(isUsed, self._stats.quantity , self._stats.quantity > 0) - if (isUsed && self._stats.quantity > 0) { - self.updateQuantity(self._stats.quantity - self.quantityCost); + if (self._stats.quantity != null || self._stats.quantity != undefined) { + // ige.devLog(isUsed, self._stats.quantity , self._stats.quantity > 0) + if (isUsed && self._stats.quantity > 0) { + self.updateQuantity(self._stats.quantity - self.quantityCost); + } } - } + + }, self._stats.delayBeforeUse); }, updateQuantity: function (qty) { From e0f3958da8af969816bbe6fbc9e844f33124a8fc Mon Sep 17 00:00:00 2001 From: PineappleBrain <62375288+PineappleBrain@users.noreply.github.com> Date: Tue, 3 May 2022 21:39:57 +0800 Subject: [PATCH 8/8] Revert "delay before use" (#2) This reverts commit 71cbcc4215519265812dddcaf5b54bb0dc6b7945. --- src/gameClasses/Item.js | 511 ++++++++++++++++++++-------------------- 1 file changed, 252 insertions(+), 259 deletions(-) diff --git a/src/gameClasses/Item.js b/src/gameClasses/Item.js index 43178ba9..ec1cfac8 100644 --- a/src/gameClasses/Item.js +++ b/src/gameClasses/Item.js @@ -251,307 +251,300 @@ var Item = IgeEntityPhysics.extend({ var player = owner && owner.getOwner(); var isUsed = false; - setTimeout(() => { - // if item has no owner, or item is unusable type, or it cannot be used by its current owner, then return - if (!owner || - (self._stats.canBeUsedBy && self._stats.canBeUsedBy.length > 0 && self._stats.canBeUsedBy.indexOf(owner._stats.type) == -1) || - self._stats.type === 'unusable') { - return; - } + // if item has no owner, or item is unusable type, or it cannot be used by its current owner, then return + if (!owner || + (self._stats.canBeUsedBy && self._stats.canBeUsedBy.length > 0 && self._stats.canBeUsedBy.indexOf(owner._stats.type) == -1) || + self._stats.type === 'unusable') { + return; + } - if (self.hasQuantityRemaining()) { - ige.game.lastUsedItemId = self.id(); + if (self.hasQuantityRemaining()) { + ige.game.lastUsedItemId = self.id(); - if ((self._stats.lastUsed - self._stats.delayBeforeUse + self._stats.fireRate < now) || self._stats.type == 'consumable') { - if (!self.canAffordItemCost()) { - ige.devLog('cannot afford item cost'); - return; - } + if ((self._stats.lastUsed + self._stats.fireRate < now) || self._stats.type == 'consumable') { + if (!self.canAffordItemCost()) { + ige.devLog('cannot afford item cost'); + return; + } - isUsed = true; + isUsed = true; - // item must be ready to fire (accordingly to fire rate), and must have ammo or have infinite ammo - if (ige.isClient && self._stats.type == 'weapon' && self._stats.effects && self._stats.effects.use && self._stats.effects.use.animation) { - self.applyAnimationById(self._stats.effects.use.animation); - } + // item must be ready to fire (accordingly to fire rate), and must have ammo or have infinite ammo + if (ige.isClient && self._stats.type == 'weapon' && self._stats.effects && self._stats.effects.use && self._stats.effects.use.animation) { + self.applyAnimationById(self._stats.effects.use.animation); + } - self._stats.lastUsed = ige.now; - ige.trigger && ige.trigger.fire('unitUsesItem', { - unitId: (owner) ? owner.id() : undefined, - itemId: self.id() - }); - - if (ige.physics && self._stats.type == 'weapon') { - if (self._stats.isGun) { - if (self._stats.bulletStartPosition) { - var rotate = this._rotate.z; - if (owner && self._stats.currentBody && self._stats.currentBody.jointType == 'weldJoint') { - rotate = owner._rotate.z; - } - - // FIX - // fixed bulletStartPositionRotation - rotate += self._stats.bulletStartPosition.rotation * Math.PI / 180; - // FIX - - if (self.anchoredOffset == undefined) { - self.anchoredOffset = { x: 0, y: 0, rotate: 0 }; - } + self._stats.lastUsed = ige.now; + ige.trigger && ige.trigger.fire('unitUsesItem', { + unitId: (owner) ? owner.id() : undefined, + itemId: self.id() + }); - var offsetAngle = rotate; - if (self._stats.flip == 1) { - offsetAngle += Math.PI; - } + if (ige.physics && self._stats.type == 'weapon') { + if (self._stats.isGun) { + if (self._stats.bulletStartPosition) { + var rotate = this._rotate.z; + if (owner && self._stats.currentBody && self._stats.currentBody.jointType == 'weldJoint') { + rotate = owner._rotate.z; + } + rotate += self._stats.bulletStartPosition.rotation * Math.PI / 180; - // item is flipped, then mirror the rotation - if (owner._stats.flip == 1) { - var bulletY = -self._stats.bulletStartPosition.y || 0; - } else { - var bulletY = self._stats.bulletStartPosition.y || 0; - } + if (self.anchoredOffset == undefined) { + self.anchoredOffset = { x: 0, y: 0, rotate: 0 }; + } + + var offsetAngle = rotate; + if (self._stats.flip == 1) { + offsetAngle += Math.PI; + } - var bulletStartPosition = { - x: (owner._translate.x + self.anchoredOffset.x) + (self._stats.bulletStartPosition.x * Math.cos(offsetAngle)) + (bulletY * Math.sin(offsetAngle)), - y: (owner._translate.y + self.anchoredOffset.y) + (self._stats.bulletStartPosition.x * Math.sin(offsetAngle)) - (bulletY * Math.cos(offsetAngle)) + // item is flipped, then mirror the rotation + if (owner._stats.flip == 1) { + var bulletY = -self._stats.bulletStartPosition.y || 0; + } else { + var bulletY = self._stats.bulletStartPosition.y || 0; + } + + var bulletStartPosition = { + x: (owner._translate.x + self.anchoredOffset.x) + (self._stats.bulletStartPosition.x * Math.cos(offsetAngle)) + (bulletY * Math.sin(offsetAngle)), + y: (owner._translate.y + self.anchoredOffset.y) + (self._stats.bulletStartPosition.x * Math.sin(offsetAngle)) - (bulletY * Math.cos(offsetAngle)) + }; + + if ( + this._stats.isGun && + (ige.isServer || (ige.isClient && ige.physics)) // render projectile on clientside if physics is enabled + ) { + var defaultData = { + rotate: rotate, + translate: bulletStartPosition }; - if ( - this._stats.isGun && - (ige.isServer || (ige.isClient && ige.physics)) // render projectile on clientside if physics is enabled - ) { - var defaultData = { - rotate: rotate, - translate: bulletStartPosition + if (self.projectileData && (ige.isServer || (ige.isClient && !self._stats.projectileStreamMode))) { + defaultData.velocity = { + deployMethod: self._stats.deployMethod, + x: Math.cos(rotate + Math.radians(-90)) * self._stats.bulletForce, + y: Math.sin(rotate + Math.radians(-90)) * self._stats.bulletForce }; - if (self.projectileData && (ige.isServer || (ige.isClient && !self._stats.projectileStreamMode))) { - defaultData.velocity = { - deployMethod: self._stats.deployMethod, - x: Math.cos(rotate + Math.radians(-90)) * self._stats.bulletForce, - y: Math.sin(rotate + Math.radians(-90)) * self._stats.bulletForce - }; - - // console.log(self._stats.currentBody.type, "unit: ", angleToTarget, "item's rotate.z: ", self._rotate.z, "facing angle", itemrotate) - var data = Object.assign( - JSON.parse(JSON.stringify(self.projectileData)), - { - type: self._stats.projectileType, + // console.log(self._stats.currentBody.type, "unit: ", angleToTarget, "item's rotate.z: ", self._rotate.z, "facing angle", itemrotate) + var data = Object.assign( + JSON.parse(JSON.stringify(self.projectileData)), + { + type: self._stats.projectileType, + sourceItemId: self.id(), + sourceUnitId: (owner) ? owner.id() : undefined, + defaultData: defaultData, + damageData: { + targetsAffected: this._stats.damage.targetsAffected, + sourceUnitId: owner.id(), sourceItemId: self.id(), - sourceUnitId: (owner) ? owner.id() : undefined, - defaultData: defaultData, - damageData: { - targetsAffected: this._stats.damage.targetsAffected, - sourceUnitId: owner.id(), - sourceItemId: self.id(), - sourcePlayerId: owner.getOwner().id(), - unitAttributes: this._stats.damage.unitAttributes, - playerAttributes: this._stats.damage.playerAttributes - } - }); - - var projectile = new Projectile(data); - ige.game.lastCreatedProjectileId = projectile.id(); - } - if (this._stats.bulletType == 'raycast') { - // starting from unit center position - var raycastStartPosition = { - x: owner._translate.x + (Math.cos(this._rotate.z + Math.radians(-90))) + (Math.cos(this._rotate.z)), - y: owner._translate.y + (Math.sin(this._rotate.z + Math.radians(-90))) + (Math.sin(this._rotate.z)) - }; - - if (self._stats.currentBody && (self._stats.currentBody.type == 'spriteOnly' || self._stats.currentBody.type == 'none')) { - var unitAnchorX = (self._stats.currentBody.unitAnchor != undefined) ? self._stats.currentBody.unitAnchor.x : 0; - var unitAnchorY = (self._stats.currentBody.unitAnchor != undefined) ? self._stats.currentBody.unitAnchor.y : 0; - - var endPosition = { - x: (owner._translate.x + unitAnchorX) + (this._stats.bulletDistance * Math.cos(owner._rotate.z + Math.radians(-90))), - y: (owner._translate.y + unitAnchorY) + (this._stats.bulletDistance * Math.sin(owner._rotate.z + Math.radians(-90))) - }; - } else { - var endPosition = { - x: (self._translate.x) + (this._stats.bulletDistance * Math.cos(self._rotate.z + Math.radians(-90))), - y: (self._translate.y) + (this._stats.bulletDistance * Math.sin(self._rotate.z + Math.radians(-90))) - }; - } + sourcePlayerId: owner.getOwner().id(), + unitAttributes: this._stats.damage.unitAttributes, + playerAttributes: this._stats.damage.playerAttributes + } + }); - var raycastMultipleCallback = function () { - var def = {}; - // var e_maxCount = 3; - var raycastCollidesWith = self._stats.raycastCollidesWith; - def.m_points = []; - def.m_normals = []; - - def.ReportFixture = function (fixture, point, normal, fraction) { - var fixtureList = fixture.m_body.m_fixtureList; - var entity = fixtureList && fixtureList.igeId && ige.$(fixtureList.igeId); - if (entity) { - entity.lastRaycastCollisionPosition = { - x: point.x * self.scaleRatio, - y: point.y * self.scaleRatio - }; - entity.raycastFraction = fraction; - self.raycastTargets.push(entity); - } - - // var body = fixture.getBody(); - // var userData = body.getUserData(); - // if (userData) { - // if (userData == 0) { - // // By returning -1, we instruct the calling code to ignore this fixture - // // and continue the ray-cast to the next fixture. - // return -1.0; - // } - // } - - def.m_points.push(point); - def.m_normals.push(normal); - // By returning 1, we instruct the caller to continue without clipping the - // ray. - return 1.0; - }; - - return def; - }; + var projectile = new Projectile(data); + ige.game.lastCreatedProjectileId = projectile.id(); + } + if (this._stats.bulletType == 'raycast') { + // starting from unit center position + var raycastStartPosition = { + x: owner._translate.x + (Math.cos(this._rotate.z + Math.radians(-90))) + (Math.cos(this._rotate.z)), + y: owner._translate.y + (Math.sin(this._rotate.z + Math.radians(-90))) + (Math.sin(this._rotate.z)) + }; - var callback = raycastMultipleCallback(); - - // ige.physics.world().rayCast(, callback.ReportFixture); - ige.physics.world().rayCast( - callback.ReportFixture, - { - x: raycastStartPosition.x / self.scaleRatio, - y: raycastStartPosition.y / self.scaleRatio - }, - { - x: endPosition.x / self.scaleRatio, - y: endPosition.y / self.scaleRatio - } - ); + if (self._stats.currentBody && (self._stats.currentBody.type == 'spriteOnly' || self._stats.currentBody.type == 'none')) { + var unitAnchorX = (self._stats.currentBody.unitAnchor != undefined) ? self._stats.currentBody.unitAnchor.x : 0; + var unitAnchorY = (self._stats.currentBody.unitAnchor != undefined) ? self._stats.currentBody.unitAnchor.y : 0; - // if (!self._stats.penetration) { - ige.game.entitiesCollidingWithLastRaycast = _.orderBy(self.raycastTargets, ['raycastFraction'], ['asc']); - // } - ige.trigger && ige.trigger.fire('raycastItemFired', { - itemId: self.id() - }); - } - self.raycastTargets = []; - - if (self._stats.recoilForce) { - // apply recoil on its owner if item itself doesn't have physical body - if (self._stats.currentBody == undefined || self._stats.currentBody.type == 'none' || self._stats.currentBody.type == 'spriteOnly') { - owner.applyForce(self._stats.recoilForce * Math.cos(owner._rotate.z + Math.radians(90)), self._stats.recoilForce * Math.sin(owner._rotate.z + Math.radians(90))); - } else { // apply recoil on item - self.applyForce(self._stats.recoilForce * Math.cos(this._rotate.z + Math.radians(90)), self._stats.recoilForce * Math.sin(this._rotate.z + Math.radians(90))); - } + var endPosition = { + x: (owner._translate.x + unitAnchorX) + (this._stats.bulletDistance * Math.cos(owner._rotate.z + Math.radians(-90))), + y: (owner._translate.y + unitAnchorY) + (this._stats.bulletDistance * Math.sin(owner._rotate.z + Math.radians(-90))) + }; + } else { + var endPosition = { + x: (self._translate.x) + (this._stats.bulletDistance * Math.cos(self._rotate.z + Math.radians(-90))), + y: (self._translate.y) + (this._stats.bulletDistance * Math.sin(self._rotate.z + Math.radians(-90))) + }; } - } - } - } else { // melee weapon - var hitboxData = this._stats.damageHitBox; - - if (hitboxData) { - // console.log(hitboxData); - var rotate = (owner.angleToTarget) ? owner.angleToTarget : 0; - var hitboxPosition = { - x: (owner._translate.x) + (hitboxData.offsetX * Math.cos(rotate)) + (hitboxData.offsetY * Math.sin(rotate)), - y: (owner._translate.y) + (hitboxData.offsetX * Math.sin(rotate)) - (hitboxData.offsetY * Math.cos(rotate)) - }; - var hitbox = { - x: hitboxPosition.x - hitboxData.width, - y: hitboxPosition.y - hitboxData.width, - width: hitboxData.width * 2, - height: hitboxData.width * 2 // width is used as a radius - }; + var raycastMultipleCallback = function () { + var def = {}; + // var e_maxCount = 3; + var raycastCollidesWith = self._stats.raycastCollidesWith; + def.m_points = []; + def.m_normals = []; + + def.ReportFixture = function (fixture, point, normal, fraction) { + var fixtureList = fixture.m_body.m_fixtureList; + var entity = fixtureList && fixtureList.igeId && ige.$(fixtureList.igeId); + if (entity) { + entity.lastRaycastCollisionPosition = { + x: point.x * self.scaleRatio, + y: point.y * self.scaleRatio + }; + entity.raycastFraction = fraction; + self.raycastTargets.push(entity); + } - var damageData = { - targetsAffected: this._stats.damage.targetsAffected, - sourceUnitId: owner.id(), - sourceItemId: self.id(), - sourcePlayerId: owner.getOwner().id(), - unitAttributes: this._stats.damage.unitAttributes, - playerAttributes: this._stats.damage.playerAttributes - }; - // console.log(owner._translate.x, owner._translate.y, hitbox); //////////Hitbox log + // var body = fixture.getBody(); + // var userData = body.getUserData(); + // if (userData) { + // if (userData == 0) { + // // By returning -1, we instruct the calling code to ignore this fixture + // // and continue the ray-cast to the next fixture. + // return -1.0; + // } + // } + + def.m_points.push(point); + def.m_normals.push(normal); + // By returning 1, we instruct the caller to continue without clipping the + // ray. + return 1.0; + }; - entities = ige.physics.getBodiesInRegion(hitbox); + return def; + }; - while (entities.length > 0) { - var entity = entities.shift(); - if (entity && entity._category == 'unit') { - entity.inflictDamage(damageData); + var callback = raycastMultipleCallback(); + + // ige.physics.world().rayCast(, callback.ReportFixture); + ige.physics.world().rayCast( + callback.ReportFixture, + { + x: raycastStartPosition.x / self.scaleRatio, + y: raycastStartPosition.y / self.scaleRatio + }, + { + x: endPosition.x / self.scaleRatio, + y: endPosition.y / self.scaleRatio + } + ); + + // if (!self._stats.penetration) { + ige.game.entitiesCollidingWithLastRaycast = _.orderBy(self.raycastTargets, ['raycastFraction'], ['asc']); + // } + ige.trigger && ige.trigger.fire('raycastItemFired', { + itemId: self.id() + }); + } + self.raycastTargets = []; + + if (self._stats.recoilForce) { + // apply recoil on its owner if item itself doesn't have physical body + if (self._stats.currentBody == undefined || self._stats.currentBody.type == 'none' || self._stats.currentBody.type == 'spriteOnly') { + owner.applyForce(self._stats.recoilForce * Math.cos(owner._rotate.z + Math.radians(90)), self._stats.recoilForce * Math.sin(owner._rotate.z + Math.radians(90))); + } else { // apply recoil on item + self.applyForce(self._stats.recoilForce * Math.cos(this._rotate.z + Math.radians(90)), self._stats.recoilForce * Math.sin(this._rotate.z + Math.radians(90))); } } } } - } else if (self._stats.type == 'consumable') { // item is not a gun (e.g. consumable) - // if cost quantity of consumable item is not defined or 0 - // it should be 1 by default. Bcz 1 item will be consumed when fire. - // currently we dont have cost quantity setting in consumable items so - // this is handler for it. - - if (!self.quantityCost) { - self.quantityCost = 1; - } - - attrData = { attributes: {} }; - if (self._stats.bonus && self._stats.bonus.consume) { - // apply unit bonuses - var unitAttributeBonuses = self._stats.bonus.consume.unitAttribute; - if (unitAttributeBonuses) { - for (var attrId in unitAttributeBonuses) { - if (attrData.attributes) { - var newValue = owner.attribute.getValue(attrId) + parseFloat(unitAttributeBonuses[attrId]); - attrData.attributes[attrId] = owner.attribute.update(attrId, newValue, true); - } + } else { // melee weapon + var hitboxData = this._stats.damageHitBox; + + if (hitboxData) { + // console.log(hitboxData); + var rotate = (owner.angleToTarget) ? owner.angleToTarget : 0; + var hitboxPosition = { + x: (owner._translate.x) + (hitboxData.offsetX * Math.cos(rotate)) + (hitboxData.offsetY * Math.sin(rotate)), + y: (owner._translate.y) + (hitboxData.offsetX * Math.sin(rotate)) - (hitboxData.offsetY * Math.cos(rotate)) + }; + + var hitbox = { + x: hitboxPosition.x - hitboxData.width, + y: hitboxPosition.y - hitboxData.width, + width: hitboxData.width * 2, + height: hitboxData.width * 2 // width is used as a radius + }; + + var damageData = { + targetsAffected: this._stats.damage.targetsAffected, + sourceUnitId: owner.id(), + sourceItemId: self.id(), + sourcePlayerId: owner.getOwner().id(), + unitAttributes: this._stats.damage.unitAttributes, + playerAttributes: this._stats.damage.playerAttributes + }; + // console.log(owner._translate.x, owner._translate.y, hitbox); //////////Hitbox log + + entities = ige.physics.getBodiesInRegion(hitbox); + + while (entities.length > 0) { + var entity = entities.shift(); + if (entity && entity._category == 'unit') { + entity.inflictDamage(damageData); } } + } + } + } else if (self._stats.type == 'consumable') { // item is not a gun (e.g. consumable) + // if cost quantity of consumable item is not defined or 0 + // it should be 1 by default. Bcz 1 item will be consumed when fire. + // currently we dont have cost quantity setting in consumable items so + // this is handler for it. + + if (!self.quantityCost) { + self.quantityCost = 1; + } - if (player && player.attribute) { - // apply player bonuses - var playerAttributeBonuses = self._stats.bonus.consume.playerAttribute; - if (playerAttributeBonuses) { - for (attrId in playerAttributeBonuses) { - var newValue = player.attribute.getValue(attrId) + parseFloat(playerAttributeBonuses[attrId]); - attrData.attributes[attrId] = player.attribute.update(attrId, newValue, true); - } + attrData = { attributes: {} }; + if (self._stats.bonus && self._stats.bonus.consume) { + // apply unit bonuses + var unitAttributeBonuses = self._stats.bonus.consume.unitAttribute; + if (unitAttributeBonuses) { + for (var attrId in unitAttributeBonuses) { + if (attrData.attributes) { + var newValue = owner.attribute.getValue(attrId) + parseFloat(unitAttributeBonuses[attrId]); + attrData.attributes[attrId] = owner.attribute.update(attrId, newValue, true); } + } + } - if (ige.isServer && self._stats && self._stats.bonus && self._stats.bonus.consume && self._stats.bonus.consume.coin) { - // ige.server.giveCoinToUser(player, self._stats.bonus.consume.coin, self._stats.name); - // player.streamUpdateData([{ - // coins: self._stats.bonus.consume.coin + player._stats.coins - // }]); + if (player && player.attribute) { + // apply player bonuses + var playerAttributeBonuses = self._stats.bonus.consume.playerAttribute; + if (playerAttributeBonuses) { + for (attrId in playerAttributeBonuses) { + var newValue = player.attribute.getValue(attrId) + parseFloat(playerAttributeBonuses[attrId]); + attrData.attributes[attrId] = player.attribute.update(attrId, newValue, true); } } - if (ige.isServer) { - owner.streamUpdateData(attrData); + if (ige.isServer && self._stats && self._stats.bonus && self._stats.bonus.consume && self._stats.bonus.consume.coin) { + // ige.server.giveCoinToUser(player, self._stats.bonus.consume.coin, self._stats.name); + // player.streamUpdateData([{ + // coins: self._stats.bonus.consume.coin + player._stats.coins + // }]); } } - self.stopUsing(); // stop using immediately after use. + if (ige.isServer) { + owner.streamUpdateData(attrData); + } } - } - // lowering the quantity by self.quantityCost - } else { // quantity is 0 - self.stopUsing(); + self.stopUsing(); // stop using immediately after use. + } } - if (isUsed && ige.isClient) { - this.playEffect('use'); - } + // lowering the quantity by self.quantityCost + } else { // quantity is 0 + self.stopUsing(); + } - if (self._stats.quantity != null || self._stats.quantity != undefined) { - // ige.devLog(isUsed, self._stats.quantity , self._stats.quantity > 0) - if (isUsed && self._stats.quantity > 0) { - self.updateQuantity(self._stats.quantity - self.quantityCost); - } + if (isUsed && ige.isClient) { + this.playEffect('use'); + } + + if (self._stats.quantity != null || self._stats.quantity != undefined) { + // ige.devLog(isUsed, self._stats.quantity , self._stats.quantity > 0) + if (isUsed && self._stats.quantity > 0) { + self.updateQuantity(self._stats.quantity - self.quantityCost); } - - }, self._stats.delayBeforeUse); + } }, updateQuantity: function (qty) {