1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-08-30 00:57:55 +00:00

Nuke treasure disks

They're datapacks now. Right???
This commit is contained in:
Jonathan Coates
2021-06-09 09:19:21 +01:00
parent e8d90b94ec
commit 2279f5044d
180 changed files with 353 additions and 12220 deletions

View File

@@ -9,4 +9,4 @@ labels: peripheralShoutout
- Link to the mod
- Mod Name
- Basic description of the mod
- Link to CC:R Peripheral Documentation for the mod
- Link to CC:R Peripheral Documentation for the mod

View File

@@ -9,6 +9,9 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Checkout submodules
run: git submodule update --init --recursive
- name: Set up Java 8
uses: actions/setup-java@v1

2
.gitignore vendored
View File

@@ -20,4 +20,4 @@
.idea
.gradle
*.DS_Store
.project
.project

2
.gitpod.Dockerfile vendored
View File

@@ -16,4 +16,4 @@ RUN sudo apt-get -q update && \
sudo apt install -yq openjdk-8-jdk openjdk-16-jdk
# This is so that you can use java 8 until such a time as you switch to java 16
RUN sudo update-java-alternatives --set java-1.8.0-openjdk-amd64
RUN sudo update-java-alternatives --set java-1.8.0-openjdk-amd64

View File

@@ -15,4 +15,4 @@ vscode:
tasks:
- init: ./gradlew
- init: ./gradlew

View File

@@ -9,7 +9,7 @@
// Custom Hidden Files
"**/.bin": true,
"**/.editorconfig": true,
},
},
"java.configuration.updateBuildConfiguration": "automatic"
}
}

14
LICENSE
View File

@@ -19,14 +19,14 @@ Mod: The mod code designated by the present license, in source form, binary
form, as obtained standalone, as part of a wider distribution or resulting from
the compilation of the original or modified sources.
Dependency: Code required for the mod to work properly. This includes
Dependency: Code required for the mod to work properly. This includes
dependencies required to compile the code as well as any file or modification
that is explicitly or implicitly required for the mod to be working.
1. Scope
--------
The present license is granted to any user of the mod. As a prerequisite,
The present license is granted to any user of the mod. As a prerequisite,
a user must own a legally acquired copy of Minecraft
2. Liability
@@ -41,13 +41,13 @@ or misuse of this mod fall on the user.
3. Play rights
--------------
The user is allowed to install this mod on a Minecraft client or server and to play
The user is allowed to install this mod on a Minecraft client or server and to play
without restriction.
4. Modification rights
----------------------
The user has the right to decompile the source code, look at either the
The user has the right to decompile the source code, look at either the
decompiled version or the original source code, and to modify it.
5. Distribution of original or modified copy rights
@@ -61,10 +61,10 @@ include:
- patch to its source or binary files
- any copy of a portion of its binary source files
The user is allowed to redistribute this mod partially, in totality, or
The user is allowed to redistribute this mod partially, in totality, or
included in a distribution.
When distributing binary files, the user must provide means to obtain its
When distributing binary files, the user must provide means to obtain its
entire set of sources or modified sources at no cost.
All distributions of this mod must remain licensed under the CCPL.
@@ -92,7 +92,7 @@ must be made available at no cost and remain licensed under the CCPL.
---------------
If you choose to contribute code or assets to be included in this mod, you
agree that, if added to to the main repository at
agree that, if added to to the main repository at
https://github.com/dan200/ComputerCraft, your contributions will be covered by
this license, and that Daniel Ratcliffe will retain the right to re-license the
mod, including your contributions, in part or in whole, under other licenses.

View File

