From 3cf0f610e9930bcc77bd89d74ec67770a0710c47 Mon Sep 17 00:00:00 2001 From: CharonInferar Date: Thu, 10 Jul 2014 22:36:58 +0200 Subject: [PATCH] Fixed several AI bugs, listed in description Fixed #0000061 : Houses can now be destroyed, even when not redeeding - Added AI action regeneration when in combat - Fixed NPC self-buffing null pointer exception --- .../player_house_generic_small_style_01.py | 1 + .../objects/building/BuildingObject.java | 9 ++ src/services/ai/AIActor.java | 6 ++ src/services/combat/CombatService.java | 23 ++++- src/services/housing/HouseTemplate.java | 9 ++ src/services/housing/HousingService.java | 99 +++++++++++++------ 6 files changed, 112 insertions(+), 35 deletions(-) diff --git a/scripts/houses/player_house_generic_small_style_01.py b/scripts/houses/player_house_generic_small_style_01.py index 3c225c31..fe35b693 100644 --- a/scripts/houses/player_house_generic_small_style_01.py +++ b/scripts/houses/player_house_generic_small_style_01.py @@ -15,6 +15,7 @@ def setup(housingTemplates): houseTemplate.addPlaceablePlanet("lok") houseTemplate.setDefaultItemLimit(200) houseTemplate.setBaseMaintenanceRate(8) + houseTemplate.setDestructionFee(800) housingTemplates.put(houseTemplate.getDeedTemplate(), houseTemplate) return \ No newline at end of file diff --git a/src/resources/objects/building/BuildingObject.java b/src/resources/objects/building/BuildingObject.java index 9ee735d1..11c11083 100644 --- a/src/resources/objects/building/BuildingObject.java +++ b/src/resources/objects/building/BuildingObject.java @@ -56,6 +56,7 @@ public class BuildingObject extends TangibleObject implements IPersistent, Seria private Vector entryList = new Vector(); private Vector banList = new Vector(); private Vector adminList = new Vector(); + private int destructionFee = 0; public static final byte PRIVATE = (byte) 0; public static final byte PUBLIC = (byte) 1; @@ -427,5 +428,13 @@ public class BuildingObject extends TangibleObject implements IPersistent, Seria return adminList.contains(creature.getObjectID()); } + public int getDestructionFee() { + return destructionFee; + } + + public void setDestructionFee(int destructionFee) { + this.destructionFee = destructionFee; + } + } diff --git a/src/services/ai/AIActor.java b/src/services/ai/AIActor.java index 5d6c7673..bd9c2819 100644 --- a/src/services/ai/AIActor.java +++ b/src/services/ai/AIActor.java @@ -97,6 +97,12 @@ public class AIActor { try { if(creature.getHealth() < creature.getMaxHealth() && !creature.isInCombat() && creature.getPosture() != 13 && creature.getPosture() != 14) creature.setHealth(creature.getHealth() + (36 + creature.getLevel() * 4)); + if(creature.getAction() < creature.getMaxAction() && creature.getPosture() != 14) { + if(!creature.isInCombat()) + creature.setAction(creature.getAction() + (15 + creature.getLevel() * 5)); + else + creature.setAction(creature.getAction() + ((15 + creature.getLevel() * 5) / 2)); + } } catch (Exception e) { e.printStackTrace(); } diff --git a/src/services/combat/CombatService.java b/src/services/combat/CombatService.java index 8ab9adcb..caf2b037 100644 --- a/src/services/combat/CombatService.java +++ b/src/services/combat/CombatService.java @@ -68,6 +68,7 @@ import services.sui.SUIWindow.SUICallback; import services.sui.SUIWindow.Trigger; import tools.DevLog; import main.NGECore; +import engine.clients.Client; import engine.resources.common.CRC; import engine.resources.objects.SWGObject; import engine.resources.scene.Point3D; @@ -1371,7 +1372,20 @@ public class CombatService implements INetworkDispatch { if(!applySpecialCost(creature, weapon, command)) success = false; - if(!success && creature.getClient() != null) { + // Quick Hotfix for AI NPCs buffing themselves + Client client = null; + if(creature.getClient() == null) { + if (creature.getAttachment("AI")!=null){ + AIActor aiActor = (AIActor) creature.getAttachment("AI"); + CreatureObject target = aiActor.getFollowObject(); + if (target.getClient()!=null) + client = target.getClient(); // Use player's client reference that is in combat with that NPC + } + } else { + client = creature.getClient(); + } + + if(!success && client != null) { IoSession session = creature.getClient().getSession(); CommandEnqueueRemove commandRemove = new CommandEnqueueRemove(creature.getObjectId(), actionCounter); session.write(new ObjControllerMessage(0x0B, commandRemove).serialize()); @@ -1380,6 +1394,9 @@ public class CombatService implements INetworkDispatch { return; } + if (client == null) + return; + if (creature.hasBuff("co_position_secured")) core.buffService.removeBuffFromCreatureByName(creature, "co_position_secured"); else @@ -1387,11 +1404,11 @@ public class CombatService implements INetworkDispatch { StartTask startTask = new StartTask(actionCounter, creature.getObjectID(), command.getCommandCRC(), CRC.StringtoCRC(command.getCooldownGroup()), command.getCooldown()); ObjControllerMessage objController2 = new ObjControllerMessage(0x0B, startTask); - creature.getClient().getSession().write(objController2.serialize()); + client.getSession().write(objController2.serialize()); CommandEnqueueRemove commandRemove = new CommandEnqueueRemove(creature.getObjectID(), actionCounter); ObjControllerMessage objController3 = new ObjControllerMessage(0x0B, commandRemove); - creature.getClient().getSession().write(objController3.serialize()); + client.getSession().write(objController3.serialize()); } diff --git a/src/services/housing/HouseTemplate.java b/src/services/housing/HouseTemplate.java index b13b5a93..be700f4d 100644 --- a/src/services/housing/HouseTemplate.java +++ b/src/services/housing/HouseTemplate.java @@ -17,6 +17,7 @@ public class HouseTemplate { private Map buildingSigns; private boolean isCivicStructure; private int civicStructureType; + private int destructionFee = 0; public HouseTemplate(String deedTemplate, String buildingTemplate, int lotCost) { this.deedTemplate = deedTemplate; @@ -95,5 +96,13 @@ public class HouseTemplate { public void setCivicStructureType(int civicStructureType) { this.civicStructureType = civicStructureType; } + + public int getDestructionFee() { + return destructionFee; + } + + public void setDestructionFee(int destructionFee) { + this.destructionFee = destructionFee; + } } diff --git a/src/services/housing/HousingService.java b/src/services/housing/HousingService.java index bb9e31d5..85856af7 100644 --- a/src/services/housing/HousingService.java +++ b/src/services/housing/HousingService.java @@ -178,6 +178,7 @@ public class HousingService implements INetworkDispatch { building.addPlayerToAdminList(null, actor.getObjectID(), playerFirstName); building.setDeedTemplate(deed.getTemplate()); building.setMaintenanceAmount(houseTemplate.getBaseMaintenanceRate()); + building.setDestructionFee(houseTemplate.getDestructionFee()); if(city != null) { city.addNewStructure(building.getObjectID()); @@ -320,7 +321,7 @@ public class HousingService implements INetworkDispatch { "\n \n @player_structure:confirm_destruction_d3a " + "\\#32CD32 @player_structure:confirm_destruction_d3b \\#FFFFFF " + "@player_structure:confirm_destruction_d4 "); - if (building.getConditionDamage()<20 && building.getMaintenanceAmount()<3000){ + if (building.getConditionDamage()<20 && building.getMaintenanceAmount() returnList) { core.suiService.closeSUIWindow(owner, 0); - if (noRedeed.size()==0 && ((CreatureObject)owner).getBankCredits()>800) - createCodeWindow(owner, target); + if (noRedeed.size()==0){ + building.setAttachment("Can_Redeed", 1); + } else { + building.setAttachment("Can_Redeed", 0); + } + + createCodeWindow(owner, target); } }); window.addHandler(1, "", Trigger.TRIGGER_CANCEL, returnList, new SUICallback() { @@ -364,17 +370,27 @@ public class HousingService implements INetworkDispatch { public void createCodeWindow(SWGObject owner, TangibleObject target) { final BuildingObject building = (BuildingObject) target.getGrandparent(); + int canRedeed = (int) building.getAttachment("Can_Redeed"); //final BuildingObject building = (BuildingObject) target.getAttachment("housing_parentstruct"); //final BuildingObject building = (BuildingObject)target; Random rnd = new Random(); final int confirmCode = 100000 + rnd.nextInt(900000); final SUIWindow window = core.suiService.createInputBox(2,"@player_structure:structure_status","@player_structure:structure_name_prompt", owner, target, 0); window.setProperty("bg.caption.lblTitle:Text", "@player_structure:confirm_destruction_t"); - - window.setProperty("Prompt.lblPrompt:Text", "@player_structure:your_structure_prefix " + + + + + if (canRedeed==1){ + window.setProperty("Prompt.lblPrompt:Text", "@player_structure:your_structure_prefix " + "\\#32CD32 @player_structure:will_redeed_confirm \\#FFFFFF "+ "@player_structure:will_redeed_suffix " + "\n \n Code: " + confirmCode); + } else { + window.setProperty("Prompt.lblPrompt:Text", "@player_structure:your_structure_prefix " + + "\\#BB0000 @player_structure:will_not_redeed_confirm \\#FFFFFF "+ + "@player_structure:will_redeed_suffix " + + "\n \n Code: " + confirmCode); + } window.setProperty("btnOk:visible", "True"); window.setProperty("btnCancel:visible", "True"); @@ -393,35 +409,54 @@ public class HousingService implements INetworkDispatch { PlayerObject player = (PlayerObject) houseOwner.getSlottedObject("ghost"); HouseTemplate houseTemplate = housingTemplates.get(houseToDeed.get(building.getTemplate())); - TangibleObject deed = (TangibleObject) core.objectService.createObject(houseTemplate.getDeedTemplate(), owner.getPlanet()); - if (player.getLotsRemaining() + houseTemplate.getLotCost() > 10){ - // Something went wrong or hacking attempt - houseOwner.sendSystemMessage("Structure can't be redeeded. Maximum lot count exceeded.",(byte)1); - return; + + if (canRedeed==1){ + TangibleObject deed = (TangibleObject) core.objectService.createObject(houseTemplate.getDeedTemplate(), owner.getPlanet()); + + if (player.getLotsRemaining() + houseTemplate.getLotCost() > 10){ + // Something went wrong or hacking attempt + houseOwner.sendSystemMessage("Structure can't be redeeded. Maximum lot count exceeded.",(byte)1); + return; + } + + deed.setIntAttribute("@obj_attr_n:examine_maintenance_rate", houseTemplate.getBaseMaintenanceRate()); + deed.setIntAttribute("@obj_attr_n:examine_maintenance", (int) building.getMaintenanceAmount()); + + owner.getContainer().remove(owner); + + int costs = 800; + houseOwner.setBankCredits(houseOwner.getBankCredits()-costs); + + destroyStructure(building); + + + SWGObject ownerInventory = owner.getSlottedObject("inventory"); + ownerInventory.add(deed); + + if (player.getLotsRemaining() + houseTemplate.getLotCost() <= 10) { + player.setLotsRemaining(player.getLotsRemaining() + houseTemplate.getLotCost()); + } + + houseOwner.sendSystemMessage("@player_structure:processing_destruction",(byte)1); + houseOwner.sendSystemMessage("@player_structure:deed_reclaimed",(byte)1); + + } else { + + if (player.getLotsRemaining() + houseTemplate.getLotCost() > 10){ + // Something went wrong or hacking attempt + houseOwner.sendSystemMessage("Structure can't be destroyed. Maximum lot count exceeded.",(byte)1); + return; + } + owner.getContainer().remove(owner); + destroyStructure(building); + if (player.getLotsRemaining() + houseTemplate.getLotCost() <= 10) { + player.setLotsRemaining(player.getLotsRemaining() + houseTemplate.getLotCost()); + } + + houseOwner.sendSystemMessage("@player_structure:processing_destruction",(byte)1); } - deed.setIntAttribute("@obj_attr_n:examine_maintenance_rate", houseTemplate.getBaseMaintenanceRate()); - deed.setIntAttribute("@obj_attr_n:examine_maintenance", (int) building.getMaintenanceAmount()); - - owner.getContainer().remove(owner); - - int costs = 800; - houseOwner.setBankCredits(houseOwner.getBankCredits()-costs); - - destroyStructure(building); - - - SWGObject ownerInventory = owner.getSlottedObject("inventory"); - ownerInventory.add(deed); - - if (player.getLotsRemaining() + houseTemplate.getLotCost() <= 10) { - player.setLotsRemaining(player.getLotsRemaining() + houseTemplate.getLotCost()); - } - - houseOwner.sendSystemMessage("@player_structure:processing_destruction",(byte)1); - houseOwner.sendSystemMessage("@player_structure:deed_reclaimed",(byte)1); - } else { houseOwner.sendSystemMessage("@player_structure:incorrect_destroy_code",(byte)1); }