Added collidable areas which can trigger a script, started work on AI, fixed position secured, updated engine

This commit is contained in:
Light2
2013-12-02 23:58:22 +01:00
parent 6857bd562b
commit 30e1e1c8ec
19 changed files with 574 additions and 26 deletions

View File

@@ -28,8 +28,8 @@
<classpathentry kind="lib" path="lib/MINA/mina-integration-xbean-2.0.4.jar"/>
<classpathentry kind="lib" path="lib/MINA/mina-statemachine-2.0.4.jar"/>
<classpathentry kind="lib" path="lib/MINA/mina-transport-apr-2.0.4.jar"/>
<classpathentry kind="lib" path="ngengine_public.jar"/>
<classpathentry kind="lib" path="lib/mbassador-1.1.7.jar"/>
<classpathentry kind="lib" path="lib/commons-lang3-3.1.jar"/>
<classpathentry kind="lib" path="ngengine_public.jar"/>
<classpathentry kind="lib" path="lib/mbassador-1.1.9.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

Binary file not shown.

BIN
lib/mbassador-1.1.9.jar Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -43,8 +43,8 @@ def removeBuff(core, actor, buff):
if actor.getGroupId() != 0 and core.objectService.getObject(actor.getGroupId()):
group = core.objectService.getObject(actor.getGroupId())
for member in group.getMemberList():
core.buffService.removeBuffToCreature(member, 'co_base_of_operations')
core.buffService.removeBuffFromCreature(member, member.getBuffByName('co_base_of_operations'))
else:
core.buffService.removeBuffToCreature(actor, 'co_base_of_operations')
core.buffService.removeBuffFromCreature(actor, actor.getBuffByName('co_base_of_operations'))
return

View File

@@ -6,7 +6,7 @@ def setup():
def run(core, actor, target, commandString):
if actor.hasBuff('co_position_secured'):
core.buffService.removeBuffFromCreature(actor, actor.getBuff('co_position_secured'))
core.buffService.removeBuffFromCreature(actor, actor.getBuffByName('co_position_secured'))
else:
core.buffService.addBuffToCreature(actor, 'co_position_secured')

View File

@@ -2,13 +2,10 @@ import sys
def add(core, actor, name, base):
actor.addSkillMod(name, base)
actor.getSkillMod(name).setModifier(10)
modifier = actor.getSkillMod(name).getModifier()
actor.setSpeedMultiplierBase(actor.getSpeedMultiplierBase() + float(float(base) / float(modifier)))
actor.setSpeedMultiplierBase(actor.getSpeedMultiplierBase() + base / 100)
return
def deduct(core, actor, name, base):
modifier = actor.getSkillMod(name).getModifier()
actor.setSpeedMultiplierBase(actor.getSpeedMultiplierBase() - float(float(base) / float(modifier)))
actor.setSpeedMultiplierBase(actor.getSpeedMultiplierBase() - base / 100)
actor.deductSkillMod(name, base)
return

View File

@@ -0,0 +1,83 @@
/*******************************************************************************
* Copyright (c) 2013 <Project SWG>
*
* This File is part of NGECore2.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Using NGEngine to work with NGECore2 is making a combined work based on NGEngine.
* Therefore all terms and conditions of the GNU Lesser General Public License cover the combination.
******************************************************************************/
package resources.common.collidables;
import java.util.Vector;
import main.NGECore;
import org.python.core.Py;
import org.python.core.PyObject;
import engine.resources.objects.SWGObject;
import engine.resources.scene.Planet;
public abstract class AbstractCollidable {
private PyObject callback;
public Vector<SWGObject> collidedObjects = new Vector<SWGObject>();
private Planet planet;
public abstract boolean doesCollide(SWGObject obj);
public PyObject getCallback() {
return callback;
}
public void setCallback(PyObject callback) {
this.callback = callback;
}
public void addCollidedObject(SWGObject obj) {
collidedObjects.add(obj);
}
public void removeCollidedObject(SWGObject obj) {
collidedObjects.remove(obj);
}
public boolean isInCollisionList(SWGObject obj) {
return collidedObjects.contains(obj);
}
public void doCollisionCheck(SWGObject obj) {
// check if already collided
if(isInCollisionList(obj) && doesCollide(obj)) {
return;
} else if(isInCollisionList(obj) && !doesCollide(obj)) {
removeCollidedObject(obj);
} else if(doesCollide(obj) && !isInCollisionList(obj)) {
addCollidedObject(obj);
if(getCallback() != null)
getCallback().__call__(Py.java2py(NGECore.getInstance()), Py.java2py(obj), Py.java2py(this));
}
}
public Planet getPlanet() {
return planet;
}
public void setPlanet(Planet planet) {
this.planet = planet;
}
}