@@ -30,7 +30,7 @@ Any contribution is welcome, be that using the mod, reporting bugs or contributi
> Comments, optional but useful if you had to do something differently than in CC:T outside of [Fabric](https://fabricmc.net/)/[Forge](https://mcforge.readthedocs.io/en/1.16.x/) differences
>
> \`\`\`
>
>
>commitID
>
> commit title
@@ -38,29 +38,29 @@ Any contribution is welcome, be that using the mod, reporting bugs or contributi
> commit desc
>
> \`\`\`
2) Follow the [Fabric](https://fabricmc.net/) programming guidelines as close as possible. This means you have to use [`loom`](https://fabricmc.net/wiki/tutorial:mappings) mappings,
2) Follow the [Fabric](https://fabricmc.net/) programming guidelines as close as possible. This means you have to use [`loom`](https://fabricmc.net/wiki/tutorial:mappings) mappings,
3) You cannot intentionally implement bugs and security vulnerabilities
4) Unless the commit is a ["patchwork"](https://github.com/Merith-TK/cc-restitched/blob/fabric/patchwork.md) compliant commit, (IE: taken from CC:T), the lua code is off limits
## Bleeding Edge Builds
Bleeding edge builds can be found [here](https://github.com/Merith-TK/cc-restitched/actions) at Github Actions.
## Community
If you need help getting started with CC: Tweaked, want to show off your latest project, or just want to chat about ComputerCraft, here is the [Forum](https://forums.computercraft.cc/) and the [Discord](https://discord.gg/H2UyJXe)
If you need help getting started with CC: Tweaked, want to show off your latest project, or just want to chat about ComputerCraft, here is the [Forum](https://forums.computercraft.cc/) and the [Discord](https://discord.gg/H2UyJXe)
## Known Issues
Main Known issue
* Mods that add blocks that can be used as peripherals for CC:T On forge, don't work with CC:R.
* This is because of the differences between forge and fabric, and that mod devs, to my knowledge have not agreed upon a standard method in which to implement cross compatibility between mods,
* [Fixed (d10f297c): please report if bug persists]</br> ~~Storage Peripherals throw a java "StackOverflowError" when using `pushItems()`,~~
* ~~Work around, you are probably using `pushItems(chest, 1)` or similar. please use `pushItems(chest, 1, nil, 1)`.~~
* [Fixed (d10f297c): please report if bug persists]</br> ~~Storage Peripherals throw a java "StackOverflowError" when using `pushItems()`,~~
* ~~Work around, you are probably using `pushItems(chest, 1)` or similar. please use `pushItems(chest, 1, nil, 1)`.~~
* Computers will not run built in commands, saying "File not found"
* This is a know bug, dont know what causes it, but just restart the computer (`ctrl+r` for one second) and it will work again
* Occurs when server runs `/reload` or a datapack is updated
## Perpherals
Unfortunately, unlike the original CC:Tweaked project, CC:Restitched, does not have any actual peripheral mods, currently the only one we have is an example for mod devs to get started with making/adding the peripheral API to their mods!
If your a mod dev made a mod with CC:R peripheral support, OR if your a player who found a mod with CC:R support, please open an [issue here](https://github.com/Merith-TK/cc-restitched/issues/new?assignees=&labels=peripheralShoutout&template=peripheral_shoutout.md) to let us know so we can add it to the list!
* ![icon](https://raw.githubusercontent.com/Toad-Dev/cc-peripheral-test/master/src/main/resources/assets/cc_test/textures/block/test_peripheral.png) [CC Peripheral Test](https://github.com/Toad-Dev/cc-peripheral-test)
* This is an example mod for how to make peripherals that work as a block, or as a turtle upgrade!
* This is an example mod for how to make peripherals that work as a block, or as a turtle upgrade!

View File

@@ -2488,4 +2488,4 @@
</option>
</inspection_tool>
</profile>
</component>
</component>

View File

@@ -58,4 +58,4 @@
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</code_scheme>

View File

@@ -44,5 +44,6 @@ exclude: |
src/generated|
src/test/resources/test-rom/data/json-parsing/|
src/test/server-files/|
config/idea/
config/idea/|
.vscode/
)

View File

@@ -9,7 +9,7 @@ SubScript // Desc of commit
```
If a edit that is present in CC:T is not needed, I will skip over it.
Any and all references to an issue number, are to be found on CC:T's repo.
Any and all references to an issue number, are to be found on CC:T's repo.
Any commit that starts with `[Patchwork]` are purely edits made by my hand, and not based on other commits from CC:T, this is to help differentiate my changes from the official changes
@@ -138,9 +138,9 @@ evidently need to lint examples too.
Add color table to docs (#553)
```
All API Documentation updates,
All API Documentation updates,
`Not Needed` for this repo.
```
```
93068402a2ffec00eedb8fe2d859ebdc005a1989
Document remaining OS functions (#554)
@@ -148,7 +148,7 @@ Document remaining OS functions (#554)
Update illuaminate CSS for deprecation (#556)
```
```
```
Not Needed
4766833cf2d041ed179529eecb9402ad09b2b79b
Bump JEI/crafttweaker versions
@@ -156,12 +156,12 @@ Bump JEI/crafttweaker versions
In my defence, they weren't out when I started the 1.15 update.
```
```
```
bf6053906dc6a3c7b0d40d5b097e745dce1f33bc
Fix TBO norm issues on old GPUs
```
```
```
Not Needed
113b560a201dbdea9de2a2ef536bcce1d6e51978
Update configuration to match latest illuaminate
@@ -201,7 +201,7 @@ to expose this.
Closes #452
```
```
```
Not Needed
6aae4e576621090840724e094aa25e51696530fc
Remove superfluous imports
@@ -210,7 +210,7 @@ Hah, this is embarassing
```
[TODO] [M3R1-01] Code has been applied, players still dont get achievments
```
```
f6160bdc57b3d9850607c2c7c2ce9734b4963478
Fix players not getting advancements when they own turtles
@@ -228,7 +228,7 @@ resolve this properly.
Fixes #564
```
```
```
17a932920711a5c0361a5048c9e0a5e7a58e6364
Bump cct-javadoc version
@@ -245,7 +245,7 @@ Tesselator, but this'll do for now.
Fixes Zundrel/cc-tweaked-fabric#20.
```
```
```
c58441b29c3715f092e7f3747bb3ec65ae5a3d29
Various SNBT parsing improvements
@@ -257,7 +257,7 @@ Correctly handle:
Fixes #559
```
```
```
e2a635b6e5f5942f999213434054e06833c5cb06
Dont fail when codecov is being finicky
```
@@ -270,13 +270,13 @@ Maybe I should run the whole test suite, not just the things I think
matter? Nah....
```
```
```
741adfa7bb2b950d2851c3f0072d6a4769f22773
Use blit to draw boxes, add colors.toBlit (#570)
```
```
```
d13bd2cce8d102ad7f61f557e707d6fe3731bc37
use arg[0] in all usage printouts (#571)
@@ -289,7 +289,7 @@ Bump to 1.94.0
```
[TODO] [M3R1-02] Zero Clue how to reimplement this in fabric.
```
```
c8aeddedd4ed430f9cb6428676ebb4fa39834182
Auto-generate monitor models
@@ -399,7 +399,7 @@ Hopefully fixes #585. Hopefully.
```
511eea39a11956c82e2c11a47b2e7cad27f9887e
Remove <!-- -->s in usages
Remove <!-- -->s in usages
```
```
@@ -426,7 +426,7 @@ Didn't port the lua tests over.
```
737b3cb57696fb5517252e7db38bc88ce960b4d8
Don't use capabilities for generic peripherals
Don't use capabilities for generic peripherals
```
Not ported, related to forges capability system which is not used in the port.

View File

@@ -1,6 +1,6 @@
{
"animation": {
"frametime": 8,
"frames": [ 0, 1 ]
}
}
{
"animation": {
"frametime": 8,
"frames": [ 0, 1 ]
}
}

View File

@@ -1,6 +1,6 @@
{
"animation": {
"frametime": 8,
"frames": [ 0, 1 ]
}
}
{
"animation": {
"frametime": 8,
"frames": [ 0, 1 ]
}
}

View File

@@ -1,6 +1,6 @@
{
"animation": {
"frametime": 8,
"frames": [ 0, 1 ]
}
}
{
"animation": {
"frametime": 8,
"frames": [ 0, 1 ]
}
}

View File

@@ -1,6 +1,6 @@
{
"animation": {
"frametime": 8,
"frames": [ 0, 1 ]
}
}
{
"animation": {
"frametime": 8,
"frames": [ 0, 1 ]
}
}

View File

@@ -40,4 +40,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -29,4 +29,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -29,4 +29,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -29,4 +29,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -29,4 +29,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -29,4 +29,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -29,4 +29,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -29,4 +29,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -29,4 +29,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -29,4 +29,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -29,4 +29,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -29,4 +29,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -29,4 +29,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -29,4 +29,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -29,4 +29,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -29,4 +29,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -29,4 +29,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -29,4 +29,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -29,4 +29,4 @@
"has_the_recipe"
]
]
}
}

