mirror of
https://github.com/ProjectSWGCore/NGECore2.git
synced 2026-10-13 03:13:26 -04:00
Added basis for server-side cooldown checks, added warmup checks, closed #273
Note that cooldown check is currently used only for the holoemote command. To add a cooldown to any command, all you have to do is CreatureObject.addCooldown(name). In this commit I also moved some cooldown variables from CombatCommand to BaseSWGCommand since many non-combat commands had cooldowns (Wookie Roar, Holo-Emotes). I also put in a warmup cooldown (time before command is called) for non-combat commands.
This commit is contained in:
@@ -14,6 +14,10 @@ def run(core, actor, target, commandString):
|
||||
|
||||
installedEmote = ''
|
||||
|
||||
if actor.hasCooldown('holoEmote'):
|
||||
actor.sendSystemMessage('Your Holo-Emote generator is in use or recharging.', 0) # Not sure if this is correct.
|
||||
return
|
||||
|
||||
if player.getHoloEmote() is not None:
|
||||
installedEmote = player.getHoloEmote().replace('holoemote_','')
|
||||
|
||||
@@ -43,7 +47,9 @@ def run(core, actor, target, commandString):
|
||||
effectObj = 'clienteffect/holoemote_' + commandString + '.cef'
|
||||
actor.playEffectObject(effectObj, 'head')
|
||||
player.setHoloEmoteUses(player.getHoloEmoteUses() - 1)
|
||||
# TODO: Cooldowns for the holo-emote's
|
||||
|
||||
actor.addCooldown('holoEmote', long(30 * 1000))
|
||||
|
||||
return
|
||||
|
||||
def holoPrompt(player, emote):
|
||||
|
||||
@@ -98,4 +98,9 @@ def run(core, actor, target, commandString):
|
||||
actor.setInStealth(True)
|
||||
actor.setRadarVisible(False)
|
||||
actor.sendSystemMessage('You are now hidden from players. "Stealth Effect" is not implemented, however players still won\'t be able to see you. Type /setgodmode stealth again to be visible.', 0)
|
||||
|
||||
elif command == 'holoEmote' and arg1:
|
||||
playerObject.setHoloEmote('holoemote_' + arg1)
|
||||
playerObject.setHoloEmoteUses(20)
|
||||
actor.sendSystemMessage('Holo-Emote Generator set to ' + 'holoemote_' + arg1, 0)
|
||||
return
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class Cooldown {
|
||||
private long startTimestamp;
|
||||
private long endTimestamp;
|
||||
|
||||
private ScheduledFuture<?> removalTask;
|
||||
|
||||
public Cooldown(long end) {
|
||||
startTimestamp = System.currentTimeMillis();
|
||||
endTimestamp = startTimestamp + end;
|
||||
}
|
||||
|
||||
public long getStartTimestamp() {
|
||||
return startTimestamp;
|
||||
}
|
||||
|
||||
public void setStartTimestamp(long startTimestamp) {
|
||||
this.startTimestamp = startTimestamp;
|
||||
}
|
||||
|
||||
public long getEndTimestamp() {
|
||||
return endTimestamp;
|
||||
}
|
||||
|
||||
public void setEndTimestamp(long endTimestamp) {
|
||||
this.endTimestamp = endTimestamp;
|
||||
}
|
||||
|
||||
public ScheduledFuture<?> getRemovalTask() {
|
||||
return removalTask;
|
||||
}
|
||||
|
||||
public void setRemovalTask(ScheduledFuture<?> removalTask) {
|
||||
this.removalTask = removalTask;
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,10 @@ import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.mina.core.buffer.IoBuffer;
|
||||
|
||||
@@ -46,6 +49,7 @@ import com.sleepycat.persist.model.NotPersistent;
|
||||
|
||||
import main.NGECore;
|
||||
import engine.clients.Client;
|
||||
import resources.common.Cooldown;
|
||||
import resources.objects.Buff;
|
||||
import resources.objects.DamageOverTime;
|
||||
import resources.objects.SWGList;
|
||||
@@ -177,6 +181,8 @@ public class CreatureObject extends TangibleObject implements IPersistent {
|
||||
private int coverCharge;
|
||||
@NotPersistent
|
||||
private TangibleObject conversingNpc;
|
||||
@NotPersistent
|
||||
private ConcurrentHashMap<String, Cooldown> cooldowns = new ConcurrentHashMap<String, Cooldown>();
|
||||
|
||||
public CreatureObject(long objectID, Planet planet, Point3D position, Quaternion orientation, String Template) {
|
||||
super(objectID, planet, Template, position, orientation);
|
||||
@@ -1722,4 +1728,43 @@ public class CreatureObject extends TangibleObject implements IPersistent {
|
||||
}
|
||||
}
|
||||
|
||||
public void addCooldown(String ability, long duration) {
|
||||
if (cooldowns.containsKey(ability))
|
||||
cooldowns.remove(ability);
|
||||
|
||||
Cooldown cd = new Cooldown(duration);
|
||||
cd.setRemovalTask(Executors.newScheduledThreadPool(1).schedule(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
removeCooldown(ability);
|
||||
}
|
||||
|
||||
}, duration, TimeUnit.MILLISECONDS));
|
||||
cooldowns.put(ability, cd);
|
||||
}
|
||||
|
||||
public boolean hasCooldown(String ability) {
|
||||
if (cooldowns.containsKey(ability))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean removeCooldown(String ability) {
|
||||
if (cooldowns.containsKey(ability)) {
|
||||
cooldowns.remove(ability);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Cooldown getCooldown(String ability) {
|
||||
if (cooldowns.containsKey(ability)) {
|
||||
return cooldowns.get(ability);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ public class BuffService implements INetworkDispatch {
|
||||
if (buffer == null)
|
||||
removeBuffFromCreature(target, buff);
|
||||
|
||||
if (target.getPosition().getDistance2D(buffer.getWorldPosition()) > 80) {
|
||||
if (target.getWorldPosition().getDistance2D(buffer.getWorldPosition()) > 80) {
|
||||
removeBuffFromCreature(target, buff);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
******************************************************************************/
|
||||
package services.command;
|
||||
|
||||
import engine.clientdata.ClientFileManager;
|
||||
import engine.clientdata.visitors.DatatableVisitor;
|
||||
import engine.resources.common.CRC;
|
||||
|
||||
public class BaseSWGCommand implements Cloneable {
|
||||
@@ -31,10 +33,32 @@ public class BaseSWGCommand implements Cloneable {
|
||||
private int maxRangeToTarget;
|
||||
private int commandCRC;
|
||||
private boolean isGmCommand = false;
|
||||
private String requiredAbility;
|
||||
private String cooldownGroup;
|
||||
private float cooldown;
|
||||
private float executeTime;
|
||||
private float warmupTime;
|
||||
|
||||
public BaseSWGCommand(String commandName) {
|
||||
setCommandName(commandName);
|
||||
setCommandCRC(CRC.StringtoCRC(commandName));
|
||||
|
||||
try {
|
||||
DatatableVisitor visitor2 = ClientFileManager.loadFile("datatables/command/command_table.iff", DatatableVisitor.class);
|
||||
for (int i = 0; i < visitor2.getRowCount(); i++) {
|
||||
if (visitor2.getObject(i, 0) != null) {
|
||||
if (((String) visitor2.getObject(i, 0)).equalsIgnoreCase(commandName)) {
|
||||
requiredAbility = (String) visitor2.getObject(i, 7);
|
||||
cooldownGroup = (String) visitor2.getObject(i, 85);
|
||||
warmupTime = (Float) visitor2.getObject(i, 86);
|
||||
executeTime = (Float) visitor2.getObject(i, 87);
|
||||
cooldown = (Float) visitor2.getObject(i, 88);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public String getCommandName() {
|
||||
@@ -89,4 +113,44 @@ public class BaseSWGCommand implements Cloneable {
|
||||
this.isGmCommand = isGmCommand;
|
||||
}
|
||||
|
||||
public String getRequiredAbility() {
|
||||
return requiredAbility;
|
||||
}
|
||||
|
||||
public void setRequiredAbility(String requiredAbility) {
|
||||
this.requiredAbility = requiredAbility;
|
||||
}
|
||||
|
||||
public String getCooldownGroup() {
|
||||
return cooldownGroup;
|
||||
}
|
||||
|
||||
public void setCooldownGroup(String cooldownGroup) {
|
||||
this.cooldownGroup = cooldownGroup;
|
||||
}
|
||||
|
||||
public float getCooldown() {
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
public void setCooldown(float cooldown) {
|
||||
this.cooldown = cooldown;
|
||||
}
|
||||
|
||||
public float getExecuteTime() {
|
||||
return executeTime;
|
||||
}
|
||||
|
||||
public void setExecuteTime(float executeTime) {
|
||||
this.executeTime = executeTime;
|
||||
}
|
||||
|
||||
public float getWarmupTime() {
|
||||
return warmupTime;
|
||||
}
|
||||
|
||||
public void setWarmupTime(float warmupTime) {
|
||||
this.warmupTime = warmupTime;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -67,16 +67,16 @@ public class CombatCommand extends BaseSWGCommand {
|
||||
private int damageType, elementalType, elementalValue;
|
||||
private String performanceSpam;
|
||||
private byte hitSpam;
|
||||
private float cooldown;
|
||||
//private float cooldown;
|
||||
private String delayAttackEggTemplate;
|
||||
private String delayAttackParticle;
|
||||
private float initialAttackDelay;
|
||||
private float delayAttackInterval;
|
||||
private int delayAttackLoops;
|
||||
private int delayAttackEggPosition;
|
||||
private String cooldownGroup;
|
||||
private float executeTime;
|
||||
private float warmupTime;
|
||||
//private String cooldownGroup;
|
||||
//private float executeTime;
|
||||
//private float warmupTime;
|
||||
private float vigorCost; // for commando kill meter and bm specials
|
||||
private float criticalChance;
|
||||
private int attack_rolls;
|
||||
@@ -162,22 +162,6 @@ public class CombatCommand extends BaseSWGCommand {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
DatatableVisitor visitor2 = ClientFileManager.loadFile("datatables/command/command_table.iff", DatatableVisitor.class);
|
||||
|
||||
for(int i = 0; i < visitor2.getRowCount(); i++) {
|
||||
if(visitor2.getObject(i, 0) != null) {
|
||||
if(((String) visitor2.getObject(i, 0)).equalsIgnoreCase(commandName)) {
|
||||
|
||||
cooldownGroup = (String) visitor2.getObject(i, 85);
|
||||
warmupTime = (Float) visitor2.getObject(i, 86);
|
||||
executeTime = (Float) visitor2.getObject(i, 87);
|
||||
cooldown = (Float) visitor2.getObject(i, 88);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -624,14 +608,6 @@ public class CombatCommand extends BaseSWGCommand {
|
||||
|
||||
}
|
||||
|
||||
public float getCooldown() {
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
public void setCooldown(float cooldown) {
|
||||
this.cooldown = cooldown;
|
||||
}
|
||||
|
||||
public String getDelayAttackEggTemplate() {
|
||||
return delayAttackEggTemplate;
|
||||
}
|
||||
@@ -680,30 +656,6 @@ public class CombatCommand extends BaseSWGCommand {
|
||||
this.delayAttackLoops = delayAttackLoops;
|
||||
}
|
||||
|
||||
public String getCooldownGroup() {
|
||||
return cooldownGroup;
|
||||
}
|
||||
|
||||
public void setCooldownGroup(String cooldownGroup) {
|
||||
this.cooldownGroup = cooldownGroup;
|
||||
}
|
||||
|
||||
public float getExecuteTime() {
|
||||
return executeTime;
|
||||
}
|
||||
|
||||
public void setExecuteTime(float executeTime) {
|
||||
this.executeTime = executeTime;
|
||||
}
|
||||
|
||||
public float getWarmupTime() {
|
||||
return warmupTime;
|
||||
}
|
||||
|
||||
public void setWarmupTime(float warmupTime) {
|
||||
this.warmupTime = warmupTime;
|
||||
}
|
||||
|
||||
public float getVigorCost() {
|
||||
return vigorCost;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,9 @@ import java.nio.ByteOrder;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import main.NGECore;
|
||||
|
||||
@@ -52,6 +55,7 @@ public class CommandService implements INetworkDispatch {
|
||||
private Vector<BaseSWGCommand> commandLookup = new Vector<BaseSWGCommand>();
|
||||
private ConcurrentHashMap<String,BaseSWGCommand> aliases = new ConcurrentHashMap<String,BaseSWGCommand>();
|
||||
private ConcurrentHashMap<Integer,BaseSWGCommand> aliasesByCRC = new ConcurrentHashMap<Integer,BaseSWGCommand>();
|
||||
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
||||
private NGECore core;
|
||||
|
||||
public CommandService(NGECore core) {
|
||||
@@ -98,16 +102,30 @@ public class CommandService implements INetworkDispatch {
|
||||
|
||||
CreatureObject actor = (CreatureObject) client.getParent();
|
||||
|
||||
SWGObject target = core.objectService.getObject(commandEnqueue.getTargetID());
|
||||
|
||||
if(command instanceof CombatCommand) {
|
||||
CombatCommand command2 = (CombatCommand) command.clone();
|
||||
processCombatCommand(actor, target, command2, commandEnqueue.getActionCounter(), commandEnqueue.getCommandArguments());
|
||||
if (actor.hasCooldown(command.getCommandName()))
|
||||
return;
|
||||
}
|
||||
|
||||
core.scriptService.callScript("scripts/commands/", command.getCommandName(), "run", core, actor, target, commandEnqueue.getCommandArguments());
|
||||
|
||||
SWGObject target = core.objectService.getObject(commandEnqueue.getTargetID());
|
||||
|
||||
// May want to have a warmup def to be called at some point in the future.
|
||||
if (command.getWarmupTime() != 0 && !(command instanceof CombatCommand)) {
|
||||
scheduler.schedule(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
core.scriptService.callScript("scripts/commands/", command.getCommandName(), "run", core, actor, target, commandEnqueue.getCommandArguments());
|
||||
}
|
||||
}, (long) command.getWarmupTime(), TimeUnit.SECONDS);
|
||||
} else {
|
||||
|
||||
if(command instanceof CombatCommand) {
|
||||
CombatCommand command2 = (CombatCommand) command.clone();
|
||||
processCombatCommand(actor, target, command2, commandEnqueue.getActionCounter(), commandEnqueue.getCommandArguments());
|
||||
return;
|
||||
}
|
||||
|
||||
core.scriptService.callScript("scripts/commands/", command.getCommandName(), "run", core, actor, target, commandEnqueue.getCommandArguments());
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user