mirror of
https://bitbucket.org/projectswg/cucore.git
synced 2026-01-16 23:04:20 -05:00
Merge holocore/quality_assurance into quality_assurance
Conflicts: cfg/nge.cfg src/services/commands/CommandService.java
This commit is contained in:
15
cfg/nge.cfg
15
cfg/nge.cfg
@@ -1,15 +0,0 @@
|
||||
# 24/08/2016 23:29:51 CEST
|
||||
CLEAN-CHARACTER-DATA=0
|
||||
ENABLE-LOGGING=true
|
||||
GALAXY-MAX-CHARACTERS=5
|
||||
GALAXY-MAX-CHARACTERS-PER-PERIOD=5
|
||||
GALAXY-MAX-ONLINE=3000
|
||||
GALAXY-NAME=Holocore
|
||||
LOAD-OBJECTS=true
|
||||
LOCAL-DB=nge
|
||||
LOCAL-PASS=nge
|
||||
LOCAL-USER=nge
|
||||
LOG-LEVEL=DEBUG
|
||||
PACKET-DEBUG=false
|
||||
PRIMARY-SPAWN-LOCATION=tat_moseisley
|
||||
WIPE-ODB-FILES=0
|
||||
@@ -3,5 +3,5 @@ function canPerform(source, target, command) {
|
||||
}
|
||||
|
||||
function doCombat(source, target, command) {
|
||||
return 100;
|
||||
return 0;
|
||||
}
|
||||
|
||||
7
scripts/commands/combat/rangedShot.js
Normal file
7
scripts/commands/combat/rangedShot.js
Normal file
@@ -0,0 +1,7 @@
|
||||
function canPerform(source, target, command) {
|
||||
return (Java.type("resources.combat.CombatStatus")).SUCCESS;
|
||||
}
|
||||
|
||||
function doCombat(source, target, command) {
|
||||
return 0;
|
||||
}
|
||||
7
scripts/commands/combat/rangedShotpistol.js
Normal file
7
scripts/commands/combat/rangedShotpistol.js
Normal file
@@ -0,0 +1,7 @@
|
||||
function canPerform(source, target, command) {
|
||||
return (Java.type("resources.combat.CombatStatus")).SUCCESS;
|
||||
}
|
||||
|
||||
function doCombat(source, target, command) {
|
||||
return 0;
|
||||
}
|
||||
7
scripts/commands/combat/rangedShotrifle.js
Normal file
7
scripts/commands/combat/rangedShotrifle.js
Normal file
@@ -0,0 +1,7 @@
|
||||
function canPerform(source, target, command) {
|
||||
return (Java.type("resources.combat.CombatStatus")).SUCCESS;
|
||||
}
|
||||
|
||||
function doCombat(source, target, command) {
|
||||
return 0;
|
||||
}
|
||||
4
scripts/commands/generic/cmdCoupDeGrace.js
Normal file
4
scripts/commands/generic/cmdCoupDeGrace.js
Normal file
@@ -0,0 +1,4 @@
|
||||
function executeCommand(galacticManager, player, target, args) {
|
||||
var DeathblowIntent = Java.type("intents.combat.DeathblowIntent");
|
||||
new DeathblowIntent(player.getCreatureObject(), target).broadcast();
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
name valid_target force_combat sac_action sac_mind use_weapon_sac animations
|
||||
TEXT INTEGER INTEGER INTEGER INTEGER INTEGER TEXT
|
||||
meleeHit 0 1 0 0 0 combo_2a_light,combo_2b_light,combo_2c_light,combo_2d_light,combo_2e_light
|
||||
name valid_target force_combat sac_action sac_mind use_weapon_sac animations percentAddFromWeapon
|
||||
TEXT INTEGER INTEGER INTEGER INTEGER INTEGER TEXT REAL
|
||||
meleeHit 0 1 0 0 0 combo_2a_light,combo_2b_light,combo_2c_light,combo_2d_light,combo_2e_light 1
|
||||
rangedShot 0 1 0 0 0 fire_1_special_single_light 1
|
||||
@@ -86,7 +86,7 @@ weapon_event_hairtrigger_carbine_03_01 object/weapon/ranged/carbine/event_carbin
|
||||
weapon_eweb_blaster_rifle object/weapon/ranged/rifle/rifle_eweb.iff weapon E-Web Rifle 1 1000 485 980 ranged_weapon RIFLE energy none 0 80 100 0 64 - 915 915 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 90 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE TRUE FALSE - 0 0 FALSE 0 4 1 - -
|
||||
weapon_gcw_carbine_charric_03_01 object/weapon/ranged/carbine/carbine_charric.iff weapon Charric Carbine 1 1000 242 482 ranged_weapon CARBINE kinetic none 0 60 100 0 50 - 603 603 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 65 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE TRUE FALSE - 0 600 FALSE 0 3 2 - -
|
||||
weapon_gcw_dh18a_pistol_03_01 object/weapon/ranged/pistol/pistol_dh18a_gcw.iff weapon DH-18A Blaster Pistol Prototype 1 1000 161 321 ranged_weapon PISTOL kinetic none 0 40 100 0 35 - 603 602 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 65 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE TRUE FALSE - 0 600 FALSE 0 3 2 - -
|
||||
weapon_gcw_heavy_pulse_cannon_03_01 object/weapon/ranged/heavy/heavy_pulse_cannon.iff weapon Pulse Cannon 1 1000 462 777 ranged_weapon HEAVY_WEAPON kinetic heat 15 100 100 0 64 - 643 643 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 65 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE TRUE FALSE - 0 600 FALSE 0 3 2 GCW -
|
||||
weapon_gcw_heavy_pulse_cannon_03_01 object/weapon/ranged/heavy/heavy_pulse_cannon.iff weapon Pulse Cannon 1 1000 462 777 ranged_weapon GROUND_TARGETTING kinetic heat 15 100 100 0 64 - 643 643 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 65 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE TRUE FALSE - 0 600 FALSE 0 3 2 GCW -
|
||||
weapon_gcw_lance_03_01 object/weapon/melee/polearm/lance_gcw_gand_shockprod.iff weapon Gand Shockprod Staff 1 1000 428 655 melee_weapon POLEARM_MELEE kinetic none 0 100 100 0 5 - 567 562 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 65 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE TRUE FALSE - 0 600 FALSE 0 3 2 - -
|
||||
weapon_gcw_tc22_rifle_03_01 object/weapon/ranged/rifle/rifle_tc22_blaster.iff weapon TC-22 Blaster Rifle Replica 1 1000 322 643 ranged_weapon RIFLE kinetic none 0 80 100 0 64 - 603 602 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 65 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE TRUE FALSE - 0 600 FALSE 0 3 2 - -
|
||||
weapon_grenade_fragmentation_01_01 object/weapon/ranged/grenade/grenade_fragmentation_generic.iff weapon Fragmentation Grenade 1 1000 325 650 ranged_weapon THROWN kinetic none 0 1000 100 0 40 - 49 49 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 1 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 0 FALSE 3 2 1 - int:reuseTimer=5,string:effect_class=fragmentation
|
||||
@@ -103,9 +103,9 @@ weapon_knuckler_ent_roadmap_02_03 object/weapon/melee/special/vibroknuckler_stat
|
||||
weapon_knuckler_ent_roadmap_02_04 object/weapon/melee/special/vibroknuckler_static.iff weapon Glamour Vibroknuckler 1 1000 190 375 melee_weapon UNARMED kinetic none 0 100 100 0 5 - 282 283 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 30 entertainer TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE strength_modified=5 0 1 FALSE 0 2 1 lvl 30 roadmap -
|
||||
weapon_knuckler_fs_roadmap_01_02 object/weapon/melee/special/vibroknuckler_static.iff weapon Precise Knuckler 1 1000 334 668 melee_weapon UNARMED kinetic none 0 100 100 0 5 - 501 501 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 50 force_sensitive TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE strength_modified=3 0 4500 FALSE 0 2 2 lvl 50 roadmap -
|
||||
weapon_knuckler_fs_roadmap_02_02 object/weapon/melee/special/vibroknuckler_static.iff weapon Neophyte Vibroknuckler 1 1000 188 375 melee_weapon UNARMED kinetic none 0 100 100 0 5 - 282 282 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 30 force_sensitive TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE strength_modified=5 0 2200 FALSE 0 2 2 lvl 30 roadmap -
|
||||
weapon_knuckler_smuggler_roadmap_01_02 object/weapon/ranged/pistol/pistol_scout_blaster_static.iff weapon Scoundrel's Scout Blaster 1 1000 73 145 ranged_weapon UNARMED kinetic none 0 40 100 0 35 - 282 273 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 30 smuggler TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE precision_modified=5 0 2200 FALSE 0 2 2 lvl 30 roadmap -
|
||||
weapon_knuckler_smuggler_roadmap_02_02 object/weapon/ranged/pistol/pistol_striker_static.iff weapon Precise Striker Pistol 1 1000 131 261 ranged_weapon UNARMED kinetic none 0 40 100 0 35 - 490 490 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 50 smuggler TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE precision_modified=10 0 4500 FALSE 0 2 2 lvl 50 roadmap -
|
||||
weapon_lightningbeam_commando_roadmap_01_02 object/weapon/ranged/rifle/rifle_dlt20.iff weapon Precise DLT-20 1 1000 182 363 ranged_weapon HEAVY_WEAPON energy none 0 100 100 0 64 - 273 273 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 30 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE precision_modified=5 0 2200 FALSE 0 2 2 lvl 30 roadmap -
|
||||
weapon_knuckler_smuggler_roadmap_01_02 object/weapon/ranged/pistol/pistol_scout_blaster_static.iff weapon Scoundrel's Scout Blaster 1 1000 73 145 ranged_weapon PISTOL kinetic none 0 40 100 0 35 - 282 273 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 30 smuggler TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE precision_modified=5 0 2200 FALSE 0 2 2 lvl 30 roadmap -
|
||||
weapon_knuckler_smuggler_roadmap_02_02 object/weapon/ranged/pistol/pistol_striker_static.iff weapon Precise Striker Pistol 1 1000 131 261 ranged_weapon PISTOL kinetic none 0 40 100 0 35 - 490 490 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 50 smuggler TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE precision_modified=10 0 4500 FALSE 0 2 2 lvl 50 roadmap -
|
||||
weapon_lightningbeam_commando_roadmap_01_02 object/weapon/ranged/rifle/rifle_dlt20.iff weapon Precise DLT-20 1 1000 182 363 ranged_weapon RIFLE energy none 0 100 100 0 64 - 273 273 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 30 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE precision_modified=5 0 2200 FALSE 0 2 2 lvl 30 roadmap -
|
||||
weapon_magna_guard_polearm_04_01 object/weapon/melee/polearm/lance_staff_magna_guard.iff weapon MagnaGuard Electrostaff 1 1000 700 1000 melee_weapon POLEARM_MELEE kinetic electricity 20 100 100 0 5 - 900 890 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 75 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE TRUE FALSE - 0 1000 FALSE 0 4 1 pvp BF reward -
|
||||
weapon_mandalorian_carbine_04_01 object/weapon/ranged/carbine/carbine_mandalorian.iff weapon Crusader M-XIII Carbine 1 1000 415 755 ranged_weapon CARBINE energy none 0 60 100 0 50 - 975 975 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 75 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE precision_modified=10,constitution_modified=5 0 5000 FALSE 0 4 1 - -
|
||||
weapon_mandalorian_heavy_04_01 object/weapon/ranged/heavy/heavy_mandalorian.iff weapon Crusader M-XX Heavy Rifle 1 1000 800 1300 ranged_weapon GROUND_TARGETTING kinetic electricity 50 100 100 0 64 - 1050 1050 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 75 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE TRUE FALSE precision_modified=10,constitution_modified=5 0 5000 FALSE 0 4 2 - -
|
||||
@@ -150,7 +150,7 @@ weapon_pistol_spy_roadmap_01_02 object/weapon/ranged/pistol/pistol_striker_stati
|
||||
weapon_pistol_trader_roadmap_01_02 object/weapon/ranged/pistol/pistol_scout_blaster_static.iff weapon Trader's Friend 1 1000 250 500 ranged_weapon PISTOL energy none 0 40 100 0 35 - 120 938 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 50 trader TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 250 FALSE 0 2 1 noncombat roadmap -
|
||||
weapon_polearm_02_01 object/weapon/melee/polearm/lance_staff_wood_s2.iff weapon Basic Wood Staff 1 1000 43 86 melee_weapon POLEARM_MELEE kinetic none 0 100 100 0 5 - 65 65 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 5 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE melee_accuracy=1 0 45 FALSE 0 2 1 level 5 required -
|
||||
weapon_polearm_02_02 object/weapon/melee/polearm/lance_staff_wood_s2_npe.iff weapon Issued Staff 1 1000 29 58 melee_weapon POLEARM_MELEE kinetic none 0 100 100 0 5 - 44 44 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 1 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 45 FALSE 0 2 1 level 1 npe -
|
||||
weapon_polearm_02_03 object/weapon/melee/polearm/polearm_vibro_axe_npe.iff weapon Jedi Training Polearm 1 1000 43 75 melee_weapon POLEARM_MELEE kinetic none 0 100 100 0 5 - 59 59 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 1 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 45 FALSE 0 2 1 level 3 NPE -
|
||||
weapon_polearm_02_03 object/weapon/melee/polearm/polearm_vibro_axe_npe.iff weapon Jedi Training Polearm 1 1000 43 75 melee_weapon POLEARM_MELEE kinetic none 0 100 100 0 5 - 59 59 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 1 force_sensitive TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 45 FALSE 0 2 1 Jedi starter weapon -
|
||||
weapon_polearm_02_04 object/weapon/melee/polearm/lance_staff_wood_s2_npe.iff weapon Reinforced Staff 1 1000 46 91 melee_weapon POLEARM_MELEE kinetic none 0 100 100 0 5 - 69 69 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 6 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 200 FALSE 0 2 1 level 6 npe -
|
||||
weapon_polearm_02_05 object/weapon/melee/polearm/lance_staff_wood_s2_npe.iff weapon Reinforced Staff 1 1000 64 128 melee_weapon POLEARM_MELEE kinetic none 0 100 100 0 5 - 96 96 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 9 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 300 FALSE 0 2 1 level 9 npe -
|
||||
weapon_polearm_04_01 object/weapon/melee/polearm/lance_controllerfp_npe.iff weapon Modified Lance 1 1000 85 170 melee_weapon POLEARM_MELEE kinetic none 0 100 100 0 5 - 128 128 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 13 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 400 FALSE 0 4 1 level 13 npe -
|
||||
@@ -228,16 +228,16 @@ weapon_tow_carbine_geo_05_01 object/weapon/ranged/carbine/carbine_geo_generic.if
|
||||
weapon_tow_carbine_sfor_03_01 object/weapon/ranged/carbine/som_carbine_republic_sfor_generic.iff weapon Kubaza Carbine 1 1000 375 750 ranged_weapon CARBINE energy electricity 28 60 100 0 50 - 938 938 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 6000 FALSE 0 3 1 ToW expansion -
|
||||
weapon_tow_carbine_sfor_05_01 object/weapon/ranged/carbine/som_carbine_republic_sfor_generic.iff weapon HK-47 Carbine 1 1000 395 790 ranged_weapon CARBINE energy electricity 34 60 100 0 50 - 938 988 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 7000 FALSE 0 5 1 ToW expansion -
|
||||
weapon_tow_carbine_wookiee_06_01 object/weapon/ranged/carbine/ep3/carbine_wookiee_bowcaster_generic.iff weapon Malevolent Bowcaster 1 1000 395 790 ranged_weapon CARBINE energy none 0 60 100 0 50 - 938 988 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 - TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE - 0 10000 FALSE 0 6 1 ToW expansion -
|
||||
weapon_tow_flamer_01_01 object/weapon/ranged/heavy/som_republic_flamer_generic.iff weapon Heavy Republic Flame Thrower 1 1000 148 295 ranged_weapon DIRECTIONAL energy heat 28 25 100 0 20 - 938 886 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE precision_modified=10 0 4000 FALSE 0 1 2 ToW expansion float:intAOEDamagePercent=0.55,int:intWeaponType=9
|
||||
weapon_tow_flamer_02_01 object/weapon/ranged/heavy/som_republic_flamer_generic.iff weapon Heavy Republic Flame Thrower 1 1000 153 305 ranged_weapon DIRECTIONAL energy heat 30 25 100 0 20 - 938 916 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE precision_modified=11 0 4500 FALSE 0 2 2 ToW expansion float:intAOEDamagePercent=0.55,int:intWeaponType=9
|
||||
weapon_tow_flamer_03_01 object/weapon/ranged/heavy/som_republic_flamer_generic.iff weapon Heavy Republic Flame Thrower 1 1000 156 312 ranged_weapon DIRECTIONAL energy heat 32 25 100 0 20 - 938 936 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE precision_modified=11 0 6000 FALSE 0 3 2 ToW expansion float:intAOEDamagePercent=0.55,int:intWeaponType=9
|
||||
weapon_tow_flamer_04_01 object/weapon/ranged/heavy/som_republic_flamer_generic.iff weapon Heavy Republic Flame Thrower 1 1000 162 323 ranged_weapon DIRECTIONAL energy heat 34 25 100 0 20 - 938 970 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE precision_modified=12 0 6500 FALSE 0 4 2 ToW expansion float:intAOEDamagePercent=0.55,int:intWeaponType=9
|
||||
weapon_tow_flamer_05_01 object/weapon/ranged/heavy/som_republic_flamer_generic.iff weapon Heavy Republic Flame Thrower 1 1000 165 329 ranged_weapon DIRECTIONAL energy heat 40 25 100 0 20 - 938 988 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE precision_modified=12 0 7000 FALSE 0 5 2 ToW expansion float:intAOEDamagePercent=0.55,int:intWeaponType=9
|
||||
weapon_tow_flamer_01_01 object/weapon/ranged/heavy/som_republic_flamer_generic.iff weapon Heavy Republic Flame Thrower 1 1000 148 295 ranged_weapon DIRECTIONAL_TARGET_WEAPON energy heat 28 25 100 0 20 - 938 886 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE precision_modified=10 0 4000 FALSE 0 1 2 ToW expansion float:intAOEDamagePercent=0.55,int:intWeaponType=9
|
||||
weapon_tow_flamer_02_01 object/weapon/ranged/heavy/som_republic_flamer_generic.iff weapon Heavy Republic Flame Thrower 1 1000 153 305 ranged_weapon DIRECTIONAL_TARGET_WEAPON energy heat 30 25 100 0 20 - 938 916 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE precision_modified=11 0 4500 FALSE 0 2 2 ToW expansion float:intAOEDamagePercent=0.55,int:intWeaponType=9
|
||||
weapon_tow_flamer_03_01 object/weapon/ranged/heavy/som_republic_flamer_generic.iff weapon Heavy Republic Flame Thrower 1 1000 156 312 ranged_weapon DIRECTIONAL_TARGET_WEAPON energy heat 32 25 100 0 20 - 938 936 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE precision_modified=11 0 6000 FALSE 0 3 2 ToW expansion float:intAOEDamagePercent=0.55,int:intWeaponType=9
|
||||
weapon_tow_flamer_04_01 object/weapon/ranged/heavy/som_republic_flamer_generic.iff weapon Heavy Republic Flame Thrower 1 1000 162 323 ranged_weapon DIRECTIONAL_TARGET_WEAPON energy heat 34 25 100 0 20 - 938 970 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE precision_modified=12 0 6500 FALSE 0 4 2 ToW expansion float:intAOEDamagePercent=0.55,int:intWeaponType=9
|
||||
weapon_tow_flamer_05_01 object/weapon/ranged/heavy/som_republic_flamer_generic.iff weapon Heavy Republic Flame Thrower 1 1000 165 329 ranged_weapon DIRECTIONAL_TARGET_WEAPON energy heat 40 25 100 0 20 - 938 988 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE precision_modified=12 0 7000 FALSE 0 5 2 ToW expansion float:intAOEDamagePercent=0.55,int:intWeaponType=9
|
||||
weapon_tow_grenade_fragmentation_04_01 object/weapon/ranged/grenade/grenade_fragmentation_generic.iff weapon Old Republic Fragmentation Grenade 1 1000 721 1442 ranged_weapon THROWN energy none 0 1000 100 0 40 - 108 108 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 100 FALSE 15 4 1 ToW expansion int:reuseTimer=5,string:effect_class=fragmentation
|
||||
weapon_tow_hammer_03_01 object/weapon/melee/2h_sword/2h_sword_maul.iff weapon Hammer of the Miner 1 1000 667 1333 melee_weapon TWO_HANDED_MELEE kinetic none 0 100 100 0 5 - 1000 1000 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 64 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE strength_modified=12 0 6000 FALSE 0 3 2 ToW expansion -
|
||||
weapon_tow_heavy_acid_beam_04_01 object/weapon/ranged/heavy/heavy_acid_beam_static.iff weapon Devastator Acid Launcher 1 1000 683 1366 ranged_weapon GROUND_TARGETTING energy acid 128 100 100 0 64 - 1000 1025 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 6500 FALSE 0 4 3 ToW expansion float:intAOEDamagePercent=0.0,int:intWeaponType=6,string:strWeaponType=acid_beam
|
||||
weapon_tow_heavy_flamer_repub_06_01 object/weapon/ranged/heavy/som_republic_flamer_generic.iff weapon Malevolent Flamethrower 1 1000 175 350 ranged_weapon DIRECTIONAL energy heat 30 25 100 0 20 - 1000 1050 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 10000 FALSE 0 6 1 ToW expansion float:intAOEDamagePercent=0.55,int:intWeaponType=9
|
||||
weapon_tow_heavy_repub_flamethrower_05_01 object/weapon/ranged/heavy/som_republic_flamer_generic.iff weapon Oppressor Flame Thrower 1 1000 175 350 ranged_weapon DIRECTIONAL energy heat 40 25 100 0 20 - 1000 1050 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 7000 FALSE 0 5 1 ToW expansion float:intAOEDamagePercent=0.55,int:intWeaponType=9
|
||||
weapon_tow_heavy_flamer_repub_06_01 object/weapon/ranged/heavy/som_republic_flamer_generic.iff weapon Malevolent Flamethrower 1 1000 175 350 ranged_weapon DIRECTIONAL_TARGET_WEAPON energy heat 30 25 100 0 20 - 1000 1050 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 10000 FALSE 0 6 1 ToW expansion float:intAOEDamagePercent=0.55,int:intWeaponType=9
|
||||
weapon_tow_heavy_repub_flamethrower_05_01 object/weapon/ranged/heavy/som_republic_flamer_generic.iff weapon Oppressor Flame Thrower 1 1000 175 350 ranged_weapon DIRECTIONAL_TARGET_WEAPON energy heat 40 25 100 0 20 - 1000 1050 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 7000 FALSE 0 5 1 ToW expansion float:intAOEDamagePercent=0.55,int:intWeaponType=9
|
||||
weapon_tow_heavy_rocket_launcher_05_01 object/weapon/ranged/heavy/heavy_rocket_launcher_generic.iff weapon AK-Prime Rocket Launcher 1 1000 659 1317 ranged_weapon GROUND_TARGETTING kinetic heat 135 100 100 0 64 - 938 988 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 commando TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 7000 FALSE 0 5 1 ToW expansion -
|
||||
weapon_tow_knuckler_05_01 object/weapon/melee/special/vibroknuckler_static.iff weapon Forward Commander Knuckler 1 1000 659 1317 melee_weapon UNARMED kinetic none 0 100 100 0 5 - 938 988 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 7000 FALSE 0 5 1 ToW expansion -
|
||||
weapon_tow_knuckler_blacksun_06_01 object/weapon/melee/special/blacksun_razor_generic.iff weapon Malevolent Razorknuckler 1 1000 700 1400 melee_weapon UNARMED kinetic none 0 100 100 0 5 - 1000 1050 0 - FALSE - 0 0 - - - 0 - - - - - - - - 0 0 - - - 0 - 88 - TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE - 0 10000 FALSE 0 6 1 ToW expansion -
|
||||
|
||||
@@ -34,15 +34,21 @@ public class CreatureKilledIntent extends Intent {
|
||||
|
||||
public static final String TYPE = "CreatureKilledIntent";
|
||||
|
||||
private final CreatureObject killedCreature;
|
||||
private final CreatureObject killer;
|
||||
private final CreatureObject corpse;
|
||||
|
||||
public CreatureKilledIntent(CreatureObject killedCreature) {
|
||||
public CreatureKilledIntent(CreatureObject killer, CreatureObject corpse) {
|
||||
super(TYPE);
|
||||
this.killedCreature = killedCreature;
|
||||
this.killer = killer;
|
||||
this.corpse = corpse;
|
||||
}
|
||||
|
||||
public CreatureObject getKilledCreature() {
|
||||
return killedCreature;
|
||||
public CreatureObject getKiller() {
|
||||
return killer;
|
||||
}
|
||||
|
||||
|
||||
public CreatureObject getCorpse() {
|
||||
return corpse;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
58
src/intents/combat/DeathblowIntent.java
Normal file
58
src/intents/combat/DeathblowIntent.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* -------------------------------------------------------------------------------- *
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore 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 Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***********************************************************************************/
|
||||
package intents.combat;
|
||||
|
||||
import resources.control.Intent;
|
||||
import resources.objects.creature.CreatureObject;
|
||||
|
||||
public class DeathblowIntent extends Intent {
|
||||
|
||||
public static final String TYPE = "DeathblowIntent";
|
||||
|
||||
private final CreatureObject killer;
|
||||
private final CreatureObject corpse;
|
||||
|
||||
/**
|
||||
* @param killer {@code CreatureObject} that's deathblowing
|
||||
* @param corpse {@code CreatureObject} that's being deathblown
|
||||
*/
|
||||
public DeathblowIntent(CreatureObject killer, CreatureObject corpse) {
|
||||
super(TYPE);
|
||||
this.killer = killer;
|
||||
this.corpse = corpse;
|
||||
}
|
||||
|
||||
public CreatureObject getKiller() {
|
||||
return killer;
|
||||
}
|
||||
|
||||
public CreatureObject getCorpse() {
|
||||
return corpse;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -48,6 +48,7 @@ public class CombatCommand extends Command {
|
||||
private boolean ignoreDistance;
|
||||
private boolean pvpOnly;
|
||||
private int attackRolls;
|
||||
private float percentAddFromWeapon;
|
||||
|
||||
public CombatCommand(String name) {
|
||||
super(name);
|
||||
@@ -146,5 +147,13 @@ public class CombatCommand extends Command {
|
||||
public void setAnimations(WeaponType type, String [] animations) {
|
||||
this.animations.put(type, animations);
|
||||
}
|
||||
|
||||
public float getPercentAddFromWeapon() {
|
||||
return percentAddFromWeapon;
|
||||
}
|
||||
|
||||
public void setPercentAddFromWeapon(float percentAddFromWeapon) {
|
||||
this.percentAddFromWeapon = percentAddFromWeapon;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ClosedByInterruptException;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.SelectableChannel;
|
||||
import java.nio.channels.SelectionKey;
|
||||
@@ -126,6 +127,7 @@ public class TCPServer {
|
||||
|
||||
public boolean close() {
|
||||
listener.stop();
|
||||
callbackExecutor.shutdown();
|
||||
try {
|
||||
if (channel != null)
|
||||
channel.close();
|
||||
@@ -267,6 +269,10 @@ public class TCPServer {
|
||||
callbackExecutor.execute(() -> callback.onIncomingData(s.socket(), smaller.array()));
|
||||
return true;
|
||||
}
|
||||
} catch (ClosedByInterruptException e) {
|
||||
key.cancel();
|
||||
disconnect(s);
|
||||
stop();
|
||||
} catch (IOException e) {
|
||||
if (e.getMessage() != null && e.getMessage().toLowerCase(Locale.US).contains("connection reset"))
|
||||
Log.e("TCPServer", "Connection Reset with %s", s.socket().getRemoteSocketAddress());
|
||||
|
||||
@@ -37,8 +37,8 @@ import resources.player.Player;
|
||||
|
||||
public class WeaponObject extends TangibleObject {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private int minDamage;
|
||||
private int maxDamage;
|
||||
// WEAO03
|
||||
private float attackSpeed = 0.5f;
|
||||
private int accuracy;
|
||||
@@ -118,6 +118,22 @@ public class WeaponObject extends TangibleObject {
|
||||
public void setType(WeaponType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public int getMinDamage() {
|
||||
return minDamage;
|
||||
}
|
||||
|
||||
public void setMinDamage(int minDamage) {
|
||||
this.minDamage = minDamage;
|
||||
}
|
||||
|
||||
public int getMaxDamage() {
|
||||
return maxDamage;
|
||||
}
|
||||
|
||||
public void setMaxDamage(int maxDamage) {
|
||||
this.maxDamage = maxDamage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
@@ -176,7 +192,9 @@ public class WeaponObject extends TangibleObject {
|
||||
@Override
|
||||
public void save(NetBufferStream stream) {
|
||||
super.save(stream);
|
||||
stream.addByte(1);
|
||||
stream.addByte(0);
|
||||
stream.addInt(minDamage);
|
||||
stream.addInt(maxDamage);
|
||||
stream.addAscii(damageType.name());
|
||||
stream.addAscii(elementalType != null ? elementalType.name() : "");
|
||||
stream.addInt(elementalValue);
|
||||
@@ -188,22 +206,21 @@ public class WeaponObject extends TangibleObject {
|
||||
@Override
|
||||
public void read(NetBufferStream stream) {
|
||||
super.read(stream);
|
||||
switch(stream.getByte()) {
|
||||
case 1:
|
||||
damageType = DamageType.valueOf(stream.getAscii());
|
||||
String elementalTypeName = stream.getAscii();
|
||||
|
||||
// A weapon doesn't necessarily have an elemental type
|
||||
if(!elementalTypeName.isEmpty())
|
||||
elementalType = DamageType.valueOf(elementalTypeName);
|
||||
|
||||
elementalValue = stream.getInt();
|
||||
default:
|
||||
attackSpeed = stream.getFloat();
|
||||
maxRange = stream.getFloat();
|
||||
type = WeaponType.valueOf(stream.getAscii());
|
||||
break;
|
||||
stream.getByte();
|
||||
minDamage = stream.getInt();
|
||||
maxDamage = stream.getInt();
|
||||
damageType = DamageType.valueOf(stream.getAscii());
|
||||
String elementalTypeName = stream.getAscii();
|
||||
|
||||
// A weapon doesn't necessarily have an elemental type
|
||||
if (!elementalTypeName.isEmpty()) {
|
||||
elementalType = DamageType.valueOf(elementalTypeName);
|
||||
}
|
||||
|
||||
elementalValue = stream.getInt();
|
||||
attackSpeed = stream.getFloat();
|
||||
maxRange = stream.getFloat();
|
||||
type = WeaponType.valueOf(stream.getAscii());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -59,6 +59,7 @@ import resources.server_info.Log.LogLevel;
|
||||
import services.admin.OnlineInterfaceService;
|
||||
import services.galaxy.GalacticManager;
|
||||
import utilities.CrcDatabaseGenerator;
|
||||
import utilities.ScheduledUtilities;
|
||||
import utilities.ThreadUtilities;
|
||||
|
||||
public class CoreManager extends Manager {
|
||||
@@ -133,6 +134,7 @@ public class CoreManager extends Manager {
|
||||
@Override
|
||||
public boolean terminate() {
|
||||
shutdownService.shutdownNow();
|
||||
ScheduledUtilities.shutdown();
|
||||
return super.terminate();
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,10 @@ import network.packets.swg.zone.object_controller.ShowFlyText.Scale;
|
||||
import network.packets.swg.zone.object_controller.combat.CombatAction;
|
||||
import intents.chat.ChatCommandIntent;
|
||||
import intents.combat.CreatureKilledIntent;
|
||||
import intents.combat.DeathblowIntent;
|
||||
import java.util.Iterator;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Future;
|
||||
import resources.Posture;
|
||||
import resources.PvpFaction;
|
||||
import resources.PvpFlag;
|
||||
@@ -69,17 +72,25 @@ public class CombatManager extends Manager {
|
||||
private final Map<Long, CombatCreature> inCombat;
|
||||
private final Set<CreatureObject> regeneratingHealthCreatures; // Only allowed outside of combat
|
||||
private final Set<CreatureObject> regeneratingActionCreatures; // Always allowed
|
||||
private final Map<CreatureObject, Future<?>> incapacitatedCreatures;
|
||||
private final Random random;
|
||||
private final CorpseService corpseService;
|
||||
private final CombatXpService combatXpService;
|
||||
|
||||
private ScheduledExecutorService executor;
|
||||
|
||||
public CombatManager() {
|
||||
registerForIntent(DeathblowIntent.TYPE);
|
||||
inCombat = new HashMap<>();
|
||||
regeneratingHealthCreatures = new HashSet<>();
|
||||
regeneratingActionCreatures = new HashSet<>();
|
||||
incapacitatedCreatures = new HashMap<>();
|
||||
random = new Random();
|
||||
|
||||
corpseService = new CorpseService();
|
||||
combatXpService = new CombatXpService();
|
||||
addChildService(corpseService);
|
||||
addChildService(combatXpService);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,8 +122,10 @@ public class CombatManager extends Manager {
|
||||
|
||||
@Override
|
||||
public void onIntentReceived(Intent i) {
|
||||
if (i instanceof ChatCommandIntent)
|
||||
processChatCommand((ChatCommandIntent) i);
|
||||
switch(i.getType()) {
|
||||
case ChatCommandIntent.TYPE: processChatCommand((ChatCommandIntent) i); break;
|
||||
case DeathblowIntent.TYPE: procesDeathblow((DeathblowIntent) i); break;
|
||||
}
|
||||
}
|
||||
|
||||
private void periodicChecks() {
|
||||
@@ -254,7 +267,9 @@ public class CombatManager extends Manager {
|
||||
enterCombat(target);
|
||||
target.addDefender(source);
|
||||
source.addDefender(target);
|
||||
// Note: This will not kill anyone
|
||||
|
||||
addWeaponDamage(source, command, info);
|
||||
|
||||
if (target.getHealth() <= info.getDamage())
|
||||
doCreatureDeath(target, source);
|
||||
else
|
||||
@@ -320,7 +335,7 @@ public class CombatManager extends Manager {
|
||||
incapacitatePlayer(killedCreature);
|
||||
} else {
|
||||
// This is just a plain ol' NPC. Die!
|
||||
killCreature(killedCreature);
|
||||
killCreature(killer, killedCreature);
|
||||
}
|
||||
|
||||
exitCombat(killedCreature);
|
||||
@@ -334,7 +349,16 @@ public class CombatManager extends Manager {
|
||||
Log.i(this, "%s was incapacitated", incapacitatedPlayer);
|
||||
|
||||
// Once the incapacitation counter expires, revive them.
|
||||
executor.schedule(() -> reviveCreature(incapacitatedPlayer), incapacitationCounter, TimeUnit.SECONDS);
|
||||
synchronized(incapacitatedCreatures) {
|
||||
incapacitatedCreatures.put(incapacitatedPlayer, executor.schedule(() -> expireIncapacitation(incapacitatedPlayer), incapacitationCounter, TimeUnit.SECONDS));
|
||||
}
|
||||
}
|
||||
|
||||
private void expireIncapacitation(CreatureObject incapacitatedPlayer) {
|
||||
synchronized(incapacitatedCreatures) {
|
||||
incapacitatedCreatures.remove(incapacitatedPlayer);
|
||||
reviveCreature(incapacitatedPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
private void reviveCreature(CreatureObject revivedCreature) {
|
||||
@@ -360,10 +384,45 @@ public class CombatManager extends Manager {
|
||||
Log.i(this, "% was revived", revivedCreature);
|
||||
}
|
||||
|
||||
private void killCreature(CreatureObject killedCreature) {
|
||||
killedCreature.setPosture(Posture.DEAD);
|
||||
Log.i(this, "%s was killed", killedCreature);
|
||||
new CreatureKilledIntent(killedCreature).broadcast();
|
||||
private void killCreature(CreatureObject killer, CreatureObject corpse) {
|
||||
corpse.setPosture(Posture.DEAD);
|
||||
Log.i(this, "%s was killed", corpse);
|
||||
new CreatureKilledIntent(killer, corpse).broadcast();
|
||||
}
|
||||
|
||||
private void procesDeathblow(DeathblowIntent i) {
|
||||
CreatureObject killer = i.getKiller();
|
||||
CreatureObject corpse = i.getCorpse();
|
||||
|
||||
// Only deathblowing players is allowed!
|
||||
if (!corpse.isPlayer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// They must be enemies
|
||||
if (!corpse.isEnemy(killer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The target of the deathblow must be incapacitated!
|
||||
if (corpse.getPosture() != Posture.INCAPACITATED) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If they're deathblown while incapacitated, their incapacitation expiration timer should cancel
|
||||
synchronized (incapacitatedCreatures) {
|
||||
Future<?> incapacitationTimer = incapacitatedCreatures.remove(corpse);
|
||||
|
||||
if (incapacitationTimer != null) {
|
||||
if (incapacitationTimer.cancel(false)) { // If the task is running, let them get back up
|
||||
killCreature(killer, corpse);
|
||||
Log.i(this, "%s was deathblown by %s", corpse, killer);
|
||||
}
|
||||
} else {
|
||||
// Can't happen with the current code, but in case it's ever refactored...
|
||||
Log.e(this, "Incapacitation timer for player %s being deathblown unexpectedly didn't exist!", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handleStatus(CreatureObject source, CombatStatus status) {
|
||||
@@ -396,6 +455,16 @@ public class CombatManager extends Manager {
|
||||
} else if ((tangibleTarget.getPvpFlags() & PvpFlag.ATTACKABLE.getBitmask()) == 0)
|
||||
return CombatStatus.INVALID_TARGET;
|
||||
|
||||
if(target instanceof CreatureObject) {
|
||||
CreatureObject creature = (CreatureObject) target;
|
||||
|
||||
switch(creature.getPosture()) {
|
||||
case DEAD:
|
||||
case INCAPACITATED:
|
||||
return CombatStatus.INVALID_TARGET;
|
||||
}
|
||||
}
|
||||
|
||||
CombatStatus status;
|
||||
switch (c.getAttackType()) {
|
||||
case AREA:
|
||||
@@ -432,6 +501,17 @@ public class CombatManager extends Manager {
|
||||
return CombatStatus.SUCCESS;
|
||||
}
|
||||
|
||||
private void addWeaponDamage(CreatureObject source, CombatCommand command, AttackInfoLight info) {
|
||||
int abilityDamage = info.getDamage();
|
||||
WeaponObject weapon = source.getEquippedWeapon();
|
||||
int minDamage = weapon.getMinDamage();
|
||||
int weaponDamage = random.nextInt((weapon.getMaxDamage() - minDamage) + 1) + minDamage;
|
||||
|
||||
weaponDamage *= command.getPercentAddFromWeapon();
|
||||
|
||||
info.setDamage(abilityDamage + weaponDamage);
|
||||
}
|
||||
|
||||
private void showFlyText(TangibleObject obj, String text, Scale scale, Color c, ShowFlyText.Flag ... flags) {
|
||||
obj.sendSelf(new ShowFlyText(obj.getObjectId(), text, scale, new RGB(c), flags));
|
||||
}
|
||||
|
||||
230
src/services/combat/CombatXpService.java
Normal file
230
src/services/combat/CombatXpService.java
Normal file
@@ -0,0 +1,230 @@
|
||||
/************************************************************************************
|
||||
* Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* -------------------------------------------------------------------------------- *
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore 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 Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***********************************************************************************/
|
||||
package services.combat;
|
||||
|
||||
import intents.combat.CreatureKilledIntent;
|
||||
import intents.experience.ExperienceIntent;
|
||||
import intents.object.DestroyObjectIntent;
|
||||
import intents.object.ObjectCreatedIntent;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import resources.control.Intent;
|
||||
import resources.control.Service;
|
||||
import resources.objects.SWGObject;
|
||||
import resources.objects.creature.CreatureDifficulty;
|
||||
import resources.objects.creature.CreatureObject;
|
||||
import resources.objects.group.GroupObject;
|
||||
import resources.server_info.Log;
|
||||
import resources.server_info.RelationalDatabase;
|
||||
import resources.server_info.RelationalServerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author mads
|
||||
*/
|
||||
public class CombatXpService extends Service {
|
||||
|
||||
private final Map<Short, XpData> xpData;
|
||||
private final Map<Long, GroupObject> groupObjects;
|
||||
|
||||
public CombatXpService() {
|
||||
xpData = new HashMap<>();
|
||||
groupObjects = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onIntentReceived(Intent i) {
|
||||
switch(i.getType()) {
|
||||
case ObjectCreatedIntent.TYPE: handleObjectCreatedIntent((ObjectCreatedIntent) i); break;
|
||||
case DestroyObjectIntent.TYPE: handleDestroyObjectIntent((DestroyObjectIntent) i); break;
|
||||
case CreatureKilledIntent.TYPE: handleCreatureKilledIntent((CreatureKilledIntent) i); break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean initialize() {
|
||||
loadXpData();
|
||||
|
||||
return super.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
// The objects we care about are only created/destroyed at this point anyways.
|
||||
registerForIntent(ObjectCreatedIntent.TYPE);
|
||||
registerForIntent(DestroyObjectIntent.TYPE);
|
||||
registerForIntent(CreatureKilledIntent.TYPE);
|
||||
|
||||
return super.start();
|
||||
}
|
||||
|
||||
private void loadXpData() {
|
||||
long start = System.nanoTime();
|
||||
|
||||
Log.i(this, "Loading combat XP rates...");
|
||||
try (RelationalDatabase npcStats = RelationalServerFactory.getServerData("creatures/npc_stats.db", "npc_stats")) {
|
||||
try (ResultSet set = npcStats.executeQuery("SELECT * FROM npc_stats")) {
|
||||
while (set.next()) {
|
||||
xpData.put(set.getShort("Level"), new XpData(set.getInt("XP"), set.getInt("Elite_XP"), set.getInt("Boss_XP")));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Log.e(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
double time = (System.nanoTime()-start)/1E6;
|
||||
Log.i(this, "Finished loading %d combat XP rates. Time: %fms", xpData.size(), time);
|
||||
}
|
||||
|
||||
private void handleObjectCreatedIntent(ObjectCreatedIntent i) {
|
||||
SWGObject object = i.getObject();
|
||||
|
||||
if(object instanceof GroupObject) {
|
||||
synchronized (groupObjects) {
|
||||
groupObjects.put(object.getObjectId(), (GroupObject) object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDestroyObjectIntent(DestroyObjectIntent i) {
|
||||
SWGObject object = i.getObject();
|
||||
|
||||
synchronized (groupObjects) {
|
||||
if(object instanceof GroupObject && groupObjects.remove(object.getObjectId()) == null) {
|
||||
Log.w(this, "%s was expected to be in the GroupObject mapping but wasn't", object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleCreatureKilledIntent(CreatureKilledIntent i) {
|
||||
CreatureObject corpse = i.getCorpse();
|
||||
|
||||
// You don't gain XP by PvP'ing
|
||||
if(corpse.isPlayer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CreatureObject killer = i.getKiller();
|
||||
GroupObject group = groupObjects.get(killer.getGroupId());
|
||||
|
||||
// Ungrouped entertainer
|
||||
if (group == null && isEntertainer(killer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
short killerLevel = group != null ? group.getLevel() : killer.getLevel();
|
||||
int experienceGained = calculateXpGain(killer, corpse, killerLevel);
|
||||
|
||||
if (experienceGained <= 0) {
|
||||
Log.w(this, "%s received no XP: XP for creature difficulty %s at level %d was %d", killer, corpse.getDifficulty(), killerLevel, experienceGained);
|
||||
return;
|
||||
}
|
||||
|
||||
if (group == null) {
|
||||
new ExperienceIntent(killer, "combat", experienceGained).broadcast();
|
||||
} else {
|
||||
group.getGroupMemberObjects().stream()
|
||||
.filter(groupMember -> !isEntertainer(groupMember) && isMemberNearby(corpse, groupMember))
|
||||
.forEach(eligibleMember -> new ExperienceIntent(eligibleMember, "combat", experienceGained).broadcast());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEntertainer(CreatureObject creature) {
|
||||
return creature.hasSkill("class_entertainer_phase1_novice");
|
||||
}
|
||||
|
||||
private int calculateXpGain(CreatureObject killer, CreatureObject corpse, short killerLevel) {
|
||||
int experienceGained;
|
||||
short corpseLevel = corpse.getLevel();
|
||||
// If the difference between killer and corpse is 10 or above, they only gain 1 xp
|
||||
if (killerLevel - corpseLevel >= 10) {
|
||||
experienceGained = 1;
|
||||
} else {
|
||||
XpData xpForLevel = this.xpData.get(corpseLevel);
|
||||
|
||||
if (xpForLevel == null) {
|
||||
Log.e(this, "%s received no XP: No XP data was found for level %d!", killer, corpseLevel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatureDifficulty creatureDifficulty = corpse.getDifficulty();
|
||||
|
||||
switch (creatureDifficulty) {
|
||||
case BOSS:
|
||||
experienceGained = xpForLevel.getBossXp();
|
||||
break;
|
||||
case ELITE:
|
||||
experienceGained = xpForLevel.getEliteXp();
|
||||
break;
|
||||
case NORMAL:
|
||||
experienceGained = xpForLevel.getXp();
|
||||
break;
|
||||
default:
|
||||
Log.e(this, "%s received no XP: Unsupported creature difficulty %s of corpse %s", killer, creatureDifficulty, corpse);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return experienceGained;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if {@code groupMember} is an observer of {@code corpse}
|
||||
*/
|
||||
private boolean isMemberNearby(CreatureObject corpse, CreatureObject groupMember) {
|
||||
return corpse.getObservers().contains(groupMember);
|
||||
}
|
||||
|
||||
private static class XpData {
|
||||
private final int xp;
|
||||
private final int eliteXp;
|
||||
private final int bossXp;
|
||||
|
||||
public XpData(int xp, int eliteXp, int bossXp) {
|
||||
this.xp = xp;
|
||||
this.eliteXp = eliteXp;
|
||||
this.bossXp = bossXp;
|
||||
}
|
||||
|
||||
public int getXp() {
|
||||
return xp;
|
||||
}
|
||||
|
||||
public int getEliteXp() {
|
||||
return eliteXp;
|
||||
}
|
||||
|
||||
public int getBossXp() {
|
||||
return bossXp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -67,16 +67,16 @@ public final class CorpseService extends Service {
|
||||
}
|
||||
|
||||
private void handleCreatureKilledIntent(CreatureKilledIntent i) {
|
||||
CreatureObject killedCreature = i.getKilledCreature();
|
||||
CreatureObject corpse = i.getCorpse();
|
||||
|
||||
if(killedCreature.isPlayer()) {
|
||||
if(corpse.isPlayer()) {
|
||||
// TODO show cloning system message
|
||||
// TODO show cloning SUI window, with all possible facilities to clone at
|
||||
// TODO after 30 minutes, close the SUI window and force them to clone at the nearest cloning facility
|
||||
// TODO if the SUI window is closed by the player, make sure it reappears
|
||||
} else {
|
||||
// This is a NPC - schedule corpse for deletion
|
||||
executor.schedule(() -> deleteCorpse(killedCreature), 120, TimeUnit.SECONDS);
|
||||
executor.schedule(() -> deleteCorpse(corpse), 120, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -423,7 +423,8 @@ public class CommandService extends Service {
|
||||
cc.setAttackType(AttackType.SINGLE_TARGET);
|
||||
cc.setForceCombat(set.getBoolean("force_combat"));
|
||||
cc.setValidTarget(ValidTarget.STANDARD);
|
||||
cc.setDefaultAnimation(set.getString("animations").split(","));
|
||||
cc.setDefaultAnimation(getAnimationList(set.getString("animations")));
|
||||
cc.setPercentAddFromWeapon(set.getFloat("percentAddFromWeapon"));
|
||||
|
||||
addCommand(cc);
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ import resources.objects.SWGObject;
|
||||
import resources.objects.creature.CreatureObject;
|
||||
import resources.objects.tangible.TangibleObject;
|
||||
import resources.player.Player;
|
||||
import utilities.ThreadUtilities;
|
||||
|
||||
public final class FactionService extends Service {
|
||||
|
||||
@@ -57,7 +58,7 @@ public final class FactionService extends Service {
|
||||
|
||||
@Override
|
||||
public boolean initialize() {
|
||||
executor = Executors.newSingleThreadScheduledExecutor();
|
||||
executor = Executors.newSingleThreadScheduledExecutor(ThreadUtilities.newThreadFactory("faction-service"));
|
||||
return super.initialize();
|
||||
}
|
||||
|
||||
|
||||
@@ -461,6 +461,7 @@ public final class StaticItemService extends Service {
|
||||
private String elementalTypeString;
|
||||
private short elementalDamage;
|
||||
private String procEffect;
|
||||
private String dps;
|
||||
// special_attack_cost: Pre-NGE artifact? (SAC)
|
||||
|
||||
public WeaponAttributes(String itemName, String iffTemplate) {
|
||||
@@ -499,10 +500,11 @@ public final class StaticItemService extends Service {
|
||||
case "ONE_HANDED_SABER": category = WeaponType.ONE_HANDED_SABER; break;
|
||||
case "TWO_HANDED_SABER": category = WeaponType.TWO_HANDED_SABER; break;
|
||||
case "POLEARM_SABER": category = WeaponType.POLEARM_SABER; break;
|
||||
case "DIRECTIONAL_TARGET_WEAPON": category = WeaponType.DIRECTIONAL_TARGET_WEAPON; break; // Free targeting
|
||||
case "GROUND_TARGETTING": category = WeaponType.HEAVY_WEAPON; break;
|
||||
case "DIRECTIONAL_TARGET_WEAPON": category = WeaponType.DIRECTIONAL_TARGET_WEAPON; break;
|
||||
case "LIGHT_RIFLE": category = WeaponType.LIGHT_RIFLE; break;
|
||||
default:
|
||||
// TODO log the fact that the weapon type isn't recognised.
|
||||
Log.e(this, "Unrecognised weapon type %s at row %d", weaponType, resultSet.getRow());
|
||||
// We return false here. That way, we don't store the
|
||||
// itemName in the Map and the item can never be spawned.
|
||||
return false;
|
||||
@@ -535,7 +537,7 @@ public final class StaticItemService extends Service {
|
||||
procEffect = "@ui_buff:" + procEffectString;
|
||||
}
|
||||
|
||||
// TODO calculate DPS
|
||||
dps = resultSet.getString("actual_dps");
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -552,6 +554,8 @@ public final class StaticItemService extends Service {
|
||||
object.addAttribute("cat_wpn_damage.wpn_elemental_value", String.valueOf(elementalDamage));
|
||||
}
|
||||
|
||||
object.addAttribute("cat_wpn_damage.weapon_dps", dps);
|
||||
|
||||
if(procEffect != null) // Not all weapons have a proc effect
|
||||
object.addAttribute("proc_name", procEffect);
|
||||
// TODO set DPS
|
||||
@@ -559,13 +563,15 @@ public final class StaticItemService extends Service {
|
||||
object.addAttribute("cat_wpn_other.wpn_range", rangeString);
|
||||
// Ziggy: Special Action Cost would go under cat_wpn_other as well, but it's a pre-NGE artifact.
|
||||
|
||||
// TODO set all WeaponObject properties
|
||||
WeaponObject weapon = (WeaponObject) object;
|
||||
weapon.setType(category);
|
||||
weapon.setAttackSpeed(attackSpeed);
|
||||
weapon.setMinRange(minRange);
|
||||
weapon.setMaxRange(maxRange);
|
||||
weapon.setDamageType(damageTypeEnum);
|
||||
weapon.setElementalType(elementalTypeEnum);
|
||||
weapon.setMinDamage(minDamage);
|
||||
weapon.setMaxDamage(maxDamage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -413,6 +413,8 @@ public class CharacterCreationService extends Service {
|
||||
defWeapon.setMaxRange(5);
|
||||
defWeapon.setType(WeaponType.UNARMED);
|
||||
defWeapon.setAttackSpeed(1);
|
||||
defWeapon.setMinDamage(50);
|
||||
defWeapon.setMaxDamage(100);
|
||||
creatureObj.setEquippedWeapon(defWeapon);
|
||||
defWeapon.moveToContainer(creatureObj); // Occupies the default_weapon slot
|
||||
createInventoryObject(objManager, creatureObj, "object/tangible/inventory/shared_character_inventory.iff");
|
||||
|
||||
@@ -46,9 +46,6 @@ public class ScheduledUtilities {
|
||||
if (executor == null) {
|
||||
int processors = Runtime.getRuntime().availableProcessors();
|
||||
executor = Executors.newScheduledThreadPool(processors, ThreadUtilities.newThreadFactory("scheduled-utilities-%d"));
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
executor.shutdown();
|
||||
}));
|
||||
}
|
||||
return executor;
|
||||
}
|
||||
@@ -66,4 +63,12 @@ public class ScheduledUtilities {
|
||||
return getScheduler().schedule(r, delay, unit);
|
||||
}
|
||||
|
||||
public static void shutdown() {
|
||||
synchronized (mutex) {
|
||||
if (executor != null) {
|
||||
executor.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user