View File

@@ -1,4 +1,4 @@
--[[
Alright then, don't ignore me. This file is to ensure the existence of the "autorun" folder, files placed in this folder
using resource packs will always run when computers startup.
]]
]]

View File

@@ -11,6 +11,6 @@ New features in CC: Restitched 1.96.0
And several bug fixes:
* Fix paintutils.drawLine incorrectly sorting coordinates (lilyzeiset).
* Fix crash with music disk
* Fix Display peripheral chat messages in multiplayer and improve /computercraft command.
* Fix Display peripheral chat messages in multiplayer and improve /computercraft command.
Type "help changelog" to see the full version history.

View File

@@ -1,875 +0,0 @@
--[[
battleship,
by GopherAtl, 2013
Do whatever you want, just don't judge me by
what a mess this code is.
--]]
local args={...}
local action=args[1]
local opponentID=nil
local openedSide=nil
local opponent=nil
local myName=""
local opponentReady=false
local myTurn
local targetX,targetY
local shipsLeft=5
local oppShipsLeft=5
local originalTerm = term.current()
--bounding box of the target grid
local targetGridBounds={
minX=16, maxX=25,
minY=4, maxY=13
}
local function doColor(text,background)
term.setTextColor(text)
term.setBackgroundColor(background)
end
local function doColor_mono(text,background)
if text==colors.blue or text==colors.red or text==colors.black or text==colors.lime or background==colors.lightGray then
term.setTextColor(colors.black)
term.setBackgroundColor(colors.white)
else
term.setTextColor(colors.white)
term.setBackgroundColor(colors.black)
end
end
local function doScreenColor()
if term.isColor() then
doColor(colors.white,colors.lightGray)
else
doColor(colors.black,colors.white)
end
end
local function toGridRef(x,y)
return string.sub("ABCDEFGHIJ",x,x)..string.sub("1234567890",y,y)
end
if not term.isColor() then
doColor=doColor_mono
end
local function quit()
if openedSide then
rednet.close(openedSide)
end
term.redirect( originalTerm )
term.setCursorPos(term.getSize())
print()
error()
end
local foundModem=false
--find modem
for k,v in pairs(redstone.getSides()) do
if peripheral.getType(v)=="modem" then
foundModem=true
if not rednet.isOpen(v) then
rednet.open(v)
openedSide=v
end
break
end
end
if not foundModem then
print("You must have a modem to play!")
return
end
if action==nil or (action~="join" and action~="host") then
print("Invalid parameters. Usage:\n> battleship host\nHosts a game, waits for another computer to join\n> battleship join\nLooks for another game to join")
quit()
end
--get player name
while true do
doColor(colors.cyan,colors.black)
write("player name: ")
doColor(colors.gray,colors.black)
myName=read()
if myName=="" then
doColor(colors.red,colors.black)
print("You have to give a name!")
elseif #myName>11 then
doColor(colors.red,colors.black)
print("Max name is 11 characters!")
else
break
end
end
if action=="join" then
print("Attempting to join a game...\n(press q to cancel)")
while true do
local retryTimer=os.startTimer(1);
rednet.broadcast("bs join "..myName);
while true do
local event,p1,p2,p3=os.pullEvent();
if event=="rednet_message" then
opponent=string.match(p2,"bs accept %s*(.+)%s*")
if opponent then
opponentID=p1
break
end
elseif event=="timer" and p1==retryTimer then
break
elseif event=="char" and (p1=="q" or p1=="Q") then
print("Couldn't find an opponent; quitting")
quit()
end
end
local joined=false
if opponentID then
print("Joining game!")
rednet.send(opponentID,"bs start")
break
end
end
elseif action=="host" then
print("Waiting for challenger...\n(Press q to cancel)")
while true do
while true do
local event,p1,p2=os.pullEvent()
if event=="rednet_message" then
opponent=string.match(p2,"bs join %s*(.+)%s*") if opponent then
print("found player, inviting..")
opponentID=p1
break
end
elseif event=="char" and (p1=="q" or p1=="Q") then
print("Couldn't find opponent, quitting")
quit()
end
end
if opponentID then
rednet.send(opponentID,"bs accept "..myName)
local timeout=os.startTimer(1)
while true do
local event,p1,p2=os.pullEvent()
if event=="rednet_message" and p2=="bs start" then
print("player joined!")
break
elseif event=="timer" and p1==timeout then
print("player joined another game. Waiting for another...")
opponentID=nil
break
end
end
if opponentID then
break
end
end
end
end
local ships={
{pos=nil,dir="h",size=5,name="carrier",hits=0},
{pos=nil,dir="h",size=4,name="battleship",hits=0},
{pos=nil,dir="h",size=3,name="cruiser",hits=0},
{pos=nil,dir="h",size=3,name="submarine",hits=0},
{pos=nil,dir="h",size=2,name="destroyer",hits=0},
}
local myShotTable={ {1,1,true},{5,5,false} }
local oppShotTable={ }
local myGrid,oppGrid={title=myName},{title=opponent}
--setup grids
for i=1,10 do
myGrid[i]={}
oppGrid[i]={}
for j=1,10 do
myGrid[i][j]={hit=false,ship=false}
oppGrid[i][j]={hit=false,ship=false}
end
end
local function drawShipsToGrid(ships,grid)
for i=1,#ships do
local x,y=table.unpack(ships[i].pos)
local stepX=ships[i].dir=="h" and 1 or 0
local stepY=stepX==1 and 0 or 1
for j=1,ships[i].size do
grid[x][y].ship=i
x,y=x+stepX,y+stepY
end
end
end
local function drawShotToGrid(shot,grid)
grid[shot[1]][shot[2]].shot=true
grid[shot[1]][shot[2]].hit=shot[3]
end
local function makeShot(x,y,grid)
local tile=grid[x][y]
if tile.shot==true then
return nil --already shot here!
end
local shot={x,y,tile.ship}
drawShotToGrid(shot,grid)
if tile.ship then
ships[tile.ship].hits=ships[tile.ship].hits+1
if ships[tile.ship].hits==ships[tile.ship].size then
os.queueEvent("shipsunk",tile.ship)
end
end
return shot
end
local function drawTile(scrX,scrY,tile)
term.setCursorPos(scrX,scrY)
if tile.ship then
if tile.shot then
doColor(colors.red,colors.gray)
term.write("@")
else
doColor(colors.white,colors.gray)
term.write("O")
end
else
if tile.hit then
doColor(colors.red,colors.gray)
term.write("x")
elseif tile.shot then
doColor(colors.white,colors.lightBlue)
term.write(".")
else
doColor(colors.white,colors.lightBlue)
term.write(" ")
end
end
end
local function drawGrid(scrX,scrY,grid)
doColor(colors.white,colors.black)
term.setCursorPos(scrX,scrY+1)
term.write(" ")
doColor(colors.white,colors.gray)
term.setCursorPos(scrX,scrY)
local pad=11-#grid.title
term.write(string.rep(" ",math.ceil(pad/2))..grid.title..string.rep(" ",math.floor(pad/2)))
for gx=1,10 do
term.setTextColor(colors.white)
term.setBackgroundColor(colors.black)
term.setCursorPos(scrX+gx,scrY+1)
term.write(gx==10 and "0" or string.char(string.byte("0")+gx))
term.setCursorPos(scrX,scrY+gx+1)
term.write(string.char(string.byte("A")+gx-1))
for gy=1,10 do
drawTile(scrX+gx,scrY+gy+1,grid[gx][gy])
end
end
doColor(colors.white,colors.black)
end
function moveTargetIndicator(newX,newY)
--if x has changed...
if targetX and targetY then
drawTile(targetX+targetGridBounds.minX-1,targetY+targetGridBounds.minY-1,oppGrid[targetX][targetY])
end
doColor(colors.yellow,colors.lightGray)
if newX~=targetX then
--space over old
if targetX then
term.setCursorPos(targetGridBounds.minX+targetX-1,targetGridBounds.maxY+1)
term.write(" ")
term.setCursorPos(targetGridBounds.minX+targetX-1,targetGridBounds.minY-3)
term.write(" ")
end
--draw new
term.setCursorPos(targetGridBounds.minX+newX-1,targetGridBounds.maxY+1)
term.write("^")
term.setCursorPos(targetGridBounds.minX+newX-1,targetGridBounds.minY-3)
term.write("v")
targetX=newX
end
if newY~=targetY then
--space over old
if targetY then
term.setCursorPos(targetGridBounds.maxX+1,targetGridBounds.minY+targetY-1)
term.write(" ")
term.setCursorPos(targetGridBounds.minX-2,targetGridBounds.minY+targetY-1)
term.write(" ")
end
--draw new
term.setCursorPos(targetGridBounds.maxX+1,targetGridBounds.minY+newY-1)
term.write("<")
term.setCursorPos(targetGridBounds.minX-2,targetGridBounds.minY+newY-1)
term.write(">")
targetY=newY
end
term.setCursorPos(15,15)
term.write("Target : "..toGridRef(targetX,targetY))
--if the target tile is a valid target, draw a "+"
if not oppGrid[targetX][targetY].shot then
term.setCursorPos(targetX+targetGridBounds.minX-1,targetY+targetGridBounds.minY-1)
doColor(colors.yellow,colors.lightBlue)
term.write("+")
end
end
local log={}
local termWidth,termHeight=term.getSize()
local logHeight=termHeight-3
local logWidth=termWidth-28
for i=1,logHeight do
log[i]=""
end
local function printLog()
doColor(colors.white,colors.black)
for i=1,logHeight do
term.setCursorPos(28,1+i)
local name,line=string.match(log[i],"(<[^>]+> )(.*)")
if name then
doColor(colors.lightBlue,colors.black)
write(name)
doColor(colors.white,colors.black)
write(line..string.rep(" ",logWidth-#log[i]))
else
write(log[i]..string.rep(" ",logWidth-#log[i]))
end
end
end
--shipX/Y are the position of ship on grid; gridX/Y are the offset of the top-left of grid
local function drawShip(size,align,x,y,char)
local stepX=align=="h" and 1 or 0
local stepY=stepX==1 and 0 or 1
for j=1,size do
term.setCursorPos(x,y)
term.write(char)
x,y=x+stepX,y+stepY
end
end
local function setStatusLine(lineNum,text)
doScreenColor()
local pad=math.floor((termWidth-#text)/2)
term.setCursorPos(1,16+lineNum)
term.write((" "):rep(pad)..text..(" "):rep(termWidth-#text-pad))
end
doScreenColor()
term.clear()
drawGrid(2,2,myGrid)
setStatusLine(1,"Started game with "..opponent.." at computer #"..(opponentID or "nil"))
local function getShipBounds(ship)
return {
minX=ship.pos[1],
minY=ship.pos[2],
maxX=ship.pos[1]+(ship.dir=="h" and ship.size-1 or 0),
maxY=ship.pos[2]+(ship.dir=="v" and ship.size-1 or 0)
}
end
local function getPointBounds(x,y)
return {
minX=x,
minY=y,
maxX=x,
maxY=y,
}
end
local function boundsIntersect(boundsA,boundsB)
return not (
boundsA.minX>boundsB.maxX or
boundsA.maxX<boundsB.minX or
boundsA.minY>boundsB.maxY or
boundsA.maxY<boundsB.minY
)
end
local function checkShipCollision(shipIndex)
local myBounds=getShipBounds(ships[shipIndex])
for i=1,#ships do
if i~=shipIndex and ships[i].pos then
if boundsIntersect(myBounds,getShipBounds(ships[i])) then
return i
end
end
end
return 0
end
local function randomizeShips()
for i=1,5 do
ships[i].pos=nil
end
for i=1,5 do
local ship=ships[i]
local dir
local x,y
repeat
--random orientation
dir=math.random(2)==1 and "v" or "h"
--random position
x = math.random(dir=="v" and 10 or (10-ship.size))
y = math.random(dir=="h" and 10 or (10-ship.size))
ship.pos={x,y}
ship.dir=dir
until checkShipCollision(i)==0
end
end
local function shipPlacement()
local selection=1
local collidesWith=0
local dragging=false
local moveShip=nil
local clickedOn=nil
local clickedAt=nil
doScreenColor()
term.setCursorPos(28,3)
write("use arrows to move ship")
term.setCursorPos(28,4)
write("press space to rotate")
term.setCursorPos(28,5)
write("tab selects next ship")
if term.isColor() then
term.setCursorPos(28,6)
write("click and drag ships")
term.setCursorPos(28,7)
write("right-click ship to")
term.setCursorPos(28,8)
write(" rotate")
end
term.setCursorPos(28,9)
write('"r" to randomize ships')
term.setCursorPos(28,10)
write('"f" when finished')
randomizeShips()
setStatusLine(1,"Arrange your ships on the grid")
while true do
--local placed=0
--draw sea
doColor(colors.white,colors.lightBlue)
for i=1,10 do
term.setCursorPos(3,3+i)
term.write(" ")
end
--draw ships
for i=1,#ships do
--draw ship at sea if it's placed
if ships[i].pos then
if collidesWith~=0 and (collidesWith==i or selection==i) then
doColor(selection==i and colors.red or colors.pink,colors.gray)
drawShip(ships[i].size,ships[i].dir,2+ships[i].pos[1],3+ships[i].pos[2],"@")
else
doColor(selection==i and colors.lime or colors.white,colors.gray)
drawShip(ships[i].size,ships[i].dir,2+ships[i].pos[1],3+ships[i].pos[2],"O")
end
end
end
local event,p1,p2,p3=os.pullEvent()
if event=="key" then
if not dragging then
if p1==keys.tab then
if collidesWith==0 then
selection=(selection%5)+1
else
local t=selection
selection=collidesWith
collidesWith=t
end
elseif p1==keys.up then
moveShip={0,-1}
elseif p1==keys.down then
moveShip={0,1}
elseif p1==keys.left then
moveShip={-1,0}
elseif p1==keys.right then
moveShip={1,0}
elseif p1==keys.space then
moveShip={0,0}
ships[selection].dir=ships[selection].dir=="h" and "v" or "h"
elseif p1==keys.f then
if collidesWith~=0 then
setStatusLine(2,"You can't finalize with ships overlapping!")
else
break
end
elseif p1==keys.r then
randomizeShips();
end
end
elseif event=="mouse_click" then
clickedOn=nil
--click event! figure out what we clicked on
local clickBounds=getPointBounds(p2,p3)
local clickGridBounds=getPointBounds(p2-2,p3-3)
for i=1,#ships do
if ships[i].pos and boundsIntersect(clickGridBounds,getShipBounds(ships[i])) and
(collidesWith==0 or collidesWith==i or i==selection) then
--select it
--if we're switching between the colliding ships, swap selection
if collidesWith~=0 and i~=selection then
collidesWith=selection
end
--mode="place"
clickedOn=ships[i]
clickedOffset={p2-2-ships[i].pos[1],p3-3-ships[i].pos[2]}
selection=i
break
--[[else
local labelBounds={minX=15,maxX=24,minY=2*i,maxY=1+2*i}
if boundsIntersect(clickBounds,labelBounds) and
(collidesWith==0 or collidesWith==i or i==selection) then
if collidesWith~=0 then
if i~=selection then
collidesWith=selection
end
else
mode="select"
end
clickedOn=ships[i]
clickedOffset={0,0}
selection=i
if ships[i].pos==nil then
ships[i].pos={1,1}
collidesWith=checkShipCollision(selection)
break
end
end--]]
end
end
if not clickedOn and collidesWith==0 and
boundsIntersect(clickBounds,{minX=15,maxX=22,minY=13,maxY=13}) then
break
elseif clickedOn and p1==2 then
--can't drag from a right-click!
clickedOn=nil
if ships[selection].dir=="h" then
ships[selection].dir="v"
moveShip={p2-2-ships[selection].pos[1],-(p2-2-ships[selection].pos[1])}
else
ships[selection].dir="h"
moveShip={p3-3-(ships[selection].pos[2]+ships[selection].size-1),p3-3-(ships[selection].pos[2])}
end
end
elseif event=="mouse_drag" and clickedOn~=nil then
--mode="place"
moveShip={
p2-2-clickedOffset[1]-ships[selection].pos[1],
p3-3-clickedOffset[2]-ships[selection].pos[2]}
end
if moveShip then
local curShip=ships[selection]
--calc position limits based on ship size and alignment
local maxX=curShip.dir=="h" and (11-curShip.size) or 10
local maxY=curShip.dir=="v" and (11-curShip.size) or 10
--apply move and clamp to limits
local newPos={
math.min(math.max(curShip.pos[1]+moveShip[1],1),maxX),
math.min(math.max(curShip.pos[2]+moveShip[2],1),maxY)
}
--place the ship
ships[selection].pos=newPos
--check for collisions with other ships
collidesWith=checkShipCollision(selection)
moveShip=nil
end
end
end
local function displayGameHelp()
doScreenColor()
term.setCursorPos(28,3)
write("arrows to move cursor")
term.setCursorPos(28,4)
write("space to fire")
if term.isColor() then
term.setCursorPos(28,6)
write("click on grid to fire")
end
end
local function hideHelpArea()
doScreenColor()
for y=3,13 do
term.setCursorPos(28,y)
write(string.rep(" ",32))
end
end
local function runGame()
--first, ship placement phase!!
shipPlacement()
hideHelpArea()
--hide the old help, draw the new
--tell the other guy we're done
rednet.send(opponentID,"bs ready")
if not opponentReady then
setStatusLine(1,"Waiting for opponent to finish placing ships")
while not opponentReady do
os.pullEvent()
end
end
--now, play the game
--draw my final ship positions intto the grid
drawShipsToGrid(ships,myGrid)
--if I'm host, flip a coin
if action=="host" then
math.randomseed(os.time())
myTurn=math.floor(100*math.random())%2==0
rednet.send(opponentID,"bs cointoss "..tostring(not myTurn))
if myTurn then
setStatusLine(2,"Your turn, take your shot!")
else
setStatusLine(2,"Opponent's turn, waiting...")
end
else
--I joined, wait for coin toss
setStatusLine(2,"waiting for coin toss...")
while myTurn==nil do
os.pullEvent()
end
end
setStatusLine(1,"")
if myTurn then
--I won, I go first
displayGameHelp()
end
--draw a target grid
drawGrid(2,2,myGrid)
drawGrid(15,2,oppGrid)
--initialize target indicators
moveTargetIndicator(5,5)
--game turn loop
while true do
--wait for my turn
while not myTurn do
os.pullEvent()
end
--my turn!
while true do
local e,p1,p2,p3,p4,p5=os.pullEvent()
if e=="mouse_click" then
local clickBounds=getPointBounds(p2,p3)
if boundsIntersect(clickBounds,targetGridBounds) then
moveTargetIndicator(p2-15,p3-3)
local shot=makeShot(targetX,targetY,oppGrid)
if shot then
--valid shot, tell the other guy
rednet.send(opponentID,"bs shot "..targetX.." "..targetY)
break
end
end
elseif e=="char" then
p1=string.lower(p1)
if p1>="a" and p1<="j" then
--row selected
moveTargetIndicator(targetX,string.byte(p1)-string.byte("a")+1)
elseif p1>="0" and p1<="9" then
local t=string.byte(p1)-string.byte("0")
if t==0 then t=10 end
moveTargetIndicator(t,targetY)
end
elseif e=="key" then
if p1==keys.enter or p1==keys.space and targetX and targetY then
local shot=makeShot(targetX,targetY,oppGrid)
if shot then
rednet.send(opponentID,"bs shot "..targetX.." "..targetY)
break
end
elseif p1==keys.up then
moveTargetIndicator(targetX,math.max(targetY-1,1))
elseif p1==keys.down then
moveTargetIndicator(targetX,math.min(targetY+1,10))
elseif p1==keys.left then
moveTargetIndicator(math.max(targetX-1,1),targetY)
elseif p1==keys.right then
moveTargetIndicator(math.min(targetX+1,10),targetY)
end
end
end
--shot sent, wait for my turn to resolve (top coroutine will switch turns and draw the hit to the grid)
setStatusLine(2,"Waiting for opponent...")
while myTurn do
os.pullEvent()
end
end
end
local gameRoutine=coroutine.create(runGame)
--if advanced terminal, default focus to chat, can play with mouse
local inChat=term.isColor()
local savedCursorPos={7,19}
--redirect just to block scroll
local redir={}
for k,v in pairs(originalTerm) do
if k~="scroll" then
redir[k]=v
else
redir[k]=function() end
end
end
originalTerm = term.redirect(redir)
--run the game routine once
coroutine.resume(gameRoutine)
--hide cursor
term.setCursorBlink(false)
while true do
local e,p1,p2,p3,p4,p5=os.pullEventRaw()
if e=="terminate" then
quit()
elseif e=="shipsunk" then
setStatusLine(1,opponent.." sank your "..ships[p1].name.."!")
rednet.send(opponentID,"bs sink")
shipsLeft=shipsLeft-1
if shipsLeft==1 then
setStatusLine(3,"You only have 1 ship left!")
elseif shipsLeft>1 then
setStatusLine(3,"You have "..shipsLeft.." ships left!")
else
rednet.send(opponentID,"bs win")
setStatusLine(3,"You lost the game!")
break
end
elseif e=="rednet_message" then
local cmd,args=string.match(p2,"^bs (%S+)%s?(.*)")
if cmd=="ready" then
opponentReady=true
os.queueEvent("kickcoroutine")
elseif cmd=="cointoss" then
myTurn=args=="true"
if myTurn then
setStatusLine(2,"Your turn, take your shot!")
else
setStatusLine(2,"Opponent's turn, waiting...")
end
os.queueEvent("kickcoroutine")
elseif cmd=="shot" then
if myTurn then
setStatusLine(3,"What the?! Got a shot but not their turn! Ignoring")
else
local tx, ty=string.match(args,"(%d+) (%d+)")
tx,ty=tonumber(tx),tonumber(ty)
local tile=myGrid[tx][ty]
local shot=makeShot(tx,ty,myGrid)
rednet.send(opponentID,"bs result "..(shot[3] and "hit" or "miss"))
drawTile(2+tx,3+ty,tile)
myTurn=true
os.queueEvent("kickcoroutine")
displayGameHelp()
setStatusLine(1,opponent.." fired at "..toGridRef(tx,ty).." and "..(shot[3] and "hit" or "missed"))
setStatusLine(2,"Your turn, take your shot!")
end
elseif cmd=="sink" then
setStatusLine(1,"You sank one of "..opponent.."'s ships!")
oppShipsLeft=oppShipsLeft-1
if oppShipsLeft==0 then
setStatusLine(2,opponent.." has no ships left!")
elseif oppShipsLeft==1 then
setStatusLine(2,"Sink 1 more to win!")
else
setStatusLine(2,"They have "..oppShipsLeft.." ships left.")
end
elseif cmd=="result" then
if not myTurn then
setStatusLine(3,"What the?! Got a shot result but not my turn! Ignoring")
else
local tile=oppGrid[targetX][targetY]
tile.hit=args=="hit"
drawTile(targetX+15,targetY+3,tile)
myTurn=false
doColor(tile.hit and colors.red or colors.white,colors.lightGray)
term.setCursorPos(17,16)
term.write(tile.hit and "HIT!" or "MISS")
setStatusLine(2,"Waiting for opponent...")
os.queueEvent("kickcoroutine")
end
elseif cmd=="win" then
--we won!
setStatusLine(3,"You won the game! Congratulations!")
break
end
--everything else goes to gameRoutine
else
--all other events go to this routine
local succ,err=coroutine.resume(gameRoutine,e,p1,p2,p3,p4,p5)
if not succ then
print("game coroutine crashed with the following error: "..err)
quit()
end
if coroutine.status(gameRoutine)=="dead" then
--game over
break
end
end
end
term.setCursorPos(1,19)
term.clearLine()
term.write(" Press any key to continue...")
os.pullEvent("key")
--if a char event was queued following the key event, this will eat it
os.sleep(0)
term.setTextColor(colors.white)
term.setBackgroundColor(colors.black)
term.clear()
quit()
--

Some files were not shown because too many files have changed in this diff Show More