View File

@@ -0,0 +1,28 @@
/*******************************************************************************
* Copyright (c) 2013 <Project SWG>
*
* This File is part of NGECore2.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Using NGEngine to work with NGECore2 is making a combined work based on NGEngine.
* Therefore all terms and conditions of the GNU Lesser General Public License cover the combination.
******************************************************************************/
package resources.common.collidables;
public class CollidableBox {
}

View File

@@ -0,0 +1,74 @@
/*******************************************************************************
* Copyright (c) 2013 <Project SWG>
*
* This File is part of NGECore2.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Using NGEngine to work with NGECore2 is making a combined work based on NGEngine.
* Therefore all terms and conditions of the GNU Lesser General Public License cover the combination.
******************************************************************************/
package resources.common.collidables;
import engine.resources.objects.SWGObject;
import engine.resources.scene.Planet;
import engine.resources.scene.Point3D;
public class CollidableCircle extends AbstractCollidable {
private Point3D center;
private float radius;
// for bh traps
private boolean useYAxis = false;
public CollidableCircle(Point3D center, float radius, Planet planet) {
this.setCenter(center);
this.setRadius(radius);
this.setPlanet(planet);
}
public Point3D getCenter() {
return center;
}
public void setCenter(Point3D center) {
this.center = center;
}
public float getRadius() {
return radius;
}
public void setRadius(float radius) {
this.radius = radius;
}
public boolean isUseYAxis() {
return useYAxis;
}
public void setUseYAxis(boolean useYAxis) {
this.useYAxis = useYAxis;
}
@Override
public boolean doesCollide(SWGObject obj) {
Point3D objectPos = obj.getWorldPosition();
if(useYAxis) {
return center.getDistance(objectPos) <= radius && objectPos.y == center.y;
} else {
return center.getDistance(objectPos) <= radius;
}
}
}

View File

