include library.utils; include library.combat; include library.colors; include library.attrib; const string detonateVolName = "landMineDetonationRadius"; const string mineDataTable = "datatables/combat/npc_landmines.iff"; //targetType flags const string flagPlayer = "targetFlag.playerAndPet"; const string flagNpc = "targetFlag.npc-SmugglerReversed"; //String File const string STF = "npc_landmines"; const string_id mineHitMessage = new string_id(STF, "hit_by_mine_detonation"); const string_id commandoDefuseAction = new string_id(STF, "commando_defuse"); const string_id mineDefused = new string_id(STF, "mine_defused"); const string_id smugglerReverseTrigger = new string_id(STF, "smuggler_reverse_trigger"); const string_id mineTriggerReversed = new string_id(STF, "mine_trigger_reversed"); const string_id deactivated = new string_id(STF, "deactivated"); const string_id reversed = new string_id(STF, "reversed"); // change to false to shut off debug logging const boolean loggingOn = false; trigger OnInitialize() { verifyMine(self); setDetonateVolumeByType(self); return SCRIPT_CONTINUE; } trigger OnAttach() { verifyMine(self); setDetonateVolumeByType(self); return SCRIPT_CONTINUE; } trigger OnDestroy() { messageTo(getObjIdObjVar(self, "parentSpawner"), "handleMineRespawn", null, 0, false); return SCRIPT_CONTINUE; } trigger OnObjectMenuRequest(obj_id player, menu_info mi) { if (isDeactivated() || isFlagSwitched()) return SCRIPT_CONTINUE; if (isCommando(player)) { doLogging("OnObjectMenuRequest", "Commando request the defuse option"); mi.addRootMenu(menu_info_types.LANDMINE_DISARM, commandoDefuseAction); } if (isSmuggler(player)) { doLogging("OnObjectMenuRequest", "Smuggler requested the flip trigger option"); mi.addRootMenu(menu_info_types.LANDMINE_REVERSE_TRIGGER, smugglerReverseTrigger); } if (isGod(player)) { sendSystemMessageTestingOnly(player, "You are getting the options because you are in god mode"); mi.addRootMenu(menu_info_types.LANDMINE_DISARM, commandoDefuseAction); mi.addRootMenu(menu_info_types.LANDMINE_REVERSE_TRIGGER, smugglerReverseTrigger); } return SCRIPT_CONTINUE; } trigger OnObjectMenuSelect(obj_id player, int item) { if ( item == menu_info_types.LANDMINE_DISARM) { doCommandoDeactivateAction(player); } if (item == menu_info_types.LANDMINE_REVERSE_TRIGGER) { doSmugglerFlagSwitchAction(player); } return SCRIPT_CONTINUE; } void doCommandoDeactivateAction(obj_id player) { doLogging("doCommandoDeactivationAction", "Deactivating mine, sending signal to destroy self in 10 minutes"); obj_id mine = getSelf(); setObjVar(mine, "deactivated", 1); messageTo(mine, "destroySelf", null, 600, false); sendSystemMessage(player, mineDefused); dictionary params = new dictionary(); params.put("type", "commando"); messageTo(mine, "showStatusFlyText", params, 0, false); } void doSmugglerFlagSwitchAction(obj_id player) { doLogging("doSmugglerFlagSwitchAction", "Flipping mine flag, sending signal to destroy self in 10 minutes"); obj_id mine = getSelf(); setObjVar(mine, "targetFlag", flagNpc); messageTo(mine, "destroySelf", null, 600, false); sendSystemMessage(player, mineTriggerReversed); dictionary params = new dictionary(); params.put("type", "smuggler"); messageTo(mine, "showStatusFlyText", params, 0, false); } messageHandler showStatusFlyText() { string type = params.getString("type"); if (type.equals("commando")) { showFlyText( getSelf(), deactivated, 1.0f, colors.GREEN ); messageTo(getSelf(), "showStatusFlyText", params, 5, false); return SCRIPT_CONTINUE; } if (type.equals("smuggler")) { showFlyText( getSelf(), reversed, 1.0f, colors.ORANGERED ); messageTo(getSelf(), "showStatusFlyText", params, 5, false); return SCRIPT_CONTINUE; } doLogging("showStatusFlyText", "Fly text was called but neither commando or smuggler was the type"); return SCRIPT_CONTINUE; } messageHandler destroySelf() { destroyObject(getSelf()); return SCRIPT_CONTINUE; } boolean isDeactivated() { doLogging("isDeactivated", "Checking is deactivated "+hasObjVar(getSelf(), "deactivated")); return hasObjVar(getSelf(), "deactivated"); } boolean isFlagSwitched() { doLogging("isFlagSwitched", "Current flag is: "+getStringObjVar(getSelf(), "targetFlag")); return (getStringObjVar(getSelf(), "targetFlag").equals(flagNpc)); } void verifyMine(obj_id landMine) { if(!hasObjVar(landMine, "mineType")) { doLogging("verifyMine", "Mine destroyed itself due to invalid mineType objvar"); destroyObject(landMine); return; } string mineType = getStringObjVar(landMine, "mineType"); string testValid = dataTableGetString(mineDataTable, mineType, "mineType"); if (testValid == null || testValid.equals("")) { doLogging("verifyMine", "Mine destroyed itself due to invalid entry("+mineType+") in datatable("+mineDataTable+")"); destroyObject(landMine); return; } } void setDetonateVolumeByType(obj_id landMine) { string mineType = getStringObjVar(landMine, "mineType"); float detonateRange = dataTableGetFloat(mineDataTable, mineType, "detonateRange"); setAttributeInterested(landMine, attrib.ALL); if (!hasTriggerVolume(landMine, detonateVolName)) { doLogging("setDetonatevolumeByType", "Detonation range for mineType("+mineType+") set to: "+detonateRange); createTriggerVolume(detonateVolName, detonateRange, true); } } trigger OnTriggerVolumeEntered(string volumeName, obj_id breacher) { if (isDeactivated()) return SCRIPT_CONTINUE; if (volumeName.equals(detonateVolName)) { if (isValidTargetTypeByMineFlag(breacher)) { if (willTriggerMineBlast(breacher)) { obj_id[] targets = getTargetsInBlastRadius(); if (targets == null) { doLogging("OnTriggerVolumeEntered", "Mine destroyed iself because no targets were returned from getTargetsInBlastRadius"); destroyObject(getSelf()); return SCRIPT_CONTINUE; } applyMineEffects(targets); } } } return SCRIPT_CONTINUE; } obj_id[] getTargetsInBlastRadius() { obj_id landMine = getSelf(); string mineType = getStringObjVar(landMine, "mineType"); float blastRadius = dataTableGetFloat(mineDataTable, mineType, "blastRadius"); location loc = getLocation(landMine); if (loc == null) return null; obj_id[] objects = getObjectsInRange(loc, blastRadius); resizeable obj_id[] targetsInRadius = new obj_id[0]; for (int i = 0; i < objects.length; i++) { if (isValidTargetTypeByMineFlag(objects[i])) { if (!isIncapacitated(objects[i]) && !isDead(objects[i])) { targetsInRadius = utils.addElement(targetsInRadius, objects[i]); doLogging("getTargetsInBlastRadius", "Target("+getName(objects[i])+"/"+objects[i]+") added to targetsInRadius array"); } } } if (targetsInRadius.length < 1) { doLogging("getTargetsInBlastRadius", "targetsInRadius is less than 1, returning null"); return null; } else return targetsInRadius; } void applyMineEffects(obj_id[] targets) { obj_id landMine = getSelf(); location mineLoc = getLocation(getSelf()); string mineType = getStringObjVar(landMine, "mineType"); int minDamage = dataTableGetInt(mineDataTable, mineType, "minDamage"); int maxDamage = dataTableGetInt(mineDataTable, mineType, "maxDamage"); string stringDamageType = dataTableGetString(mineDataTable, mineType, "damageType"); string mineDetonationEffect = dataTableGetString(mineDataTable, mineType, "effectOnExplode"); int damageType = getDamageTypeFromString(stringDamageType); doLogging("applyMineEffects", "mineType: "+mineType+", minDamage: "+minDamage+", maxDamage: "+maxDamage+", stringDamageType: "+stringDamageType+", mineDetonationEffect: "+mineDetonationEffect); if (damageType == -1) { doLogging("applyMineEffects", "getDamageTypeFromString returned -1 when sent "+stringDamageType+" for mine "+mineType); destroyObject(landMine); return; } playClientEffectLoc(targets[0], mineDetonationEffect, mineLoc, 0.4f); for (int i = 0;i