package com.planet_ink.coffee_mud.Items.BasicTech; import com.planet_ink.coffee_mud.core.interfaces.*; import com.planet_ink.coffee_mud.core.*; import com.planet_ink.coffee_mud.core.collections.*; import com.planet_ink.coffee_mud.Abilities.interfaces.*; import com.planet_ink.coffee_mud.Areas.interfaces.*; import com.planet_ink.coffee_mud.Behaviors.interfaces.*; import com.planet_ink.coffee_mud.CharClasses.interfaces.*; import com.planet_ink.coffee_mud.Commands.interfaces.*; import com.planet_ink.coffee_mud.Common.interfaces.*; import com.planet_ink.coffee_mud.Exits.interfaces.*; import com.planet_ink.coffee_mud.Items.interfaces.*; import com.planet_ink.coffee_mud.Items.interfaces.Armor.SizeDeviation; import com.planet_ink.coffee_mud.Items.interfaces.Technical.TechType; import com.planet_ink.coffee_mud.Libraries.interfaces.*; import com.planet_ink.coffee_mud.Locales.interfaces.*; import com.planet_ink.coffee_mud.MOBS.interfaces.*; import com.planet_ink.coffee_mud.Races.interfaces.*; import java.util.*; /* Copyright 2013-2019 Bo Zimmerman Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ public class StdPersonalShield extends StdElecItem implements Armor { @Override public String ID() { return "StdPersonalShield"; } short layer=0; short layerAttributes=0; public StdPersonalShield() { super(); setName("a personal shield generator"); basePhyStats.setWeight(2); setDisplayText("a personal shield generator sits here."); setDescription("The muting field generator is worn about the body and activated to use. It neutralizes weapon damage. "); baseGoldValue=2500; basePhyStats().setLevel(1); recoverPhyStats(); setMaterial(RawMaterial.RESOURCE_STEEL); super.activate(true); super.setRawProperLocationBitmap(Wearable.WORN_ABOUT_BODY); super.setPowerCapacity(1000); super.setPowerRemaining(1000); } protected String fieldOnStr(final MOB viewerM) { return L((owner() instanceof MOB)? "A field of energy surrounds <O-NAME>.": "A field of energy surrounds <T-NAME>."); } protected String fieldDeadStr(final MOB viewerM) { return L((owner() instanceof MOB)?"" + "The field around <O-NAME> flickers and dies out.": "The field around <T-NAME> flickers and dies out."); } @Override public TechType getTechType() { return TechType.PERSONAL_SHIELD; } protected boolean doShield(final MOB mob, final CMMsg msg, final double successFactor) { if(mob.location()!=null) { if(msg.tool() instanceof Weapon) { final String s="^F"+((Weapon)msg.tool()).hitString(0)+"^N"; if(s.indexOf("<DAMAGE> <T-HIM-HER>")>0) mob.location().show(msg.source(),msg.target(),msg.tool(),CMMsg.MSG_OK_VISUAL,CMStrings.replaceAll(s, "<DAMAGE>", L("it reflects off the shield around"))); else if(s.indexOf("<DAMAGES> <T-HIM-HER>")>0) mob.location().show(msg.source(),msg.target(),msg.tool(),CMMsg.MSG_OK_VISUAL,CMStrings.replaceAll(s, "<DAMAGES>", L("reflects off the shield around"))); else mob.location().show(mob,msg.source(),msg.tool(),CMMsg.MSG_OK_VISUAL,L("The field around <S-NAME> reflects the <O-NAMENOART> damage.")); } else mob.location().show(mob,msg.source(),msg.tool(),CMMsg.MSG_OK_VISUAL,L("The field around <S-NAME> reflects the <O-NAMENOART> damage.")); } return false; } protected boolean doesShield(final MOB mob, final CMMsg msg, final double successFactor) { return (Math.random() >= successFactor) && activated(); } @Override public boolean sameAs(final Environmental E) { if(!(E instanceof StdPersonalShield)) return false; return super.sameAs(E); } @Override public void setMiscText(final String newText) { if(CMath.isInteger(newText)) this.setPowerCapacity(CMath.s_int(newText)); super.setMiscText(newText); } @Override public SizeDeviation getSizingDeviation(final MOB mob) { return SizeDeviation.FITS; } @Override public boolean okMessage(final Environmental myHost, final CMMsg msg) { if(!super.okMessage(myHost, msg)) return false; if(msg.amITarget(owner()) && (owner() instanceof MOB)) { final MOB mob=(MOB)owner(); switch(msg.targetMinor()) { case CMMsg.TYP_REMOVE: case CMMsg.TYP_DROP: if(activated()) msg.addTrailerMsg(CMClass.getMsg(mob, this, null,CMMsg.MSG_OK_VISUAL,CMMsg.TYP_DEACTIVATE|CMMsg.MASK_ALWAYS,CMMsg.MSG_OK_VISUAL,fieldDeadStr(msg.source()))); break; case CMMsg.TYP_DAMAGE: // remember 50% miss rate if((activated()) &&(powerRemaining()>0) && amBeingWornProperly()) { double successFactor=0.5; final Manufacturer m=getFinalManufacturer(); successFactor=m.getReliabilityPct()*successFactor; int weaponTech=CMLib.tech().getGlobalTechLevel(); if(msg.tool() instanceof Electronics) weaponTech=((Electronics)msg.tool()).techLevel(); final int myTech=techLevel(); final int techDiff=Math.max(Math.min(myTech-weaponTech,10),-10); if(techDiff!= 0) successFactor+=(0.05)*techDiff; if(doesShield(mob, msg, successFactor)) { final long powerConsumed=Math.round(msg.value()*Math.max(.33, Math.abs(2.0-m.getEfficiencyPct()))); if(powerRemaining()>=powerConsumed) { setPowerRemaining(powerRemaining()-powerConsumed); if(!doShield(mob,msg, successFactor)) return false; } else setPowerRemaining(0); } if(powerRemaining()<=0) { setPowerRemaining(0); final CMMsg msg2=CMClass.getMsg(mob, this, null,CMMsg.MSG_OK_VISUAL,CMMsg.TYP_DEACTIVATE|CMMsg.MASK_ALWAYS,CMMsg.MSG_OK_VISUAL,fieldDeadStr(msg.source())); if(mob.location()!=null) mob.location().send(mob, msg2); } } break; } } return true; } @Override public void executeMsg(final Environmental host, final CMMsg msg) { if(msg.amITarget(this)) { switch(msg.targetMinor()) { case CMMsg.TYP_LOOK: super.executeMsg(host, msg); if(CMLib.flags().canBeSeenBy(this, msg.source())) { msg.source().tell(L("@x1 is currently @x2 and is at @x3% power.",name(),(activated()?"activated":"deactivated"),""+Math.round(CMath.div(powerRemaining(),powerCapacity())*100.0))); } return; case CMMsg.TYP_ACTIVATE: { if((msg.source().location()!=null)&&(!CMath.bset(msg.targetMajor(), CMMsg.MASK_CNTRLMSG))) msg.source().location().show(msg.source(), this, owner(), CMMsg.MSG_OK_VISUAL, fieldOnStr(null)); this.activate(true); final Physical P=owner(); if(P!=null) { P.recoverPhyStats(); if(P instanceof MOB) { ((MOB)P).recoverCharStats(); ((MOB)P).recoverMaxState(); } } break; } case CMMsg.TYP_DEACTIVATE: { if((msg.source().location()!=null)&&(!CMath.bset(msg.targetMajor(), CMMsg.MASK_CNTRLMSG))) msg.source().location().show(msg.source(), this, owner(), CMMsg.MSG_OK_VISUAL, fieldDeadStr(null)); this.activate(false); final Physical P=owner(); if(P!=null) { P.recoverPhyStats(); if(P instanceof MOB) { ((MOB)P).recoverCharStats(); ((MOB)P).recoverMaxState(); } } break; } default: super.executeMsg(host,msg); break; } } else if(msg.amITarget(owner()) && (owner() instanceof MOB) && (!amWearingAt(Wearable.IN_INVENTORY))) { switch(msg.targetMinor()) { case CMMsg.TYP_LOOK: super.executeMsg(host, msg); if(CMLib.flags().canBeSeenBy(owner(), msg.source()) &&(activated())&&(powerRemaining()>0)) msg.source().tell(msg.source(),this,owner(),fieldOnStr(msg.source())); return; } } super.executeMsg(host, msg); } @Override public short getClothingLayer() { return layer; } @Override public void setClothingLayer(final short newLayer) { layer = newLayer; } @Override public short getLayerAttributes() { return layerAttributes; } @Override public void setLayerAttributes(final short newAttributes) { layerAttributes = newAttributes; } @Override public boolean canWear(final MOB mob, final long where) { if(where==0) return (whereCantWear(mob)==0); if((rawProperLocationBitmap()&where)!=where) return false; return mob.freeWearPositions(where,getClothingLayer(),getLayerAttributes())>0; } }