@@ -541,7 +541,7 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder {
}
public IoBuffer buildSpeedModDelta(float speed) {
public IoBuffer buildSpeedModBaseDelta(float speed) {
IoBuffer buffer = bufferPool.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN);
buffer.putFloat(speed);
@@ -552,6 +552,19 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder {
return buffer;
}
public IoBuffer buildSpeedModDelta(float speedModifier) {
IoBuffer buffer = bufferPool.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN);
buffer.putFloat(speedModifier);
int size = buffer.position();
buffer.flip();
buffer = createDelta("CREO", (byte) 4, (short) 1, (short) 5, buffer, size + 4);
return buffer;
}
public IoBuffer buildTurnRadiusDelta(float turnRadius) {

View File

@@ -492,7 +492,7 @@ public class CreatureObject extends TangibleObject implements IPersistent {
synchronized(objectMutex) {
this.speedMultiplierBase = speedMultiplierBase;
}
IoBuffer speedDelta = messageBuilder.buildSpeedModDelta(speedMultiplierBase);
IoBuffer speedDelta = messageBuilder.buildSpeedModBaseDelta(speedMultiplierBase);
notifyObservers(speedDelta, true);
@@ -508,6 +508,9 @@ public class CreatureObject extends TangibleObject implements IPersistent {
synchronized(objectMutex) {
this.speedMultiplierMod = speedMultiplierMod;
}
IoBuffer speedDelta = messageBuilder.buildSpeedModDelta(speedMultiplierMod);
notifyObservers(speedDelta, true);
}
public long getListenToId() {

View File

@@ -199,7 +199,7 @@ public class GroupService implements INetworkDispatch {
}
public void removeGroupBuffs(CreatureObject member) {
for(Buff buff : member.getBuffList().get()) {
for(Buff buff : new ArrayList<Buff>(member.getBuffList().get())) {
if(buff.isGroupBuff() && buff.getGroupBufferId() != member.getObjectID()) {
core.buffService.removeBuffFromCreature(member, buff);
}

View File

@@ -69,6 +69,7 @@ import resources.objects.cell.CellObject;
import resources.objects.creature.CreatureObject;
import resources.objects.player.PlayerObject;
import resources.common.*;
import resources.common.collidables.AbstractCollidable;
import toxi.geom.Line3D;
import toxi.geom.Ray3D;
import toxi.geom.Vec3D;
@@ -91,6 +92,9 @@ import wblut.math.WB_M44;
public class SimulationService implements INetworkDispatch {
Map<String, QuadTree<SWGObject>> quadTrees;
Map<String, QuadTree<AbstractCollidable>> collidableQuadTrees;
private NGECore core;
private Map<String, MeshVisitor> cellMeshes = new ConcurrentHashMap<String, MeshVisitor>();
@@ -98,9 +102,11 @@ public class SimulationService implements INetworkDispatch {
this.core = core;
TerrainService terrainService = core.terrainService;
quadTrees = new ConcurrentHashMap<String, QuadTree<SWGObject>>();
collidableQuadTrees = new ConcurrentHashMap<String, QuadTree<AbstractCollidable>>();
for (int i = 0; i < core.terrainService.getPlanetList().size(); i++) {
quadTrees.put(terrainService.getPlanetList().get(i).getName(), new QuadTree<SWGObject>(-8192, -8192, 8192, 8192));
collidableQuadTrees.put(terrainService.getPlanetList().get(i).getName(), new QuadTree<AbstractCollidable>(-8192, -8192, 8192, 8192));
}
core.commandService.registerCommand("opencontainer");
@@ -146,6 +152,18 @@ public class SimulationService implements INetworkDispatch {
}
}
public void addCollidable(AbstractCollidable collidable, float x, float y) {
collidableQuadTrees.get(collidable.getPlanet().getName()).put(x, y, collidable);
}
public void removeCollidable(AbstractCollidable collidable, float x, float y) {
collidableQuadTrees.get(collidable.getPlanet().getName()).remove(x, y, collidable);
}
public List<AbstractCollidable> getCollidables(Planet planet, float x, float y, float range) {
return collidableQuadTrees.get(planet.getName()).get(x, y, range);
}
public void add(SWGObject object, int x, int y) {
object.setIsInQuadtree(true);
core.objectService.loadServerTemplate(object);
@@ -275,7 +293,7 @@ public class SimulationService implements INetworkDispatch {
}
}
checkForCollidables(object);
}
@@ -326,6 +344,8 @@ public class SimulationService implements INetworkDispatch {
object.setOrientation(newOrientation);
object.setMovementCounter(dataTransform.getMovementCounter());
object.notifyObservers(utm, false);
checkForCollidables(object);
}
@@ -466,6 +486,14 @@ public class SimulationService implements INetworkDispatch {
if(object.getGroupId() != 0)
core.groupService.handleGroupDisband(object);
Point3D objectPos = object.getWorldPosition();
List<AbstractCollidable> collidables = getCollidables(object.getPlanet(), objectPos.x, objectPos.z, 512);
for(AbstractCollidable collidable : collidables) {
collidables.remove(object);
}
if (ghost != null) {
String objectShortName = object.getCustomName();
@@ -917,5 +945,14 @@ public class SimulationService implements INetworkDispatch {
}
}
public void checkForCollidables(SWGObject object) {
Point3D objectPos = object.getWorldPosition();
List<AbstractCollidable> collidables = getCollidables(object.getPlanet(), objectPos.x, objectPos.z, 256);
for(AbstractCollidable collidable : collidables) {
collidable.doCollisionCheck(object);
}
}
}

View File

@@ -0,0 +1,57 @@
/*******************************************************************************
* Copyright (c) 2013 <Project SWG>
*
* This File is part of NGECore2.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Using NGEngine to work with NGECore2 is making a combined work based on NGEngine.
* Therefore all terms and conditions of the GNU Lesser General Public License cover the combination.
******************************************************************************/
package services.ai;
import engine.resources.scene.Point3D;
import resources.objects.creature.CreatureObject;
public class AIActor {
private CreatureObject creature;
private Point3D spawnPosition;
public AIActor(CreatureObject creature, Point3D spawnPosition) {
this.creature = creature;
this.spawnPosition = spawnPosition;
}
public CreatureObject getCreature() {
return creature;
}
public void setCreature(CreatureObject creature) {
this.creature = creature;
}
public Point3D getSpawnPosition() {
return spawnPosition;
}
public void setSpawnPosition(Point3D spawnPosition) {
this.spawnPosition = spawnPosition;
}
public void doAggro(CreatureObject defender) {
}
}

View File

@@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright (c) 2013 <Project SWG>
*
* This File is part of NGECore2.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Using NGEngine to work with NGECore2 is making a combined work based on NGEngine.
* Therefore all terms and conditions of the GNU Lesser General Public License cover the combination.
******************************************************************************/
package services.ai;
public class AIService {
}

View File

@@ -0,0 +1,137 @@
/*******************************************************************************
* Copyright (c) 2013 <Project SWG>
*
* This File is part of NGECore2.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Using NGEngine to work with NGECore2 is making a combined work based on NGEngine.
* Therefore all terms and conditions of the GNU Lesser General Public License cover the combination.
******************************************************************************/
package services.ai;
import java.util.Vector;
import net.engio.mbassy.listener.Handler;
import resources.objects.creature.CreatureObject;
import resources.objects.tangible.TangibleObject;
import services.combat.CombatEvents.DamageTaken;
public class LairActor {
private Vector<AIActor> creatures = new Vector<AIActor>();
private TangibleObject lairObject;
private int maxSpawns;
private String creatureTemplate;
private volatile int spawnWave = 0;
public LairActor(TangibleObject lairObject, String creatureTemplate) {
this.lairObject = lairObject;
this.creatureTemplate = creatureTemplate;
lairObject.getEventBus().subscribe(this);
}
public LairActor(TangibleObject lairObject, String creatureTemplate, int maxSpawns) {
this.lairObject = lairObject;
this.creatureTemplate = creatureTemplate;
this.maxSpawns = maxSpawns;
lairObject.getEventBus().subscribe(this);
}
public Vector<AIActor> getCreatures() {
return creatures;
}
public TangibleObject getLairObject() {
return lairObject;
}
public void setLairObject(TangibleObject lairObject) {
this.lairObject = lairObject;
}
@Handler
public void handleLairDamageEvent(DamageTaken event) {
for(AIActor ai : creatures) {
ai.doAggro(event.attacker);
}
spawnNewCreatures();
}
private void spawnNewCreatures() {
if(creatures.size() >= maxSpawns)
return;
int currentCondition = lairObject.getConditionDamage();
int maxCondition = lairObject.getMaxDamage();
switch(spawnWave) {
// TODO: play damage effect
case 0:
spawnWave++;
break;
case 1:
if((currentCondition / maxCondition) < 0.7) {
spawnWave++;
} else {
return;
}
case 2:
if((currentCondition / maxCondition) < 0.3) {
spawnWave++;
} else {
return;
}
break;
case 3:
return;
default:
return;
}
// TODO: spawn creatures
healLair();
}
private void healLair() {
}
public int getMaxSpawns() {
return maxSpawns;
}
public void setMaxSpawns(int maxSpawns) {
this.maxSpawns = maxSpawns;
}
public String getCreatureTemplate() {
return creatureTemplate;
}
public void setCreatureTemplate(String creatureTemplate) {
this.creatureTemplate = creatureTemplate;
}
}

View File

@@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2013 <Project SWG>
*
* This File is part of NGECore2.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Using NGEngine to work with NGECore2 is making a combined work based on NGEngine.
* Therefore all terms and conditions of the GNU Lesser General Public License cover the combination.
******************************************************************************/
package services.combat;
import resources.objects.creature.CreatureObject;
import engine.resources.common.Event;
public class CombatEvents {
public class DamageTaken implements Event {
public CreatureObject attacker;
}
}

View File

@@ -322,7 +322,7 @@ public class CombatService implements INetworkDispatch {
int armorAbsorbed = (int) (damageBeforeArmor - damage);
if(mitigationType == HitType.BLOCK) {
float blockValue = (attacker.getStrength() + attacker.getSkillMod("combat_block_value").getBase()) / 2 + 25;
float blockValue = (attacker.getStrength() + attacker.getSkillModBase("combat_block_value")) / 2 + 25;
damage -= blockValue;
}
@@ -487,8 +487,7 @@ public class CombatService implements INetworkDispatch {
if(actionCost == 0 && healthCost == 0)
return true;
if(attacker.getSkillMod("expertise_action_all") != null)
actionCost *= attacker.getSkillMod("expertise_action_all").getBase();
actionCost *= getWeaponActionCostReduction(attacker, weapon);
float newAction = attacker.getAction() - actionCost;
if(newAction <= 0)
@@ -566,6 +565,8 @@ public class CombatService implements INetworkDispatch {
}
rawDamage *= getWeaponDamageIncrease(attacker, weapon);
if(target.getSkillMod("damage_decrease_percentage") != null) {
rawDamage *= (1 - (target.getSkillMod("damage_decrease_percentage").getBase() / 100));
}
@@ -573,11 +574,7 @@ public class CombatService implements INetworkDispatch {
if(target.getSkillMod("combat_divide_damage_dealt") != null) {
rawDamage *= (1 - (target.getSkillMod("combat_divide_damage_dealt").getBase() / 100));
}
if(attacker.getSkillMod("expertise_damage_melee") != null) {
rawDamage *= (1 + (attacker.getSkillMod("expertise_damage_melee").getBase() / 100));
}
return rawDamage;
}
@@ -701,7 +698,7 @@ public class CombatService implements INetworkDispatch {
float r;
Random random = new Random();
float blockChance = (float) target.getSkillMod("display_only_block").getBase() / 10000;
float blockChance = (float) target.getSkillModBase("display_only_block") / 10000;
r = random.nextFloat();
if(r <= blockChance)
@@ -709,7 +706,7 @@ public class CombatService implements INetworkDispatch {
if(command.getAttackType() == 0 || command.getAttackType() == 2 || command.getAttackType() == 3) {
float evasionChance = (float) target.getSkillMod("display_only_evasion").getBase() / 10000;
float evasionChance = (float) target.getSkillModBase("display_only_evasion") / 10000;
r = random.nextFloat();
if(r <= evasionChance)
@@ -719,7 +716,7 @@ public class CombatService implements INetworkDispatch {
if(hitType == HitType.HIT && target.getSkillMod("display_only_glancing_blow") != null) {
float glanceChance = (float) target.getSkillMod("display_only_glancing_blow").getBase() / 10000;
float glanceChance = (float) target.getSkillModBase("display_only_glancing_blow") / 10000;
r = random.nextFloat();
if(r <= glanceChance)
@@ -1248,7 +1245,68 @@ public class CombatService implements INetworkDispatch {
target.notifyObservers(new PlayClientEffectLocMessage("appearance/pt_heal_2.prt", target.getPlanet().getName(), target.getWorldPosition()), true);
}
}
public float getWeaponActionCostReduction(CreatureObject attacker, WeaponObject weapon) {
int weaponType = weapon.getWeaponType();
int actionReduction;
switch(weaponType) {
case 0: actionReduction = attacker.getSkillModBase("expertise_action_weapon_0");
case 1: actionReduction = attacker.getSkillModBase("expertise_action_weapon_1");
case 2: actionReduction = attacker.getSkillModBase("expertise_action_weapon_2");
case 4: actionReduction = attacker.getSkillModBase("expertise_action_weapon_4");
case 5: actionReduction = attacker.getSkillModBase("expertise_action_weapon_5");
case 6: actionReduction = attacker.getSkillModBase("expertise_action_weapon_6");
case 7: actionReduction = attacker.getSkillModBase("expertise_action_weapon_7");
case 8: actionReduction = attacker.getSkillModBase("expertise_action_weapon_8");
case 9: actionReduction = attacker.getSkillModBase("expertise_action_weapon_9");
case 10: actionReduction = attacker.getSkillModBase("expertise_action_weapon_10");
case 11: actionReduction = attacker.getSkillModBase("expertise_action_weapon_11");
case 12: actionReduction = attacker.getSkillModBase("expertise_action_weapon_3");
default: actionReduction = 0;
}
actionReduction += attacker.getSkillModBase("expertise_action_all");
return 1 + (actionReduction / 100);
}
public float getWeaponDamageIncrease(CreatureObject attacker, WeaponObject weapon) {
int weaponType = weapon.getWeaponType();
int weaponDmgIncrease;
switch(weaponType) {
case 0: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_0");
case 1: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_1");
case 2: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_2");
case 4: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_4");
case 5: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_5");
case 6: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_6");
case 7: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_7");
case 8: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_8");
case 9: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_9");
case 10: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_10");
case 11: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_11");
case 12: weaponDmgIncrease = attacker.getSkillModBase("expertise_damage_weapon_3");
default: weaponDmgIncrease = 0;
}
weaponDmgIncrease += attacker.getSkillModBase("expertise_damage_all");
return 1 + (weaponDmgIncrease / 100);
}
public enum HitType{;