I mean, the coding part is actually pretty straightforward. It's all the math involved in deciding how stongly to pull, in which direction, whether to break the cable or not, etc, that is going to take a lot of thinking.
For coding, all you need is:
1) An OnHitEffectPlugin for your weapon's projectile. Within it you have:
public void onHit(DamagingProjectileAPI projectile, CombatEntityAPI target, Vector2f point, boolean shieldHit, ApplyDamageResultAPI damageResult, CombatEngineAPI engine) {
//...
}
Here, you decide if you want to attach harpoon or not. Do the shield hit counts, does some damage threshold needs to be exceeded, etc. You will also need to check if the target is an instance of ShipAPI or not. If you do want to attach a cable, you then do:
ShipAPI target_ship = (ShipAPI) target;
target_ship.addListener(new my_every_frame_harpoon_script(...));
2) An every frame combat script, in this case a listener class that implements AdvanceableListener. You pass the towing ShipAPI, the target ShipAPI, and the connection point (likely the Vector2f point from the on-hit effect) as constructor arguments to it and store them in protected/private variables.
Then here you have:
public void advance(float amount) {
//...
}
This method is called every script (amount is how many seconds have passed since the last call). Here you do a bunch of very difficult math to figure out the force and direction of the pull. You can use ShipAPI.getLocation() and ShipAPI.getVelocity() to find the locations and velocity vectors of both ships. When you want to push something, you just modify its getVelocity().
3) When you want to break the cable, you do
towed_ship.removeListener(this);
withing your every frame listener's advance method.
4) You will also need to do visuals for the cable. They will also be updated in the advance method.