From 34a17a9542aad4b2a35c13216b4ba3f57804f312 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Wed, 25 Sep 2019 08:50:40 -0400 Subject: [PATCH 01/19] add test file --- java/Example_v1.java => Example_v0.java | 0 antlr/R_v0.g | 420 - antlr/R_v1.g | 495 - c/hello_v0.c | 4 - c/hello_v1.c | 3 - c/patch_v0.c | 6 - c/patch_v1.c | 6 - c/saner_v0.c | 3 - c/saner_v1.c | 4 - c/tas_v0.c | 301 - c/tas_v1.c | 301 - java/Example_v0.java | 20 - java/MultiMapping_v0.java | 20 - java/MultiMapping_v1.java | 34 - java/cases/fluent_v0.java | 14 - java/cases/fluent_v1.java | 16 - java/cases/matrices_v0.java | 7 - java/cases/matrices_v1.java | 7 - java/cases/varargs_v0.java | 3 - java/cases/varargs_v1.java | 3 - .../cvsvintage/BoardView1_1.214_1.215_v0.java | 4253 ---- .../cvsvintage/BoardView1_1.214_1.215_v1.java | 4253 ---- .../IRMILocalContext_1.1_1.2_v0.java | 85 - .../IRMILocalContext_1.1_1.2_v1.java | 59 - java/cvsvintage/IndexWriter_1.2_1.3_v0.java | 401 - java/cvsvintage/IndexWriter_1.2_1.3_v1.java | 402 - java/cvsvintage/Install_1.9_1.10_v0.java | 121 - java/cvsvintage/Install_1.9_1.10_v1.java | 121 - .../IntrospectionUtils_1.1_1.2_v0.java | 99 - .../IntrospectionUtils_1.1_1.2_v1.java | 99 - .../JacORBPRODelegate_1.1_1.2_v0.java | 80 - .../JacORBPRODelegate_1.1_1.2_v1.java | 38 - .../MetricsInterceptor_1.18_1.19_v0.java | 333 - .../MetricsInterceptor_1.18_1.19_v1.java | 333 - .../MirrorListHandler_1.2_1.3_v0.java | 159 - .../MirrorListHandler_1.2_1.3_v1.java | 161 - java/cvsvintage/RQueryUser_1.1_1.2_v0.java | 15 - java/cvsvintage/RQueryUser_1.1_1.2_v1.java | 44 - .../SegmentTermDocs_1.6_1.7_v0.java | 231 - .../SegmentTermDocs_1.6_1.7_v1.java | 231 - java/cvsvintage/Server_1.925_1.926_v0.java | 18150 --------------- java/cvsvintage/Server_1.925_1.926_v1.java | 18151 ---------------- ...entStereotypeComboBoxModel_1.3_1.4_v0.java | 83 - ...entStereotypeComboBoxModel_1.3_1.4_v1.java | 85 - java/michal_v0.java | 37 - java/michal_v1.java | 36 - .../AlterTableAlterColumn_4076_4129_v0.java | 473 - .../AlterTableAlterColumn_4076_4129_v1.java | 487 - java/oldies/BasicClient_1018_1024_v0.java | 318 - java/oldies/BasicClient_1018_1024_v1.java | 315 - java/oldies/EPerm_v0.java | 9 - java/oldies/EPerm_v1.java | 9 - ...nventory_287c56f97631_5ff114b22264_v0.java | 728 - ...nventory_287c56f97631_5ff114b22264_v1.java | 773 - java/oldies/Perm_v0.java | 15 - java/oldies/Perm_v1.java | 14 - java/oldies/ResultsProducer_v0.java | 179 - java/oldies/ResultsProducer_v1.java | 212 - java/oldies/Slides_v0.java | 11 - java/oldies/Slides_v1.java | 16 - java/oldies/jnamed_1.68_1.69_v0.java | 700 - java/oldies/jnamed_1.68_1.69_v1.java | 698 - java/oldies/update_1.70_1.71_v0.java | 700 - java/oldies/update_1.70_1.71_v1.java | 697 - java/simple/AnnotationsTest.java | 18 - java/spl/notepad/Variant00001java/About.java | 25 - .../spl/notepad/Variant00001java/Actions.java | 468 - java/spl/notepad/Variant00001java/Center.java | 37 - .../Variant00001java/ExampleFileFilter.java | 307 - java/spl/notepad/Variant00001java/Fonts.java | 136 - .../spl/notepad/Variant00001java/Notepad.java | 305 - java/spl/notepad/Variant00001java/Print.java | 64 - java/spl/notepad/Variant00002java/About.java | 25 - .../spl/notepad/Variant00002java/Actions.java | 481 - java/spl/notepad/Variant00002java/Center.java | 37 - .../Variant00002java/ExampleFileFilter.java | 307 - java/spl/notepad/Variant00002java/Fonts.java | 136 - .../spl/notepad/Variant00002java/Notepad.java | 356 - java/spl/notepad/Variant00002java/Print.java | 64 - java/spl/notepad/Variant00003java/About.java | 25 - .../spl/notepad/Variant00003java/Actions.java | 497 - java/spl/notepad/Variant00003java/Center.java | 37 - .../Variant00003java/ExampleFileFilter.java | 307 - java/spl/notepad/Variant00003java/Fonts.java | 136 - .../spl/notepad/Variant00003java/Notepad.java | 342 - java/spl/notepad/Variant00003java/Print.java | 64 - java/spl/notepad/Variant00004java/About.java | 25 - .../spl/notepad/Variant00004java/Actions.java | 515 - java/spl/notepad/Variant00004java/Center.java | 37 - .../Variant00004java/ExampleFileFilter.java | 307 - java/spl/notepad/Variant00004java/Fonts.java | 136 - .../spl/notepad/Variant00004java/Notepad.java | 394 - java/spl/notepad/Variant00004java/Print.java | 64 - java/spl/notepad/Variant00005java/About.java | 25 - .../spl/notepad/Variant00005java/Actions.java | 468 - java/spl/notepad/Variant00005java/Center.java | 37 - .../Variant00005java/ExampleFileFilter.java | 307 - java/spl/notepad/Variant00005java/Fonts.java | 136 - .../spl/notepad/Variant00005java/Notepad.java | 336 - java/spl/notepad/Variant00005java/Print.java | 64 - .../notepad/Variant00005java/RedoAction.java | 50 - .../notepad/Variant00005java/UndoAction.java | 50 - java/spl/notepad/Variant00006java/About.java | 25 - .../spl/notepad/Variant00006java/Actions.java | 481 - java/spl/notepad/Variant00006java/Center.java | 37 - .../Variant00006java/ExampleFileFilter.java | 307 - java/spl/notepad/Variant00006java/Fonts.java | 136 - .../spl/notepad/Variant00006java/Notepad.java | 388 - java/spl/notepad/Variant00006java/Print.java | 64 - .../notepad/Variant00006java/RedoAction.java | 50 - .../notepad/Variant00006java/UndoAction.java | 50 - java/spl/notepad/Variant00007java/About.java | 25 - .../spl/notepad/Variant00007java/Actions.java | 497 - java/spl/notepad/Variant00007java/Center.java | 37 - .../Variant00007java/ExampleFileFilter.java | 307 - java/spl/notepad/Variant00007java/Fonts.java | 136 - .../spl/notepad/Variant00007java/Notepad.java | 373 - java/spl/notepad/Variant00007java/Print.java | 64 - .../notepad/Variant00007java/RedoAction.java | 50 - .../notepad/Variant00007java/UndoAction.java | 50 - java/spl/notepad/Variant00008java/About.java | 25 - .../spl/notepad/Variant00008java/Actions.java | 515 - java/spl/notepad/Variant00008java/Center.java | 37 - .../Variant00008java/ExampleFileFilter.java | 307 - java/spl/notepad/Variant00008java/Fonts.java | 136 - .../spl/notepad/Variant00008java/Notepad.java | 425 - java/spl/notepad/Variant00008java/Print.java | 64 - .../notepad/Variant00008java/RedoAction.java | 50 - .../notepad/Variant00008java/UndoAction.java | 50 - js/gumtree_v0.js | 90 - js/gumtree_v1.js | 91 - json/ast_v0.json | 32 - json/ast_v1.json | 32 - json/fullast_v0.json | 961 - json/fullast_v1.json | 961 - json/stack_v0.json | 510 - json/stack_v1.json | 505 - php/hashids_src.php | 307 - python/whois_v0.py | 5 - python/whois_v1.py | 8 - r/SSplotComps_r658_src.R | 981 - r/SSplotComps_r684_dst.R | 997 - r/TSCplot_r692_src.R | 77 - r/TSCplot_r693_dst.R | 86 - r/tableGrob_r167_src.R | 391 - r/tableGrob_r170_dst.R | 464 - ruby/diggit_cli_v0.rb | 327 - ruby/diggit_cli_v1.rb | 334 - xml/directory_v0.xml | 32 - xml/directory_v1.xml | 37 - 150 files changed, 75120 deletions(-) rename java/Example_v1.java => Example_v0.java (100%) delete mode 100644 antlr/R_v0.g delete mode 100644 antlr/R_v1.g delete mode 100644 c/hello_v0.c delete mode 100644 c/hello_v1.c delete mode 100644 c/patch_v0.c delete mode 100644 c/patch_v1.c delete mode 100644 c/saner_v0.c delete mode 100644 c/saner_v1.c delete mode 100644 c/tas_v0.c delete mode 100644 c/tas_v1.c delete mode 100644 java/Example_v0.java delete mode 100644 java/MultiMapping_v0.java delete mode 100644 java/MultiMapping_v1.java delete mode 100644 java/cases/fluent_v0.java delete mode 100644 java/cases/fluent_v1.java delete mode 100644 java/cases/matrices_v0.java delete mode 100644 java/cases/matrices_v1.java delete mode 100644 java/cases/varargs_v0.java delete mode 100644 java/cases/varargs_v1.java delete mode 100644 java/cvsvintage/BoardView1_1.214_1.215_v0.java delete mode 100644 java/cvsvintage/BoardView1_1.214_1.215_v1.java delete mode 100644 java/cvsvintage/IRMILocalContext_1.1_1.2_v0.java delete mode 100644 java/cvsvintage/IRMILocalContext_1.1_1.2_v1.java delete mode 100644 java/cvsvintage/IndexWriter_1.2_1.3_v0.java delete mode 100644 java/cvsvintage/IndexWriter_1.2_1.3_v1.java delete mode 100644 java/cvsvintage/Install_1.9_1.10_v0.java delete mode 100644 java/cvsvintage/Install_1.9_1.10_v1.java delete mode 100644 java/cvsvintage/IntrospectionUtils_1.1_1.2_v0.java delete mode 100644 java/cvsvintage/IntrospectionUtils_1.1_1.2_v1.java delete mode 100644 java/cvsvintage/JacORBPRODelegate_1.1_1.2_v0.java delete mode 100644 java/cvsvintage/JacORBPRODelegate_1.1_1.2_v1.java delete mode 100644 java/cvsvintage/MetricsInterceptor_1.18_1.19_v0.java delete mode 100644 java/cvsvintage/MetricsInterceptor_1.18_1.19_v1.java delete mode 100644 java/cvsvintage/MirrorListHandler_1.2_1.3_v0.java delete mode 100644 java/cvsvintage/MirrorListHandler_1.2_1.3_v1.java delete mode 100644 java/cvsvintage/RQueryUser_1.1_1.2_v0.java delete mode 100644 java/cvsvintage/RQueryUser_1.1_1.2_v1.java delete mode 100644 java/cvsvintage/SegmentTermDocs_1.6_1.7_v0.java delete mode 100644 java/cvsvintage/SegmentTermDocs_1.6_1.7_v1.java delete mode 100644 java/cvsvintage/Server_1.925_1.926_v0.java delete mode 100644 java/cvsvintage/Server_1.925_1.926_v1.java delete mode 100644 java/cvsvintage/UMLModelElementStereotypeComboBoxModel_1.3_1.4_v0.java delete mode 100644 java/cvsvintage/UMLModelElementStereotypeComboBoxModel_1.3_1.4_v1.java delete mode 100644 java/michal_v0.java delete mode 100644 java/michal_v1.java delete mode 100644 java/oldies/AlterTableAlterColumn_4076_4129_v0.java delete mode 100644 java/oldies/AlterTableAlterColumn_4076_4129_v1.java delete mode 100644 java/oldies/BasicClient_1018_1024_v0.java delete mode 100644 java/oldies/BasicClient_1018_1024_v1.java delete mode 100644 java/oldies/EPerm_v0.java delete mode 100644 java/oldies/EPerm_v1.java delete mode 100644 java/oldies/Inventory_287c56f97631_5ff114b22264_v0.java delete mode 100644 java/oldies/Inventory_287c56f97631_5ff114b22264_v1.java delete mode 100644 java/oldies/Perm_v0.java delete mode 100644 java/oldies/Perm_v1.java delete mode 100644 java/oldies/ResultsProducer_v0.java delete mode 100644 java/oldies/ResultsProducer_v1.java delete mode 100644 java/oldies/Slides_v0.java delete mode 100644 java/oldies/Slides_v1.java delete mode 100644 java/oldies/jnamed_1.68_1.69_v0.java delete mode 100644 java/oldies/jnamed_1.68_1.69_v1.java delete mode 100644 java/oldies/update_1.70_1.71_v0.java delete mode 100644 java/oldies/update_1.70_1.71_v1.java delete mode 100644 java/simple/AnnotationsTest.java delete mode 100644 java/spl/notepad/Variant00001java/About.java delete mode 100644 java/spl/notepad/Variant00001java/Actions.java delete mode 100644 java/spl/notepad/Variant00001java/Center.java delete mode 100644 java/spl/notepad/Variant00001java/ExampleFileFilter.java delete mode 100644 java/spl/notepad/Variant00001java/Fonts.java delete mode 100644 java/spl/notepad/Variant00001java/Notepad.java delete mode 100644 java/spl/notepad/Variant00001java/Print.java delete mode 100644 java/spl/notepad/Variant00002java/About.java delete mode 100644 java/spl/notepad/Variant00002java/Actions.java delete mode 100644 java/spl/notepad/Variant00002java/Center.java delete mode 100644 java/spl/notepad/Variant00002java/ExampleFileFilter.java delete mode 100644 java/spl/notepad/Variant00002java/Fonts.java delete mode 100644 java/spl/notepad/Variant00002java/Notepad.java delete mode 100644 java/spl/notepad/Variant00002java/Print.java delete mode 100644 java/spl/notepad/Variant00003java/About.java delete mode 100644 java/spl/notepad/Variant00003java/Actions.java delete mode 100644 java/spl/notepad/Variant00003java/Center.java delete mode 100644 java/spl/notepad/Variant00003java/ExampleFileFilter.java delete mode 100644 java/spl/notepad/Variant00003java/Fonts.java delete mode 100644 java/spl/notepad/Variant00003java/Notepad.java delete mode 100644 java/spl/notepad/Variant00003java/Print.java delete mode 100644 java/spl/notepad/Variant00004java/About.java delete mode 100644 java/spl/notepad/Variant00004java/Actions.java delete mode 100644 java/spl/notepad/Variant00004java/Center.java delete mode 100644 java/spl/notepad/Variant00004java/ExampleFileFilter.java delete mode 100644 java/spl/notepad/Variant00004java/Fonts.java delete mode 100644 java/spl/notepad/Variant00004java/Notepad.java delete mode 100644 java/spl/notepad/Variant00004java/Print.java delete mode 100644 java/spl/notepad/Variant00005java/About.java delete mode 100644 java/spl/notepad/Variant00005java/Actions.java delete mode 100644 java/spl/notepad/Variant00005java/Center.java delete mode 100644 java/spl/notepad/Variant00005java/ExampleFileFilter.java delete mode 100644 java/spl/notepad/Variant00005java/Fonts.java delete mode 100644 java/spl/notepad/Variant00005java/Notepad.java delete mode 100644 java/spl/notepad/Variant00005java/Print.java delete mode 100644 java/spl/notepad/Variant00005java/RedoAction.java delete mode 100644 java/spl/notepad/Variant00005java/UndoAction.java delete mode 100644 java/spl/notepad/Variant00006java/About.java delete mode 100644 java/spl/notepad/Variant00006java/Actions.java delete mode 100644 java/spl/notepad/Variant00006java/Center.java delete mode 100644 java/spl/notepad/Variant00006java/ExampleFileFilter.java delete mode 100644 java/spl/notepad/Variant00006java/Fonts.java delete mode 100644 java/spl/notepad/Variant00006java/Notepad.java delete mode 100644 java/spl/notepad/Variant00006java/Print.java delete mode 100644 java/spl/notepad/Variant00006java/RedoAction.java delete mode 100644 java/spl/notepad/Variant00006java/UndoAction.java delete mode 100644 java/spl/notepad/Variant00007java/About.java delete mode 100644 java/spl/notepad/Variant00007java/Actions.java delete mode 100644 java/spl/notepad/Variant00007java/Center.java delete mode 100644 java/spl/notepad/Variant00007java/ExampleFileFilter.java delete mode 100644 java/spl/notepad/Variant00007java/Fonts.java delete mode 100644 java/spl/notepad/Variant00007java/Notepad.java delete mode 100644 java/spl/notepad/Variant00007java/Print.java delete mode 100644 java/spl/notepad/Variant00007java/RedoAction.java delete mode 100644 java/spl/notepad/Variant00007java/UndoAction.java delete mode 100644 java/spl/notepad/Variant00008java/About.java delete mode 100644 java/spl/notepad/Variant00008java/Actions.java delete mode 100644 java/spl/notepad/Variant00008java/Center.java delete mode 100644 java/spl/notepad/Variant00008java/ExampleFileFilter.java delete mode 100644 java/spl/notepad/Variant00008java/Fonts.java delete mode 100644 java/spl/notepad/Variant00008java/Notepad.java delete mode 100644 java/spl/notepad/Variant00008java/Print.java delete mode 100644 java/spl/notepad/Variant00008java/RedoAction.java delete mode 100644 java/spl/notepad/Variant00008java/UndoAction.java delete mode 100644 js/gumtree_v0.js delete mode 100644 js/gumtree_v1.js delete mode 100644 json/ast_v0.json delete mode 100644 json/ast_v1.json delete mode 100644 json/fullast_v0.json delete mode 100644 json/fullast_v1.json delete mode 100644 json/stack_v0.json delete mode 100644 json/stack_v1.json delete mode 100644 php/hashids_src.php delete mode 100644 python/whois_v0.py delete mode 100644 python/whois_v1.py delete mode 100644 r/SSplotComps_r658_src.R delete mode 100644 r/SSplotComps_r684_dst.R delete mode 100644 r/TSCplot_r692_src.R delete mode 100644 r/TSCplot_r693_dst.R delete mode 100644 r/tableGrob_r167_src.R delete mode 100644 r/tableGrob_r170_dst.R delete mode 100644 ruby/diggit_cli_v0.rb delete mode 100644 ruby/diggit_cli_v1.rb delete mode 100644 xml/directory_v0.xml delete mode 100644 xml/directory_v1.xml diff --git a/java/Example_v1.java b/Example_v0.java similarity index 100% rename from java/Example_v1.java rename to Example_v0.java diff --git a/antlr/R_v0.g b/antlr/R_v0.g deleted file mode 100644 index 5acda70..0000000 --- a/antlr/R_v0.g +++ /dev/null @@ -1,420 +0,0 @@ -grammar R; - -options { - output = AST; - language = Java ; - ASTLabelType = CommonTree; - memoize = true; // This is FUCK** important because of `if` -} - -tokens { - CALL; - BRAKET; - KW; - PARMS; - SEQUENCE; - //NULL; - MISSING_VAL; - UPLUS; - UMINUS; - UTILDE; - } - -@header { package fr.labri.gumtree.gen.r; } -@lexer::header { package fr.labri.gumtree.gen.r; } -@rulecatch { - catch(RecognitionException re){ - throw re; // Stop at first error - } -} -@lexer::rulecatch { - catch(RecognitionException re){ - throw re; // Stop at first error ??? Doesn't work at all ??? why ?? - } -} -@members { - public void display_next_tokens(){ - System.err.print("Allowed tokens: "); - for(int next: next_tokens()) - System.err.print(tokenNames[next]); - System.err.println(""); - } - public int[] next_tokens(){ - return state.following[state._fsp].toArray(); - } -} - -@lexer::members{ - int incomplete_stack[] = new int[100]; // MAX_SIZE ??? - int incomplete_depth = 0; - @Override - public void reportError(RecognitionException e) { - throw new RuntimeException(e); - } -} -@lexer::init{ - incomplete_stack[incomplete_depth] = 0; -} - -/**************************************************** -** Known errors : -** - foo * if(...) ... because of priority -** - No help support '?' & '??' -** - %OP% not very robust, maybe allow everything -** - More than 3x '.' are handled like ... -** - '.' is a valid id -** - Line break are tolerated in strings even without a '\' !!! (ugly) -** - EOF does'nt work with unbalanced structs -** - Improve the stack of balanced structures -** -** - Must add NA values ... -*****************************************************/ -script - : n_ statement* -> ^(SEQUENCE statement*) - ; -interactive - : n_! statement - ; -statement - : expr_or_assign n! - | '--EOF--' .* EOF -> // Stop processing of a file (non std) - ; - -n_ : (NEWLINE | COMMENT)*; -n : (NEWLINE | COMMENT)+ | EOF | SEMICOLUMN n_; - -expr_or_assign - : alter_assign -// | expr_wo_assign - ; -expr - : assign -// | expr_wo_assign - ; -expr_wo_assign - : while_expr - | if_expr - | for_expr - | repeat_expr - | function - | NEXT (LPAR n_ RPAR)? -> NEXT - | BREAK (LPAR n_ RPAR)? -> BREAK - ; -sequence - : lbb=LBRACE n_ (e+=expr_or_assign (n e+=expr_or_assign)* n?)? RBRACE -> ^(SEQUENCE[lbb] $e*) - ; -// $ ^(ARROW $l $r) - | SUPER_ARROW n_ r=expr -> ^(SUPER_ARROW $l $r) - | a=RIGHT_ARROW n_ r=expr -> ^(ARROW[$a] $r $l) - | a=SUPER_RIGHT_ARROW n_ r=expr -> ^(SUPER_ARROW[$a] $r $l) - | -> $l - ) - ; -alter_assign - : l=tilde_expr - ( ARROW n_ r=expr_or_assign -> ^(ARROW $l $r) - | SUPER_ARROW n_ r=expr_or_assign -> ^(SUPER_ARROW $l $r) - | a=RIGHT_ARROW n_ r=expr_or_assign -> ^(ARROW[$a] $r $l) - | a=SUPER_RIGHT_ARROW n_ r=expr_or_assign -> ^(SUPER_ARROW[$a] $r $l) - | a=ASSIGN n_ r=expr_or_assign -> ^(ARROW[$a] $l $r) - | -> $l - ) - ; -// $> -if_expr - : - IF n_ LPAR n_ cond=expr_or_assign n_ RPAR n_ t=expr_or_assign - /*(n_ ELSE)=>*/( - options {greedy=false; backtrack = true;}: - n_ ELSE n_ f=expr_or_assign - )? - -> ^(IF $cond $t $f?) - ; -// $ ^(WHILE $c $body) - ; -for_expr - : FOR n_ LPAR n_ ID n_ IN n_ in=expr_or_assign n_ RPAR n_ body=expr_or_assign -> ^(FOR ID $in $body) - ; -repeat_expr - : REPEAT n_ body=expr_or_assign -> ^(REPEAT $body) - ; -// $> - -function - : FUNCTION n_ LPAR n_ (par_decl (n_ COMMA n_ par_decl)* n_)? RPAR n_ body=expr_or_assign -> ^(FUNCTION par_decl* $body) - ; -par_decl - : iid=ID -> ^(ID NULL[iid]) - | ID n_ ASSIGN n_ expr -> ^(ID expr) - | VARIATIC -> VARIATIC - ; -tilde_expr - : or_expr (TILDE^ n_! or_expr)* - ; -or_expr - : and_expr (or_operator^ n_! and_expr)* - ; -and_expr - : comp_expr (and_operator^ n_! comp_expr)* - ; -comp_expr - : add_expr (comp_operator^ n_! add_expr)* - ; -add_expr - : mult_expr (add_operator^ n_! mult_expr)* - ; -mult_expr - : operator_expr (mult_operator^ n_! operator_expr)* - ; -operator_expr - : column_expr (OP^ n_! column_expr)* - ; -column_expr - : power_expr (COLUMN^ n_! power_expr)* - ; -power_expr - : l=unary_expression (power_operator^ n_! r=unary_expression)* // buggy l'associativite est a droite (?) - ; -unary_expression - : NOT n_ unary_expression -> ^(NOT unary_expression) - | pl=PLUS n_ unary_expression -> ^(UPLUS[pl] unary_expression) - | m=MINUS n_ unary_expression -> ^(UMINUS[m] unary_expression) - | t=TILDE n_ unary_expression -> ^(UTILDE[t] unary_expression) - | basic_expr - ; -basic_expr - : (lhs=simple_expr -> $lhs) - ( (FIELD n_ name=id) -> ^(FIELD $basic_expr $name) - | (AT n_ name=id) -> ^(AT $basic_expr $name) - | (LBRAKET subscript=expr_list RBRAKET) -> ^(BRAKET[lhs.start] $basic_expr $subscript?) - | (LBB subscript=expr_list RBRAKET RBRAKET) -> ^(LBB $basic_expr $subscript?) - // Must use RBRAKET instead of RBB beacause of : a[b[1]] - | (LPAR a=args RPAR) -> ^(CALL[lhs.start] $basic_expr $a?) - )* - ; -simple_expr - : id - | bool - | DD - | NULL - | NUMBER - | id NS_GET^ n_! id - | id NS_GET_INT^ n_! id - | LPAR! n_! expr_or_assign n_! RPAR! - | sequence - | expr_wo_assign - ; -id : ID | STRING | VARIATIC; -bool: TRUE | FALSE; -or_operator - : OR | BITWISEOR; -and_operator - : AND | BITWISEAND; -comp_operator - : GT | GE | LT | LE | EQ | NE; -add_operator - : PLUS | MINUS; -mult_operator - : MULT | DIV | MOD; -power_operator - : CARRET - ; -expr_list - : (n_ expr_list_arg)? n_ (COMMA (n_ expr_list_arg)? n_)* -> expr_list_arg* - ; -expr_list_arg - : expr -> expr - | name=id n_ ASSIGN n_ v=expr -> ^(KW[name.start] $name $v) - ; -args: (n_ arg_expr)? n_ (COMMA (n_ arg_expr)? n_)* -> arg_expr* - ; -arg_expr - : expr -> expr - | name=id n_ ASSIGN n_ v=expr -> ^(KW[name.start] $name $v) - | name=id n_ ass=ASSIGN -> ^(KW[name.start] $name NULL[ass]) //FIXME - | nn=NULL n_ ASSIGN n_ v=expr -> ^(KW[nn] $nn $v) - | nnn=NULL n_ ASSIGN -> ^(KW[nnn] $nnn $nnn) //FIXME - ; -/////////////////////////////////////////////////////////////////////////////// -/// Lexer -/// -COMMENT - : '#' ~('\n'|'\r'|'\f')* (LINE_BREAK | EOF) { if(incomplete_stack[incomplete_depth]>0) $channel=HIDDEN; } - ; -ARROW - : '<-' | ':=' - ; -SUPER_ARROW - : '<<-' ; -RIGHT_ARROW - : '->' - ; -SUPER_RIGHT_ARROW - : '->>' - ; -VARIATIC - : '..' '.'+ - ; // FIXME -EQ : '=='; -NE : '!='; -GE : '>='; -LE : '<='; -GT : '>'; -LT : '<'; -ASSIGN - : '='; - - -NS_GET_INT - : ':::'; -NS_GET - : '::'; - -COLUMN - : ':'; -SEMICOLUMN - : ';'; -COMMA - : ','; -AND - : '&&'; -BITWISEAND - : '&'; -OR : '||'; -BITWISEOR - :'|'; -LBRACE - : '{' {incomplete_stack[++incomplete_depth] = 0;}; // TODO grow the stack -RBRACE - : '}' {incomplete_depth -- ;}; -LPAR - : '(' { incomplete_stack[incomplete_depth] ++; }; -RPAR - : ')' { incomplete_stack[incomplete_depth]--; }; -LBB - : '[[' { incomplete_stack[incomplete_depth] += 2; }; // Must increase by two beacause of ']'']' used for closing -LBRAKET - : '[' { incomplete_stack[incomplete_depth] ++; }; -RBRAKET - : ']' { incomplete_stack[incomplete_depth] --;}; -CARRET - : '^' | '**'; -TILDE - : '~' ; -MOD - : '%%' ; - -NOT - : '!'; -PLUS - : '+'; -MULT - : '*'; -DIV : '/'; -MINUS - : '-'; - -FIELD - : '$'; -AT : '@'; - -FUNCTION - : 'function'; -NULL - : 'NULL'; - -TRUE - : 'TRUE'; -FALSE - : 'FALSE'; - -WHILE - : 'while'; -FOR : 'for'; -REPEAT - : 'repeat'; -IN : 'in'; -IF : 'if'; -ELSE - : 'else'; -NEXT - : 'next'; -BREAK - : 'break'; -// ? - -WS : ( ' ' - | '\t' - ) {$channel=HIDDEN;} - ; -NEWLINE - : LINE_BREAK { if(incomplete_stack[incomplete_depth]>0) $channel=HIDDEN; }; -NUMBER - : ('0'..'9')+ '.' ('0'..'9')* EXPONENT? ('i'|'L')? - | '.'? ('0'..'9')+ EXPONENT? ('i'|'L')? - | '0x' HEX_DIGIT+ 'L'? - ; -DD : '..' ('0'..'9')+ - ; -ID : '.'* ID_NAME - | '.' - | '`' ( ESC_SEQ | ~('\\'|'`') )* '`' {setText(getText().substring(1, getText().length()-1));} - ; -OP : '%' OP_NAME+ '%' - ; -STRING - : - ( '"' ( ESC_SEQ | ~('\\'|'"') )* '"' - | '\'' ( ESC_SEQ | ~('\\'|'\'') )* '\'' - ) {setText(getText().substring(1, getText().length()-1));} - ; -fragment -LINE_BREAK - : - (('\f'|'\r')? '\n') - | ('\n'? ('\r'|'\f')) // This rule fix very old Mac/Dos/Windows encoded files - ; -fragment -EXPONENT - : ('e'|'E') ('+'|'-')? ('0'..'9')+ - ; -fragment -OP_NAME - : ID_NAME - | ('*'|'/'|'+'|'-'|'>'|'<'|'='|'|'|'&'|':'|'^'|'.'|'~'|',') - ; -fragment -ID_NAME - : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'.')* - ; -fragment -ESC_SEQ - : '\\' ('b'|'t'|'n'|'f'|'r'|'"'|'\''|'`'|'\\'|' '|'a'|'v') - | '\\' LINE_BREAK // FIXME that's an ugly way to fix this - | UNICODE_ESC - | OCTAL_ESC - | HEX_ESC - ; -fragment -UNICODE_ESC - : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT - ; -fragment -HEX_ESC - : '\\x' HEX_DIGIT HEX_DIGIT? - ; -fragment -HEX_DIGIT - : ('0'..'9'|'a'..'f'|'A'..'F') - ; -fragment -OCTAL_ESC - : '\\' ('0'..'3') ('0'..'7') ('0'..'7') - | '\\' ('0'..'7') ('0'..'7') - | '\\' ('0'..'7') - ; diff --git a/antlr/R_v1.g b/antlr/R_v1.g deleted file mode 100644 index 3ede0de..0000000 --- a/antlr/R_v1.g +++ /dev/null @@ -1,495 +0,0 @@ -grammar R; - -options { - language = Java ; - memoize = true; -} - -tokens { - CALL; - BRAKET; - KW; - PARMS; - SEQUENCE; - //NULL; - MISSING_VAL; - UPLUS; - UMINUS; - UTILDE; - } - -@header { -package r.parser; - -import r.*; -import r.data.*; -import r.nodes.*; -import r.nodes.Call.*; -import r.nodes.UnaryOperation.*; -import r.nodes.BinaryOperation.*; -//Checkstyle: stop -} -@lexer::header { -package r.parser; -//Checkstyle: stop -} -@rulecatch { - catch(RecognitionException re){ - throw re; // Stop at first error - } -} -@lexer::rulecatch { - catch(RecognitionException re){ - throw re; // Stop at first error ??? Doesn't work at all ??? why ?? - } -} - -@lexer::members{ - public final int MAX_INCOMPLETE_SIZE = 1000; - int incomplete_stack[] = new int[MAX_INCOMPLETE_SIZE]; // TODO probably go for an ArrayList of int - int incomplete_depth; - - @Override - public void reportError(RecognitionException e) { - throw new RuntimeException(e); - } -} -@lexer::init{ - incomplete_depth = 0; - incomplete_stack[incomplete_depth] = 0; -} - -/**************************************************** -** Known errors : -** - No help support '?' & '??' -** - %OP% not very robust, maybe allow everything -** - '.' is a valid id -*****************************************************/ - -script - : n_ (statement )* - ; -interactive - : n_ (statement )* - ; -statement - : expr_or_assign n - | '--EOF--' .* EOF - ; - -n_ : (NEWLINE | COMMENT)*; -n : (NEWLINE | COMMENT)+ | EOF | SEMICOLON n_; - -expr_or_assign - : alter_assign - ; -expr - : assign - ; -expr_wo_assign - : while_expr - | if_expr - | for_expr - | repeat_expr - | function - | NEXT /* ((LPAR)=>LPAR n_ RPAR)? */ - | BREAK /* ((LPAR)=>LPAR n_ RPAR)? */ - ; -sequence - : LBRACE n_ (expr_or_assign (n expr_or_assign )* n?)? RBRACE - ; -assign - : tilde_expr - ( ARROW n_ expr - | SUPER_ARROW n_ expr - | RIGHT_ARROW n_ expr - | SUPER_RIGHT_ARROW n_ expr - | - ) - ; -alter_assign - : tilde_expr - ( (ARROW)=>ARROW n_ expr_or_assign - | (SUPER_ARROW)=>SUPER_ARROW n_ expr_or_assign - | (RIGHT_ARROW)=>RIGHT_ARROW n_ expr_or_assign - | (SUPER_RIGHT_ARROW)=>SUPER_RIGHT_ARROW n_ expr_or_assign - | (ASSIGN)=>ASSIGN n_ expr_or_assign - | - ) - ; -if_expr - : - IF n_ LPAR n_ expr_or_assign n_ RPAR n_ expr_or_assign - ((n_ ELSE)=>(options {greedy=false; backtrack=true;}: n_ ELSE n_ expr_or_assign ) - | - ) - ; -while_expr - : WHILE n_ LPAR n_ expr_or_assign n_ RPAR n_ expr_or_assign - ; -for_expr - : FOR n_ LPAR n_ ID n_ IN n_ expr_or_assign n_ RPAR n_ expr_or_assign - ; -repeat_expr - : REPEAT n_ expr_or_assign - ; -function - : FUNCTION n_ LPAR n_ (par_decl (n_ COMMA n_ par_decl)* n_)? RPAR n_ expr_or_assign - ; -par_decl - : ID - | ID n_ ASSIGN n_ expr - | VARIATIC // FIXME This is not quite good, since `...` is a special token - // For this reason let's call RSymbol.xxxx(...) - // This 3 cases were not handled ... and everything was working fine - // I add them for completeness, however note that the function create - // with such a signature will always fail if they try to access them ! - | VARIATIC n_ ASSIGN n_ expr - | DD - | DD n_ ASSIGN n_ expr - ; -tilde_expr - : utilde_expr - ( ((TILDE)=>TILDE n_ utilde_expr ))* - ; -utilde_expr - : TILDE n_ or_expr - | or_expr ; -or_expr - : and_expr - (((or_operator)=>or_operator n_ and_expr ))* - ; -and_expr - : not_expr - (((and_operator)=>and_operator n_ not_expr ))* - ; -not_expr - : NOT n_ not_expr - | comp_expr - ; -comp_expr - : add_expr - (((comp_operator)=>comp_operator n_ add_expr ))* - ; -add_expr - : mult_expr - (((add_operator)=>add_operator n_ mult_expr ))* - ; -mult_expr - : operator_expr - (((mult_operator)=>mult_operator n_ operator_expr ))* - ; -operator_expr - : colon_expr - (((OP)=>OP n_ colon_expr ))* /* FIXME BinaryOperation.create(op, $operator_expr.v, $r.v); */ - ; -colon_expr - : unary_expression - (((COLON)=>COLON n_ unary_expression ))* - ; -unary_expression - : PLUS n_ unary_expression - | MINUS n_ unary_expression - | power_expr - ; -power_expr - : basic_expr - (((power_operator)=>power_operator n_ power_expr ) - |) - ; -basic_expr - : simple_expr - (((FIELD|AT|LBRAKET|LBB|LPAR)=>expr_subset )+ | (n_)=>) - ; -expr_subset - : (FIELD n_ id) - | (AT n_ id) - | (LBRAKET args RBRAKET) - | (LBB args RBRAKET RBRAKET) - // Must use RBRAKET in`stead of RBB beacause of : a[b[1]] - | (LPAR args RPAR) - //| - ; -simple_expr - : id - | bool - | DD - | NULL - | number - | conststring - | id NS_GET n_ id - | id NS_GET_INT n_ id - | LPAR n_ expr_or_assign n_ RPAR - | sequence - | expr_wo_assign - ; -number - : INTEGER - | DOUBLE - | COMPLEX - ; -conststring - : STRING - ; -id - : ID - | VARIATIC - ; -bool - : TRUE - | FALSE - | NA - ; -or_operator - : OR - | BITWISEOR ; -and_operator - : AND - | BITWISEAND ; -comp_operator - : GT - | GE - | LT - | LE - | EQ - | NE ; -add_operator - : PLUS - | MINUS ; -mult_operator - : MULT - | MAT_MULT - | DIV - | MOD ; -power_operator - : CARRET - ; -args - : (n_ arg_expr)? n_ (COMMA ( | n_ arg_expr) n_)* - ; -arg_expr - : expr - | id n_ ASSIGN n_ expr - | id n_ ASSIGN - | NULL n_ ASSIGN n_ expr - | NULL n_ ASSIGN - ; -/////////////////////////////////////////////////////////////////////////////// -/// Lexer -/// -COMMENT - : '#' ~('\n'|'\r'|'\f')* (LINE_BREAK | EOF) { if(incomplete_stack[incomplete_depth]>0) $channel=HIDDEN; } - ; -ARROW - : '<-' | ':=' - ; -SUPER_ARROW - : '<<-' ; -RIGHT_ARROW - : '->' - ; -SUPER_RIGHT_ARROW - : '->>' - ; -VARIATIC - : '..' '.'+ - ; // FIXME -EQ : '=='; -NE : '!='; -GE : '>='; -LE : '<='; -GT : '>'; -LT : '<'; -ASSIGN - : '='; - - -NS_GET_INT - : ':::'; -NS_GET - : '::'; - -COLON - : ':'; -SEMICOLON - : ';'; -COMMA - : ','; -AND - : '&&'; -BITWISEAND - : '&'; -OR : '||'; -BITWISEOR - :'|'; -LBRACE - : '{' {incomplete_stack[++incomplete_depth] = 0; }; // TODO grow the stack -RBRACE - : '}' {incomplete_depth -- ;}; -LPAR - : '(' { incomplete_stack[incomplete_depth] ++; }; -RPAR - : ')' { incomplete_stack[incomplete_depth]--; }; -LBB - : '[[' { incomplete_stack[incomplete_depth] += 2; }; // Must increase by two beacause of ']'']' used for closing -LBRAKET - : '[' { incomplete_stack[incomplete_depth] ++; }; -RBRAKET - : ']' { incomplete_stack[incomplete_depth] --;}; -CARRET - : '^' | '**'; -TILDE - : '~' ; -MOD - : '%%' ; - -NOT - : '!'; -PLUS - : '+'; -MULT - : '*'; -MAT_MULT - : '%*%'; - -DIV : '/'; -MINUS - : '-'; - -FIELD - : '$'; -AT : '@'; - -FUNCTION - : 'function'; -NULL - : 'NULL'; - -NA - : 'NA'; -TRUE - : 'TRUE'; -FALSE - : 'FALSE'; - -WHILE - : 'while'; -FOR : 'for'; -REPEAT - : 'repeat'; -IN : 'in'; -IF : 'if'; -ELSE - : 'else'; -NEXT - : 'next'; -BREAK - : 'break'; -// ? - -WS : ( ' ' - | '\t' - ) {$channel=HIDDEN;} - ; -NEWLINE - : LINE_BREAK { if(incomplete_stack[incomplete_depth]>0) $channel=HIDDEN; }; -INTEGER - : ('0'..'9')+ '.' ('0'..'9')* 'L' - | '.'? ('0'..'9')+ EXPONENT? 'L' - | '0x' HEX_DIGIT+ 'L' - ; -COMPLEX - : ('0'..'9')+ '.' ('0'..'9')* EXPONENT? 'i' - | '.'? ('0'..'9')+ EXPONENT? 'i' - | '0x' HEX_DIGIT 'i' - ; -DOUBLE - : ('0'..'9')+ '.' ('0'..'9')* EXPONENT? - | '.'? ('0'..'9')+ EXPONENT? - | '0x' HEX_DIGIT - ; -DD : '..' ('0'..'9')+ - ; -ID : '.'* ID_NAME - | '.' - | '`' ( ESC_SEQ | ~('\\'|'`') )* '`' - ; -OP : '%' OP_NAME+ '%' - ; -/* -STRING - : - ( '"' ( ESC_SEQ | ~('\\'|'"') )* '"' - | '\'' ( ESC_SEQ | ~('\\'|'\'') )* '\'' - ) {setText(getText().substring(1, getText().length()-1));} - ; -*/ -STRING -: - '"' - ( - ESCAPE - | ~( '\\' | '"' ) - )* - '"' - ; - -/* not supporting \v and \a */ -fragment ESCAPE : - '\\' - ( 't' - | 'n' - | 'r' - | 'b' - | 'f' - | '"' - | '\\' - | 'x' HEX_DIGIT HEX_DIGIT - | 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT - | 'U' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT - ); -fragment -LINE_BREAK - : - (('\f'|'\r')? '\n') - | ('\n'? ('\r'|'\f')) // This rule fix very old Mac/Dos/Windows encoded files - ; -fragment -EXPONENT - : ('e'|'E') ('+'|'-')? ('0'..'9')+ - ; -fragment -OP_NAME - : ID_NAME - | ('*'|'/'|'+'|'-'|'>'|'<'|'='|'|'|'&'|':'|'^'|'.'|'~'|',') - ; -fragment -ID_NAME - : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'.')* - ; -fragment -ESC_SEQ - : '\\' ('b'|'t'|'n'|'f'|'r'|'"'|'\''|'`'|'\\'|' '|'a'|'v') - | '\\' LINE_BREAK // FIXME that's an ugly way to fix this - | UNICODE_ESC - | OCTAL_ESC - | HEX_ESC - ; -fragment -UNICODE_ESC - : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT - ; -fragment -HEX_ESC - : '\\x' HEX_DIGIT HEX_DIGIT? - ; -fragment -HEX_DIGIT - : ('0'..'9'|'a'..'f'|'A'..'F') - ; -fragment -OCTAL_ESC - : '\\' ('0'..'3') ('0'..'7') ('0'..'7') - | '\\' ('0'..'7') ('0'..'7') - | '\\' ('0'..'7') - ; diff --git a/c/hello_v0.c b/c/hello_v0.c deleted file mode 100644 index 30d1728..0000000 --- a/c/hello_v0.c +++ /dev/null @@ -1,4 +0,0 @@ -void main() { - int i; - return 0; -} diff --git a/c/hello_v1.c b/c/hello_v1.c deleted file mode 100644 index 448d5fa..0000000 --- a/c/hello_v1.c +++ /dev/null @@ -1,3 +0,0 @@ -void main() { - return 0; -} diff --git a/c/patch_v0.c b/c/patch_v0.c deleted file mode 100644 index c94c71d..0000000 --- a/c/patch_v0.c +++ /dev/null @@ -1,6 +0,0 @@ -void main() { - int a = 0; - int b = 0; - if (a > b) - return; -} diff --git a/c/patch_v1.c b/c/patch_v1.c deleted file mode 100644 index ab26f6c..0000000 --- a/c/patch_v1.c +++ /dev/null @@ -1,6 +0,0 @@ -void main() { - int a = 0; - int b = 0; - if (a < b) - return; -} diff --git a/c/saner_v0.c b/c/saner_v0.c deleted file mode 100644 index 1bb21f3..0000000 --- a/c/saner_v0.c +++ /dev/null @@ -1,3 +0,0 @@ -x = 37; -if (y) - x = 0; \ No newline at end of file diff --git a/c/saner_v1.c b/c/saner_v1.c deleted file mode 100644 index 929bf56..0000000 --- a/c/saner_v1.c +++ /dev/null @@ -1,4 +0,0 @@ -if (y) - x = 0 -else - x = 37 diff --git a/c/tas_v0.c b/c/tas_v0.c deleted file mode 100644 index f4dd305..0000000 --- a/c/tas_v0.c +++ /dev/null @@ -1,301 +0,0 @@ -#include "tas3004.h" -#include "tas_eq_prefs.h" - -static struct tas_drce_t eqp_17_1_0_drce={ - enable: 1, - above: { val: 3.0 * (1<<8), expand: 0 }, - below: { val: 1.0 * (1<<8), expand: 0 }, - threshold: -19.12 * (1<<8), - energy: 2.4 * (1<<12), - attack: 0.013 * (1<<12), - decay: 0.212 * (1<<12), -}; - -static struct tas_biquad_ctrl_t eqp_17_1_0_biquads[]={ - { channel: 0, filter: 0, data: { coeff: { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } }, - { channel: 0, filter: 1, data: { coeff: { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } }, - { channel: 0, filter: 2, data: { coeff: { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } }, - { channel: 0, filter: 3, data: { coeff: { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } }, - { channel: 0, filter: 4, data: { coeff: { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } }, - { channel: 0, filter: 5, data: { coeff: { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } }, - { channel: 0, filter: 6, data: { coeff: { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } }, - - { channel: 1, filter: 0, data: { coeff: { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } }, - { channel: 1, filter: 1, data: { coeff: { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } }, - { channel: 1, filter: 2, data: { coeff: { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } }, - { channel: 1, filter: 3, data: { coeff: { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } }, - { channel: 1, filter: 4, data: { coeff: { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } }, - { channel: 1, filter: 5, data: { coeff: { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } }, - { channel: 1, filter: 6, data: { coeff: { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } } -}; - -static struct tas_eq_pref_t eqp_17_1_0 = { - sample_rate: 44100, - device_id: 0x17, - output_id: TAS_OUTPUT_INTERNAL_SPKR, - speaker_id: 0x00, - - drce: &eqp_17_1_0_drce, - - filter_count: 14, - biquads: eqp_17_1_0_biquads -}; - -/* ======================================================================== */ - -static struct tas_drce_t eqp_18_1_0_drce={ - enable: 1, - above: { val: 3.0 * (1<<8), expand: 0 }, - below: { val: 1.0 * (1<<8), expand: 0 }, - threshold: -13.14 * (1<<8), - energy: 2.4 * (1<<12), - attack: 0.013 * (1<<12), - decay: 0.212 * (1<<12), -}; - -static struct tas_biquad_ctrl_t eqp_18_1_0_biquads[]={ - { channel: 0, filter: 0, data: { coeff: { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } }, - { channel: 0, filter: 1, data: { coeff: { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } }, - { channel: 0, filter: 2, data: { coeff: { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } }, - { channel: 0, filter: 3, data: { coeff: { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } }, - { channel: 0, filter: 4, data: { coeff: { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } }, - { channel: 0, filter: 5, data: { coeff: { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } }, - { channel: 0, filter: 6, data: { coeff: { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }, - - { channel: 1, filter: 0, data: { coeff: { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } }, - { channel: 1, filter: 1, data: { coeff: { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } }, - { channel: 1, filter: 2, data: { coeff: { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } }, - { channel: 1, filter: 3, data: { coeff: { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } }, - { channel: 1, filter: 4, data: { coeff: { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } }, - { channel: 1, filter: 5, data: { coeff: { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } }, - { channel: 1, filter: 6, data: { coeff: { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } } -}; - -static struct tas_eq_pref_t eqp_18_1_0 = { - sample_rate: 44100, - device_id: 0x18, - output_id: TAS_OUTPUT_INTERNAL_SPKR, - speaker_id: 0x00, - - drce: &eqp_18_1_0_drce, - - filter_count: 14, - biquads: eqp_18_1_0_biquads -}; - -/* ======================================================================== */ - -static struct tas_drce_t eqp_1a_1_0_drce={ - enable: 1, - above: { val: 3.0 * (1<<8), expand: 0 }, - below: { val: 1.0 * (1<<8), expand: 0 }, - threshold: -10.75 * (1<<8), - energy: 2.4 * (1<<12), - attack: 0.013 * (1<<12), - decay: 0.212 * (1<<12), -}; - -static struct tas_biquad_ctrl_t eqp_1a_1_0_biquads[]={ - { channel: 0, filter: 0, data: { coeff: { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } }, - { channel: 0, filter: 1, data: { coeff: { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } }, - { channel: 0, filter: 2, data: { coeff: { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } }, - { channel: 0, filter: 3, data: { coeff: { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } }, - { channel: 0, filter: 4, data: { coeff: { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } }, - { channel: 0, filter: 5, data: { coeff: { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } }, - { channel: 0, filter: 6, data: { coeff: { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } }, - - { channel: 1, filter: 0, data: { coeff: { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } }, - { channel: 1, filter: 1, data: { coeff: { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } }, - { channel: 1, filter: 2, data: { coeff: { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } }, - { channel: 1, filter: 3, data: { coeff: { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } }, - { channel: 1, filter: 4, data: { coeff: { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } }, - { channel: 1, filter: 5, data: { coeff: { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } }, - { channel: 1, filter: 6, data: { coeff: { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } } -}; - -static struct tas_eq_pref_t eqp_1a_1_0 = { - sample_rate: 44100, - device_id: 0x1a, - output_id: TAS_OUTPUT_INTERNAL_SPKR, - speaker_id: 0x00, - - drce: &eqp_1a_1_0_drce, - - filter_count: 14, - biquads: eqp_1a_1_0_biquads -}; - -/* ======================================================================== */ - -static struct tas_drce_t eqp_1c_1_0_drce={ - enable: 1, - above: { val: 3.0 * (1<<8), expand: 0 }, - below: { val: 1.0 * (1<<8), expand: 0 }, - threshold: -14.34 * (1<<8), - energy: 2.4 * (1<<12), - attack: 0.013 * (1<<12), - decay: 0.212 * (1<<12), -}; - -static struct tas_biquad_ctrl_t eqp_1c_1_0_biquads[]={ - { channel: 0, filter: 0, data: { coeff: { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } }, - { channel: 0, filter: 1, data: { coeff: { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } }, - { channel: 0, filter: 2, data: { coeff: { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } }, - { channel: 0, filter: 3, data: { coeff: { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } }, - { channel: 0, filter: 4, data: { coeff: { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } }, - { channel: 0, filter: 5, data: { coeff: { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } }, - { channel: 0, filter: 6, data: { coeff: { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } }, - - { channel: 1, filter: 0, data: { coeff: { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } }, - { channel: 1, filter: 1, data: { coeff: { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } }, - { channel: 1, filter: 2, data: { coeff: { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } }, - { channel: 1, filter: 3, data: { coeff: { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } }, - { channel: 1, filter: 4, data: { coeff: { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } }, - { channel: 1, filter: 5, data: { coeff: { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } }, - { channel: 1, filter: 6, data: { coeff: { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } } -}; - -static struct tas_eq_pref_t eqp_1c_1_0 = { - sample_rate: 44100, - device_id: 0x1c, - output_id: TAS_OUTPUT_INTERNAL_SPKR, - speaker_id: 0x00, - - drce: &eqp_1c_1_0_drce, - - filter_count: 14, - biquads: eqp_1c_1_0_biquads -}; - -/* ======================================================================== */ - -static uint tas3004_master_tab[]={ - 0x0, 0x75, 0x9c, 0xbb, - 0xdb, 0xfb, 0x11e, 0x143, - 0x16b, 0x196, 0x1c3, 0x1f5, - 0x229, 0x263, 0x29f, 0x2e1, - 0x328, 0x373, 0x3c5, 0x41b, - 0x478, 0x4dc, 0x547, 0x5b8, - 0x633, 0x6b5, 0x740, 0x7d5, - 0x873, 0x91c, 0x9d2, 0xa92, - 0xb5e, 0xc39, 0xd22, 0xe19, - 0xf20, 0x1037, 0x1161, 0x129e, - 0x13ed, 0x1551, 0x16ca, 0x185d, - 0x1a08, 0x1bcc, 0x1dac, 0x1fa7, - 0x21c1, 0x23fa, 0x2655, 0x28d6, - 0x2b7c, 0x2e4a, 0x3141, 0x3464, - 0x37b4, 0x3b35, 0x3ee9, 0x42d3, - 0x46f6, 0x4b53, 0x4ff0, 0x54ce, - 0x59f2, 0x5f5f, 0x6519, 0x6b24, - 0x7183, 0x783c, 0x7f53, 0x86cc, - 0x8ead, 0x96fa, 0x9fba, 0xa8f2, - 0xb2a7, 0xbce1, 0xc7a5, 0xd2fa, - 0xdee8, 0xeb75, 0xf8aa, 0x1068e, - 0x1152a, 0x12487, 0x134ad, 0x145a5, - 0x1577b, 0x16a37, 0x17df5, 0x192bd, - 0x1a890, 0x1bf7b, 0x1d78d, 0x1f0d1, - 0x20b55, 0x22727, 0x24456, 0x262f2, - 0x2830b -}; - -static uint tas3004_mixer_tab[]={ - 0x0, 0x748, 0x9be, 0xbaf, - 0xda4, 0xfb1, 0x11de, 0x1431, - 0x16ad, 0x1959, 0x1c37, 0x1f4b, - 0x2298, 0x2628, 0x29fb, 0x2e12, - 0x327d, 0x3734, 0x3c47, 0x41b4, - 0x4787, 0x4dbe, 0x546d, 0x5b86, - 0x632e, 0x6b52, 0x7400, 0x7d54, - 0x873b, 0x91c6, 0x9d1a, 0xa920, - 0xb5e5, 0xc38c, 0xd21b, 0xe18f, - 0xf1f5, 0x1036a, 0x1160f, 0x129d6, - 0x13ed0, 0x1550c, 0x16ca0, 0x185c9, - 0x1a07b, 0x1bcc3, 0x1dab9, 0x1fa75, - 0x21c0f, 0x23fa3, 0x26552, 0x28d64, - 0x2b7c9, 0x2e4a2, 0x31411, 0x3463b, - 0x37b44, 0x3b353, 0x3ee94, 0x42d30, - 0x46f55, 0x4b533, 0x4fefc, 0x54ce5, - 0x59f25, 0x5f5f6, 0x65193, 0x6b23c, - 0x71835, 0x783c3, 0x7f52c, 0x86cc0, - 0x8eacc, 0x96fa5, 0x9fba0, 0xa8f1a, - 0xb2a71, 0xbce0a, 0xc7a4a, 0xd2fa0, - 0xdee7b, 0xeb752, 0xf8a9f, 0x1068e4, - 0x1152a3, 0x12486a, 0x134ac8, 0x145a55, - 0x1577ac, 0x16a370, 0x17df51, 0x192bc2, - 0x1a88f8, 0x1bf7b7, 0x1d78c9, 0x1f0d04, - 0x20b542, 0x227268, 0x244564, 0x262f26, - 0x2830af -}; - -static uint tas3004_treble_tab[]={ - 0x96, 0x95, 0x95, 0x94, - 0x93, 0x92, 0x92, 0x91, - 0x90, 0x90, 0x8f, 0x8e, - 0x8d, 0x8d, 0x8c, 0x8b, - 0x8a, 0x8a, 0x89, 0x88, - 0x88, 0x87, 0x86, 0x85, - 0x85, 0x84, 0x83, 0x83, - 0x82, 0x81, 0x80, 0x80, - 0x7f, 0x7e, 0x7e, 0x7d, - 0x7c, 0x7b, 0x7b, 0x7a, - 0x79, 0x78, 0x78, 0x77, - 0x76, 0x76, 0x75, 0x74, - 0x73, 0x73, 0x72, 0x71, - 0x71, 0x68, 0x45, 0x5b, - 0x6d, 0x6c, 0x6b, 0x6a, - 0x69, 0x68, 0x67, 0x66, - 0x65, 0x63, 0x62, 0x62, - 0x60, 0x5e, 0x5c, 0x5b, - 0x59, 0x57, 0x55, 0x53, - 0x52, 0x4f, 0x4d, 0x4a, - 0x48, 0x46, 0x43, 0x40, - 0x3d, 0x3a, 0x36, 0x33, - 0x2f, 0x2c, 0x27, 0x23, - 0x1f, 0x1a, 0x15, 0xf, - 0x8, 0x5, 0x2, 0x1, - 0x1 -}; - -static uint tas3004_bass_tab[]={ - 0x96, 0x95, 0x95, 0x94, - 0x93, 0x92, 0x92, 0x91, - 0x90, 0x90, 0x8f, 0x8e, - 0x8d, 0x8d, 0x8c, 0x8b, - 0x8a, 0x8a, 0x89, 0x88, - 0x88, 0x87, 0x86, 0x85, - 0x85, 0x84, 0x83, 0x83, - 0x82, 0x81, 0x80, 0x80, - 0x7f, 0x7e, 0x7e, 0x7d, - 0x7c, 0x7b, 0x7b, 0x7a, - 0x79, 0x78, 0x78, 0x77, - 0x76, 0x76, 0x75, 0x74, - 0x73, 0x73, 0x72, 0x71, - 0x70, 0x6f, 0x6e, 0x6d, - 0x6c, 0x6b, 0x6a, 0x6a, - 0x69, 0x67, 0x66, 0x66, - 0x65, 0x63, 0x62, 0x62, - 0x61, 0x60, 0x5e, 0x5d, - 0x5b, 0x59, 0x57, 0x55, - 0x53, 0x51, 0x4f, 0x4c, - 0x4a, 0x48, 0x46, 0x44, - 0x41, 0x3e, 0x3b, 0x38, - 0x36, 0x33, 0x2f, 0x2b, - 0x28, 0x24, 0x20, 0x1c, - 0x17, 0x12, 0xd, 0x7, - 0x1 -}; - -struct tas_gain_t tas3004_gain={ - master: tas3004_master_tab, - treble: tas3004_treble_tab, - bass: tas3004_bass_tab, - mixer: tas3004_mixer_tab -}; - -struct tas_eq_pref_t *tas3004_eq_prefs[]={ - &eqp_17_1_0, - &eqp_18_1_0, - &eqp_1a_1_0, - &eqp_1c_1_0, - NULL -}; diff --git a/c/tas_v1.c b/c/tas_v1.c deleted file mode 100644 index b910e0a..0000000 --- a/c/tas_v1.c +++ /dev/null @@ -1,301 +0,0 @@ -#include "tas3004.h" -#include "tas_eq_prefs.h" - -static struct tas_drce_t eqp_17_1_0_drce={ - .enable = 1, - .above = { .val = 3.0 * (1<<8), .expand = 0 }, - .below = { .val = 1.0 * (1<<8), .expand = 0 }, - .threshold = -19.12 * (1<<8), - .energy = 2.4 * (1<<12), - .attack = 0.013 * (1<<12), - .decay = 0.212 * (1<<12), -}; - -static struct tas_biquad_ctrl_t eqp_17_1_0_biquads[]={ - { .channel = 0, .filter = 0, .data = { .coeff = { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } }, - { .channel = 0, .filter = 1, .data = { .coeff = { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } }, - { .channel = 0, .filter = 2, .data = { .coeff = { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } }, - { .channel = 0, .filter = 3, .data = { .coeff = { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } }, - { .channel = 0, .filter = 4, .data = { .coeff = { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } }, - { .channel = 0, .filter = 5, .data = { .coeff = { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } }, - { .channel = 0, .filter = 6, .data = { .coeff = { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } }, - - { .channel = 1, .filter = 0, .data = { .coeff = { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } }, - { .channel = 1, .filter = 1, .data = { .coeff = { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } }, - { .channel = 1, .filter = 2, .data = { .coeff = { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } }, - { .channel = 1, .filter = 3, .data = { .coeff = { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } }, - { .channel = 1, .filter = 4, .data = { .coeff = { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } }, - { .channel = 1, .filter = 5, .data = { .coeff = { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } }, - { .channel = 1, .filter = 6, .data = { .coeff = { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } } -}; - -static struct tas_eq_pref_t eqp_17_1_0 = { - .sample_rate = 44100, - .device_id = 0x17, - .output_id = TAS_OUTPUT_INTERNAL_SPKR, - .speaker_id = 0x00, - - .drce = &eqp_17_1_0_drce, - - .filter_count = 14, - .biquads = eqp_17_1_0_biquads -}; - -/* ======================================================================== */ - -static struct tas_drce_t eqp_18_1_0_drce={ - .enable = 1, - .above = { .val = 3.0 * (1<<8), .expand = 0 }, - .below = { .val = 1.0 * (1<<8), .expand = 0 }, - .threshold = -13.14 * (1<<8), - .energy = 2.4 * (1<<12), - .attack = 0.013 * (1<<12), - .decay = 0.212 * (1<<12), -}; - -static struct tas_biquad_ctrl_t eqp_18_1_0_biquads[]={ - { .channel = 0, .filter = 0, .data = { .coeff = { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } }, - { .channel = 0, .filter = 1, .data = { .coeff = { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } }, - { .channel = 0, .filter = 2, .data = { .coeff = { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } }, - { .channel = 0, .filter = 3, .data = { .coeff = { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } }, - { .channel = 0, .filter = 4, .data = { .coeff = { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } }, - { .channel = 0, .filter = 5, .data = { .coeff = { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } }, - { .channel = 0, .filter = 6, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }, - - { .channel = 1, .filter = 0, .data = { .coeff = { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } }, - { .channel = 1, .filter = 1, .data = { .coeff = { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } }, - { .channel = 1, .filter = 2, .data = { .coeff = { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } }, - { .channel = 1, .filter = 3, .data = { .coeff = { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } }, - { .channel = 1, .filter = 4, .data = { .coeff = { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } }, - { .channel = 1, .filter = 5, .data = { .coeff = { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } }, - { .channel = 1, .filter = 6, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } } -}; - -static struct tas_eq_pref_t eqp_18_1_0 = { - .sample_rate = 44100, - .device_id = 0x18, - .output_id = TAS_OUTPUT_INTERNAL_SPKR, - .speaker_id = 0x00, - - .drce = &eqp_18_1_0_drce, - - .filter_count = 14, - .biquads = eqp_18_1_0_biquads -}; - -/* ======================================================================== */ - -static struct tas_drce_t eqp_1a_1_0_drce={ - .enable = 1, - .above = { .val = 3.0 * (1<<8), .expand = 0 }, - .below = { .val = 1.0 * (1<<8), .expand = 0 }, - .threshold = -10.75 * (1<<8), - .energy = 2.4 * (1<<12), - .attack = 0.013 * (1<<12), - .decay = 0.212 * (1<<12), -}; - -static struct tas_biquad_ctrl_t eqp_1a_1_0_biquads[]={ - { .channel = 0, .filter = 0, .data = { .coeff = { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } }, - { .channel = 0, .filter = 1, .data = { .coeff = { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } }, - { .channel = 0, .filter = 2, .data = { .coeff = { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } }, - { .channel = 0, .filter = 3, .data = { .coeff = { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } }, - { .channel = 0, .filter = 4, .data = { .coeff = { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } }, - { .channel = 0, .filter = 5, .data = { .coeff = { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } }, - { .channel = 0, .filter = 6, .data = { .coeff = { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } }, - - { .channel = 1, .filter = 0, .data = { .coeff = { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } }, - { .channel = 1, .filter = 1, .data = { .coeff = { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } }, - { .channel = 1, .filter = 2, .data = { .coeff = { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } }, - { .channel = 1, .filter = 3, .data = { .coeff = { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } }, - { .channel = 1, .filter = 4, .data = { .coeff = { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } }, - { .channel = 1, .filter = 5, .data = { .coeff = { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } }, - { .channel = 1, .filter = 6, .data = { .coeff = { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } } -}; - -static struct tas_eq_pref_t eqp_1a_1_0 = { - .sample_rate = 44100, - .device_id = 0x1a, - .output_id = TAS_OUTPUT_INTERNAL_SPKR, - .speaker_id = 0x00, - - .drce = &eqp_1a_1_0_drce, - - .filter_count = 14, - .biquads = eqp_1a_1_0_biquads -}; - -/* ======================================================================== */ - -static struct tas_drce_t eqp_1c_1_0_drce={ - .enable = 1, - .above = { .val = 3.0 * (1<<8), .expand = 0 }, - .below = { .val = 1.0 * (1<<8), .expand = 0 }, - .threshold = -14.34 * (1<<8), - .energy = 2.4 * (1<<12), - .attack = 0.013 * (1<<12), - .decay = 0.212 * (1<<12), -}; - -static struct tas_biquad_ctrl_t eqp_1c_1_0_biquads[]={ - { .channel = 0, .filter = 0, .data = { .coeff = { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } }, - { .channel = 0, .filter = 1, .data = { .coeff = { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } }, - { .channel = 0, .filter = 2, .data = { .coeff = { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } }, - { .channel = 0, .filter = 3, .data = { .coeff = { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } }, - { .channel = 0, .filter = 4, .data = { .coeff = { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } }, - { .channel = 0, .filter = 5, .data = { .coeff = { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } }, - { .channel = 0, .filter = 6, .data = { .coeff = { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } }, - - { .channel = 1, .filter = 0, .data = { .coeff = { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } }, - { .channel = 1, .filter = 1, .data = { .coeff = { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } }, - { .channel = 1, .filter = 2, .data = { .coeff = { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } }, - { .channel = 1, .filter = 3, .data = { .coeff = { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } }, - { .channel = 1, .filter = 4, .data = { .coeff = { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } }, - { .channel = 1, .filter = 5, .data = { .coeff = { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } }, - { .channel = 1, .filter = 6, .data = { .coeff = { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } } -}; - -static struct tas_eq_pref_t eqp_1c_1_0 = { - .sample_rate = 44100, - .device_id = 0x1c, - .output_id = TAS_OUTPUT_INTERNAL_SPKR, - .speaker_id = 0x00, - - .drce = &eqp_1c_1_0_drce, - - .filter_count = 14, - .biquads = eqp_1c_1_0_biquads -}; - -/* ======================================================================== */ - -static uint tas3004_master_tab[]={ - 0x0, 0x75, 0x9c, 0xbb, - 0xdb, 0xfb, 0x11e, 0x143, - 0x16b, 0x196, 0x1c3, 0x1f5, - 0x229, 0x263, 0x29f, 0x2e1, - 0x328, 0x373, 0x3c5, 0x41b, - 0x478, 0x4dc, 0x547, 0x5b8, - 0x633, 0x6b5, 0x740, 0x7d5, - 0x873, 0x91c, 0x9d2, 0xa92, - 0xb5e, 0xc39, 0xd22, 0xe19, - 0xf20, 0x1037, 0x1161, 0x129e, - 0x13ed, 0x1551, 0x16ca, 0x185d, - 0x1a08, 0x1bcc, 0x1dac, 0x1fa7, - 0x21c1, 0x23fa, 0x2655, 0x28d6, - 0x2b7c, 0x2e4a, 0x3141, 0x3464, - 0x37b4, 0x3b35, 0x3ee9, 0x42d3, - 0x46f6, 0x4b53, 0x4ff0, 0x54ce, - 0x59f2, 0x5f5f, 0x6519, 0x6b24, - 0x7183, 0x783c, 0x7f53, 0x86cc, - 0x8ead, 0x96fa, 0x9fba, 0xa8f2, - 0xb2a7, 0xbce1, 0xc7a5, 0xd2fa, - 0xdee8, 0xeb75, 0xf8aa, 0x1068e, - 0x1152a, 0x12487, 0x134ad, 0x145a5, - 0x1577b, 0x16a37, 0x17df5, 0x192bd, - 0x1a890, 0x1bf7b, 0x1d78d, 0x1f0d1, - 0x20b55, 0x22727, 0x24456, 0x262f2, - 0x2830b -}; - -static uint tas3004_mixer_tab[]={ - 0x0, 0x748, 0x9be, 0xbaf, - 0xda4, 0xfb1, 0x11de, 0x1431, - 0x16ad, 0x1959, 0x1c37, 0x1f4b, - 0x2298, 0x2628, 0x29fb, 0x2e12, - 0x327d, 0x3734, 0x3c47, 0x41b4, - 0x4787, 0x4dbe, 0x546d, 0x5b86, - 0x632e, 0x6b52, 0x7400, 0x7d54, - 0x873b, 0x91c6, 0x9d1a, 0xa920, - 0xb5e5, 0xc38c, 0xd21b, 0xe18f, - 0xf1f5, 0x1036a, 0x1160f, 0x129d6, - 0x13ed0, 0x1550c, 0x16ca0, 0x185c9, - 0x1a07b, 0x1bcc3, 0x1dab9, 0x1fa75, - 0x21c0f, 0x23fa3, 0x26552, 0x28d64, - 0x2b7c9, 0x2e4a2, 0x31411, 0x3463b, - 0x37b44, 0x3b353, 0x3ee94, 0x42d30, - 0x46f55, 0x4b533, 0x4fefc, 0x54ce5, - 0x59f25, 0x5f5f6, 0x65193, 0x6b23c, - 0x71835, 0x783c3, 0x7f52c, 0x86cc0, - 0x8eacc, 0x96fa5, 0x9fba0, 0xa8f1a, - 0xb2a71, 0xbce0a, 0xc7a4a, 0xd2fa0, - 0xdee7b, 0xeb752, 0xf8a9f, 0x1068e4, - 0x1152a3, 0x12486a, 0x134ac8, 0x145a55, - 0x1577ac, 0x16a370, 0x17df51, 0x192bc2, - 0x1a88f8, 0x1bf7b7, 0x1d78c9, 0x1f0d04, - 0x20b542, 0x227268, 0x244564, 0x262f26, - 0x2830af -}; - -static uint tas3004_treble_tab[]={ - 0x96, 0x95, 0x95, 0x94, - 0x93, 0x92, 0x92, 0x91, - 0x90, 0x90, 0x8f, 0x8e, - 0x8d, 0x8d, 0x8c, 0x8b, - 0x8a, 0x8a, 0x89, 0x88, - 0x88, 0x87, 0x86, 0x85, - 0x85, 0x84, 0x83, 0x83, - 0x82, 0x81, 0x80, 0x80, - 0x7f, 0x7e, 0x7e, 0x7d, - 0x7c, 0x7b, 0x7b, 0x7a, - 0x79, 0x78, 0x78, 0x77, - 0x76, 0x76, 0x75, 0x74, - 0x73, 0x73, 0x72, 0x71, - 0x71, 0x68, 0x45, 0x5b, - 0x6d, 0x6c, 0x6b, 0x6a, - 0x69, 0x68, 0x67, 0x66, - 0x65, 0x63, 0x62, 0x62, - 0x60, 0x5e, 0x5c, 0x5b, - 0x59, 0x57, 0x55, 0x53, - 0x52, 0x4f, 0x4d, 0x4a, - 0x48, 0x46, 0x43, 0x40, - 0x3d, 0x3a, 0x36, 0x33, - 0x2f, 0x2c, 0x27, 0x23, - 0x1f, 0x1a, 0x15, 0xf, - 0x8, 0x5, 0x2, 0x1, - 0x1 -}; - -static uint tas3004_bass_tab[]={ - 0x96, 0x95, 0x95, 0x94, - 0x93, 0x92, 0x92, 0x91, - 0x90, 0x90, 0x8f, 0x8e, - 0x8d, 0x8d, 0x8c, 0x8b, - 0x8a, 0x8a, 0x89, 0x88, - 0x88, 0x87, 0x86, 0x85, - 0x85, 0x84, 0x83, 0x83, - 0x82, 0x81, 0x80, 0x80, - 0x7f, 0x7e, 0x7e, 0x7d, - 0x7c, 0x7b, 0x7b, 0x7a, - 0x79, 0x78, 0x78, 0x77, - 0x76, 0x76, 0x75, 0x74, - 0x73, 0x73, 0x72, 0x71, - 0x70, 0x6f, 0x6e, 0x6d, - 0x6c, 0x6b, 0x6a, 0x6a, - 0x69, 0x67, 0x66, 0x66, - 0x65, 0x63, 0x62, 0x62, - 0x61, 0x60, 0x5e, 0x5d, - 0x5b, 0x59, 0x57, 0x55, - 0x53, 0x51, 0x4f, 0x4c, - 0x4a, 0x48, 0x46, 0x44, - 0x41, 0x3e, 0x3b, 0x38, - 0x36, 0x33, 0x2f, 0x2b, - 0x28, 0x24, 0x20, 0x1c, - 0x17, 0x12, 0xd, 0x7, - 0x1 -}; - -struct tas_gain_t tas3004_gain={ - .master = tas3004_master_tab, - .treble = tas3004_treble_tab, - .bass = tas3004_bass_tab, - .mixer = tas3004_mixer_tab -}; - -struct tas_eq_pref_t *tas3004_eq_prefs[]={ - &eqp_17_1_0, - &eqp_18_1_0, - &eqp_1a_1_0, - &eqp_1c_1_0, - NULL -}; diff --git a/java/Example_v0.java b/java/Example_v0.java deleted file mode 100644 index 9d82b83..0000000 --- a/java/Example_v0.java +++ /dev/null @@ -1,20 +0,0 @@ -import java.util.Random; - -public class Example { - - public void hello() { - System.out.println("Hello everybody!"); - System.out.println("This code is a magnificent example"); - System.out.println("For the ASE 2014 conference"); - System.out.println("It draws a number at random"); - System.out.println("Adds 10"); - System.out.println("Multiplies by 10"); - System.out.println("And displays it"); - Random r = new Random(); - int i = r.nextInt(); - i += 10; - i *= 10; - System.out.println(i); - } - -} \ No newline at end of file diff --git a/java/MultiMapping_v0.java b/java/MultiMapping_v0.java deleted file mode 100644 index ee495d8..0000000 --- a/java/MultiMapping_v0.java +++ /dev/null @@ -1,20 +0,0 @@ -public class Test { - - /** - * Gets the first inventory item matching with any of the provided ids. - * - * @param ids the ids to look for - * @return the first inventory item matching with any of the provided ids; - * otherwise null - */ - public static Item getItem(int... ids) { - Item[] items = getItems(ids); - for (Item item : items) { - if (item != null) { - return item; - } - } - - return null; - } -} \ No newline at end of file diff --git a/java/MultiMapping_v1.java b/java/MultiMapping_v1.java deleted file mode 100644 index 670fbe3..0000000 --- a/java/MultiMapping_v1.java +++ /dev/null @@ -1,34 +0,0 @@ -public class Test { - - /** - * Gets the first inventory item matching with any of the provided ids. - * - * @param ids the ids to look for - * @return the first inventory item matching with any of the provided ids; - * otherwise null - */ - public static Item getItem(int... ids) { - Item[] items = getItems(ids); - if (items.length > 0) { - return items[0]; - } else { - return null; - } - } - - /** - * Gets the first inventory item matching with any of the provided ids. - * - * @param filter the filter to use - * @return the first inventory item matching with any of the provided ids; - * otherwise null - */ - public static Item getItem(final Filter filter) { - Item[] items = getItems(filter); - if (items.length > 0) { - return items[0]; - } else { - return null; - } - } -} \ No newline at end of file diff --git a/java/cases/fluent_v0.java b/java/cases/fluent_v0.java deleted file mode 100644 index 83c7f59..0000000 --- a/java/cases/fluent_v0.java +++ /dev/null @@ -1,14 +0,0 @@ -public class ChainSyntaxTest { - - public void foo() { - - StringBuffer buffer = new StringBuffer(); - - String string = buffer - .append("a") - .append("c") - .toString(); - - } - -} \ No newline at end of file diff --git a/java/cases/fluent_v1.java b/java/cases/fluent_v1.java deleted file mode 100644 index 24406e7..0000000 --- a/java/cases/fluent_v1.java +++ /dev/null @@ -1,16 +0,0 @@ -private class ChainSyntaxTest { - - public void foo() { - - StringBuffer buffer = new StringBuffer(); - - String string = buffer - .append("a") - .append("b") - .append("c") - .toString(); - - } - -} - diff --git a/java/cases/matrices_v0.java b/java/cases/matrices_v0.java deleted file mode 100644 index ff5e472..0000000 --- a/java/cases/matrices_v0.java +++ /dev/null @@ -1,7 +0,0 @@ -public class Foo { - - void foo() { - int[][] toto = new int[12][]; - } - -} \ No newline at end of file diff --git a/java/cases/matrices_v1.java b/java/cases/matrices_v1.java deleted file mode 100644 index 4b84bfc..0000000 --- a/java/cases/matrices_v1.java +++ /dev/null @@ -1,7 +0,0 @@ -public class Foo { - - void foo() { - int[][] toto = new int[26][]; - } - -} \ No newline at end of file diff --git a/java/cases/varargs_v0.java b/java/cases/varargs_v0.java deleted file mode 100644 index 0706579..0000000 --- a/java/cases/varargs_v0.java +++ /dev/null @@ -1,3 +0,0 @@ -interface Foo { - void foo(String... args); -} \ No newline at end of file diff --git a/java/cases/varargs_v1.java b/java/cases/varargs_v1.java deleted file mode 100644 index c635d2b..0000000 --- a/java/cases/varargs_v1.java +++ /dev/null @@ -1,3 +0,0 @@ -interface Foo { - void foo(String args); -} \ No newline at end of file diff --git a/java/cvsvintage/BoardView1_1.214_1.215_v0.java b/java/cvsvintage/BoardView1_1.214_1.215_v0.java deleted file mode 100644 index 735287f..0000000 --- a/java/cvsvintage/BoardView1_1.214_1.215_v0.java +++ /dev/null @@ -1,4253 +0,0 @@ -/* - * MegaMek - - * Copyright (C) 2000,2001,2002,2003,2004,2005 Ben Mazur (bmazur@sev.org) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -package megamek.client.ui.AWT; - -// Defines Iterator class for JDK v1.1 -import com.sun.java.util.collections.*; -import java.awt.*; -import java.awt.event.*; -import java.awt.image.*; -import java.util.Enumeration; - -import megamek.client.event.BoardViewEvent; -import megamek.client.event.BoardViewListener; -import megamek.client.ui.AWT.util.*; -import megamek.common.*; -import megamek.common.actions.*; -import megamek.common.event.BoardEvent; -import megamek.common.event.BoardListener; -import megamek.common.event.GameEntityRemoveEvent; -import megamek.common.event.GameNewActionEvent; -import megamek.common.event.GameBoardNewEvent; -import megamek.common.event.GameBoardChangeEvent; -import megamek.common.event.GameEntityChangeEvent; -import megamek.common.event.GameEntityNewEvent; -import megamek.common.event.GameListener; -import megamek.common.event.GameListenerAdapter; -import megamek.common.preference.PreferenceManager; - -import java.util.Properties; - -/** - * Displays the board; lets the user scroll around and select points on it. - */ -public class BoardView1 - extends Canvas - implements IBoardView, BoardListener, MouseListener, MouseMotionListener, KeyListener, AdjustmentListener -{ - private static final int TRANSPARENT = 0xFFFF00FF; - - // the dimensions of megamek's hex images - private static final int HEX_W = 84; - private static final int HEX_H = 72; - private static final int HEX_WC = HEX_W - HEX_W/4; - - // The list of valid zoom factors. Other values cause map aliasing, - // I can't be bothered figuring out why. - Ben - private static final float[] ZOOM_FACTORS = - { 0.30f, 0.41f, 0.50f, - 0.60f, 0.68f, 0.79f, - 0.90f, 1.00f - //1.09f, 1.17f - }; - - private ImageCache[] scaledImageCaches; - - // the index of zoom factor 1.00f - private static final int BASE_ZOOM_INDEX = 7; - - // line width of the c3 network lines - private static final int C3_LINE_WIDTH = 1; - - private static Font FONT_7 = new Font("SansSerif", Font.PLAIN, 7); //$NON-NLS-1$ - private static Font FONT_8 = new Font("SansSerif", Font.PLAIN, 8); //$NON-NLS-1$ - private static Font FONT_9 = new Font("SansSerif", Font.PLAIN, 9); //$NON-NLS-1$ - private static Font FONT_10 = new Font("SansSerif", Font.PLAIN, 10); //$NON-NLS-1$ - private static Font FONT_12 = new Font("SansSerif", Font.PLAIN, 12); //$NON-NLS-1$ - - private Dimension hex_size = null; - private boolean isJ2RE; - - private Font font_hexnum = FONT_10; - private Font font_elev = FONT_9; - private Font font_minefield = FONT_12; - - private IGame game; - private Frame frame; - - private Point mousePos = new Point(); - private Rectangle view = new Rectangle(); - private Point offset = new Point(); - private Dimension boardSize; - - // scrolly stuff: - private Scrollbar vScrollbar = null; - private Scrollbar hScrollbar = null; - private boolean isScrolling = false; - private Point scroll = new Point(); - private boolean initCtlScroll; - private boolean ctlKeyHeld = false; - private int previousMouseX; - private int previousMouseY; - - // back buffer to draw to - private Image backImage; - private Dimension backSize; - private Graphics backGraph; - - // buffer for all the hexes you can possibly see - private Image boardImage; - private Rectangle boardRect; - private Graphics boardGraph; - - // entity sprites - private Vector entitySprites = new Vector(); - private Hashtable entitySpriteIds = new Hashtable(); - - // sprites for the three selection cursors - private CursorSprite cursorSprite; - private CursorSprite highlightSprite; - private CursorSprite selectedSprite; - private CursorSprite firstLOSSprite; - private CursorSprite secondLOSSprite; - - // sprite for current movement - private Vector pathSprites = new Vector(); - - // vector of sprites for all firing lines - private Vector attackSprites = new Vector(); - - // vector of sprites for C3 network lines - private Vector C3Sprites = new Vector(); - - // tooltip stuff - private Window tipWindow; - private boolean isTipPossible = false; - private long lastIdle; - - private TilesetManager tileManager = null; - - // polygons for a few things - private Polygon hexPoly; - private Polygon[] facingPolys; - private Polygon[] movementPolys; - - // the player who owns this BoardView's client - private Player localPlayer = null; - - // should we mark deployment hexes for a player? - private Player m_plDeployer = null; - - // should be able to turn it off(board editor) - private boolean useLOSTool = true; - - // Initial scale factor for sprites and map - private boolean hasZoomed = false; - public int zoomIndex; - private float scale; - private Hashtable scaledImageCache = new Hashtable(); - - // Displayables (Chat box, etc.) - private Vector displayables = new Vector(); - - // Move units step by step - private Vector movingUnits = new Vector(); - private long moveWait = 0; - - // moving entity sprites - private Vector movingEntitySprites = new Vector(); - private Hashtable movingEntitySpriteIds = new Hashtable(); - private Vector ghostEntitySprites = new Vector(); - protected transient Vector boardListeners = new Vector(); - - // wreck sprites - private Vector wreckSprites = new Vector(); - - private Coords rulerStart; // added by kenn - private Coords rulerEnd; // added by kenn - private Color rulerStartColor; // added by kenn - private Color rulerEndColor; // added by kenn - - // Position of the mouse before right mouse button was pressed. Used to have an anchor for scrolling - private Point oldMousePosition = null; - - // Indicate that a scrolling took place, so no popup should be drawn on right mouse button release - private boolean scrolled = false; - - private Coords lastCursor; - private Coords highlighted; - private Coords selected; - private Coords firstLOS; - - private ClientGUI clientgui; - - private RedrawWorker redrawWorker = new RedrawWorker(); - - /** - * Construct a new board view for the specified game - */ - public BoardView1(IGame game, Frame frame) throws java.io.IOException { - this(game, frame, null); - } - - /** - * Construct a new board view for the specified game - */ - public BoardView1(IGame game, Frame frame, ClientGUI clientgui) throws java.io.IOException { - this.clientgui = clientgui; - this.game = game; - this.frame = frame; - - tileManager = new TilesetManager(this); - - game.addGameListener(gameListener); - game.getBoard().addBoardListener(this); - redrawWorker.start(); - addKeyListener(this); - addMouseListener(this); - addMouseMotionListener(this); - /* MouseWheelListener isn't a v1.3.1 API ** - try{ - addMouseWheelListener( new MouseWheelListener(){ - public void mouseWheelMoved(MouseWheelEvent we){ - if (we.getWheelRotation() > 0){ - zoomIn(); - } else { - zoomOut(); - } - } - }); - } catch ( Throwable error ){ - System.out.println("Mouse wheel not supported by this jvm"); - } - /* MouseWheelListener isn't a v1.3.1 API */ - - // only use scaling if we're using Java 2, otherwise we get memory leaks etc. - Properties p = System.getProperties(); - String javaVersion = p.getProperty( "java.version" ); //$NON-NLS-1$ - if ( javaVersion.charAt(2) == '1' ){ - isJ2RE = false; - zoomIndex = BASE_ZOOM_INDEX; - } else { - isJ2RE = true; - zoomIndex = GUIPreferences.getInstance().getMapZoomIndex(); - checkZoomIndex(); - hasZoomed = true; - } - scale = ZOOM_FACTORS[ zoomIndex ]; - - updateFontSizes(); - updateBoardSize(); - - // tooltip - tipWindow = new Window(frame); - - hex_size = new Dimension((int)(HEX_W*scale), (int)(HEX_H*scale)); - - initPolys(); - - cursorSprite = new CursorSprite(Color.cyan); - highlightSprite = new CursorSprite(Color.white); - selectedSprite = new CursorSprite(Color.blue); - firstLOSSprite = new CursorSprite(Color.red); - secondLOSSprite = new CursorSprite(Color.red); - - scaledImageCaches = new ImageCache[ZOOM_FACTORS.length]; - for(int i = 0;iScrollbar - * @param horizontal - the horizontal Scrollbar - */ - public void setScrollbars (Scrollbar vertical, Scrollbar horizontal) { - this.vScrollbar = vertical; - this.hScrollbar = horizontal; - - // When the scroll bars are adjusted, update our offset. - this.vScrollbar.addAdjustmentListener (this); - this.hScrollbar.addAdjustmentListener (this); - } - - /** - * Update ourself when a scroll bar is adjusted. - * - * @param event - the AdjustmentEvent that caused this call. - */ - public void adjustmentValueChanged (AdjustmentEvent event) { - Point oldPt = this.scroll; - Point newPt = new Point (oldPt.x, oldPt.y); - if (event.getAdjustable().getOrientation() == Adjustable.VERTICAL) { - newPt.y = event.getValue(); - } else { - newPt.x = event.getValue(); - } - this.scroll.setLocation (newPt); - this.repaint(); - } - - public void paint(Graphics g) { - update(g); - } - - /** - * Draw the screen! - */ - public void update(Graphics g) { - // Limit our size to the viewport of the scroll pane. - final Dimension size = getSize(); - // final long startTime = System.currentTimeMillis(); // commentme - - // Make sure our scrollbars have the right sizes. - // N.B. A buggy Sun implementation makes me to do this here instead - // of updateBoardSize() (which is where *I* think it belongs). - if (null != this.vScrollbar) { - this.vScrollbar.setVisibleAmount (size.height); - this.vScrollbar.setBlockIncrement (size.height); - this.vScrollbar.setUnitIncrement ((int) (scale * HEX_H / 2.0)); - this.vScrollbar.setMaximum (boardSize.height); - } - if (null != this.hScrollbar) { - this.hScrollbar.setVisibleAmount (size.width); - this.hScrollbar.setBlockIncrement (size.width); - this.hScrollbar.setUnitIncrement ((int) (scale * HEX_W / 2.0)); - this.hScrollbar.setMaximum (boardSize.width); - } - - // update view, offset - view.setLocation(scroll); - view.setSize(getOptimalView(size)); - offset.setLocation(getOptimalOffset(size)); - - if (!this.isTileImagesLoaded()) { - g.drawString(Messages.getString("BoardView1.loadingImages"), 20, 50); //$NON-NLS-1$ - if (!tileManager.isStarted()) { - System.out.println("boardview1: loading images for board"); //$NON-NLS-1$ - tileManager.loadNeededImages(game); - } - return; - } - - // make sure back buffer is valid - if (backGraph == null || !view.getSize().equals(backSize)) { - // make new back buffer - backSize = view.getSize(); - backImage = createImage(backSize.width, backSize.height); - backGraph = backImage.getGraphics(); - } - - // make sure board rectangle contains our current view rectangle - if (boardImage == null || !boardRect.union(view).equals(boardRect)) { - updateBoardImage(); - } - - // draw onto the back buffer: - - // draw the board - backGraph.drawImage(boardImage, 0, 0, this); - - // draw wrecks - if (GUIPreferences.getInstance().getShowWrecks()) { - drawSprites(wreckSprites); - } - - // Minefield signs all over the place! - drawMinefields(); - - // Artillery targets - drawArtilleryHexes(); - - // draw highlight border - drawSprite(highlightSprite); - - // draw cursors - drawSprite(cursorSprite); - drawSprite(selectedSprite); - drawSprite(firstLOSSprite); - drawSprite(secondLOSSprite); - - // draw deployment indicators - if (m_plDeployer != null) { - drawDeployment(); - } - - // draw C3 links - drawSprites(C3Sprites); - - // draw onscreen entities - drawSprites(entitySprites); - - // draw moving onscreen entities - drawSprites(movingEntitySprites); - - // draw ghost onscreen entities - drawSprites(ghostEntitySprites); - - // draw onscreen attacks - drawSprites(attackSprites); - - // draw movement, if valid - drawSprites(pathSprites); - - // added by kenn - // draw the ruler line - if (rulerStart != null) { - Point start = getCentreHexLocation(rulerStart); - if (rulerEnd != null) { - Point end = getCentreHexLocation(rulerEnd); - backGraph.setColor(Color.yellow); - backGraph.drawLine(start.x - boardRect.x, start.y - boardRect.y, end.x - boardRect.x, end.y - boardRect.y); - - backGraph.setColor(rulerEndColor); - backGraph.fillRect(end.x - boardRect.x - 1, end.y - boardRect.y - 1, 2, 2); - } - - backGraph.setColor(rulerStartColor); - backGraph.fillRect(start.x - boardRect.x - 1, start.y - boardRect.y - 1, 2, 2); - } - // end kenn - - // draw all the "displayables" - for (int i = 0; i < displayables.size(); i++) { - Displayable disp = (Displayable) displayables.elementAt(i); - disp.draw(backGraph, backSize); - } - - // draw the back buffer onto the screen - // first clear the entire view if the map has been zoomed - if ( hasZoomed == true ){ - Image tmpImage = createImage( size.width, size.height ); - Graphics tmpGraphics = tmpImage.getGraphics(); - tmpGraphics.drawImage(backImage, offset.x, offset.y, this); - g.drawImage(tmpImage, 0, 0, this); - hasZoomed=false; - } else { - g.drawImage(backImage, offset.x, offset.y, this); - } - //g.drawString(""+scale, 10, 10); - - // final long finishTime = System.currentTimeMillis();//commentme - // System.out.println("BoardView1: updated screen in " + (finishTime - startTime) + " ms."); //commentme - } - - /** - * Updates the boardSize variable with the proper values for this board. - */ - private void updateBoardSize() { - int width = game.getBoard().getWidth() * (int)(HEX_WC*scale) + (int)(HEX_W/4*scale); - int height = game.getBoard().getHeight() * (int)(HEX_H*scale) + (int)(HEX_H/2*scale); - boardSize = new Dimension(width, height); - } - - /** - * Think up the size of the view rectangle based on the size of the component - * and the size of board - */ - private Dimension getOptimalView(Dimension size) { - return new Dimension( - Math.min(size.width, boardSize.width), - Math.min(size.height, boardSize.height)); - } - - /** - * Where should the offset be for this screen size? - */ - private Point getOptimalOffset(Dimension size) { - int ox = 0; - int oy = 0; - if (size.width > boardSize.width) { - ox = (size.width - boardSize.width) / 2; - } - if (size.height > boardSize.height) { - oy = (size.height - boardSize.height) / 2; - } - return new Point(ox, oy); - } - - /** - * Repaint the bounds of a sprite, offset by view - */ - private void repaintBounds(Rectangle bounds) { - if (view != null) { - repaint(bounds.x - view.x + offset.x, bounds.y - view.y + offset.y, bounds.width, bounds.height); - } - } - - /** - * Looks through a vector of buffered images and draws them if they're - * onscreen. - */ - private synchronized void drawSprites(Vector spriteVector) { - for (int i = 0; i < spriteVector.size(); i++) { - final Sprite sprite = (Sprite)spriteVector.get(i); - drawSprite(sprite); - } - } - - /** - * Draws a sprite, if it is in the current view - */ - private final void drawSprite(Sprite sprite) { - if (view.intersects(sprite.getBounds())) { - final int drawX = sprite.getBounds().x - view.x; - final int drawY = sprite.getBounds().y - view.y; - if (!sprite.isReady()) { - sprite.prepare(); - } - sprite.drawOnto(backGraph, drawX, drawY, this); - } - } - - /** - * Manages a cache of scaled images. - */ - private Image getScaledImage(Image base) { - if (base == null) { - return null; - } - if ( zoomIndex == BASE_ZOOM_INDEX ) { - return base; - } - - - Image scaled = (Image) scaledImageCaches[zoomIndex].get(base); - if (scaled == null) { - Dimension d = getImageBounds(base).getSize(); - d.width *= scale; - d.height *= scale; - - scaled = scale(base, d.width, d.height); - - MediaTracker tracker = new MediaTracker(this); - tracker.addImage( scaled, 1 ); - // Wait for image to load - try{ - tracker.waitForID( 1 ); - } catch ( InterruptedException e ){ e.printStackTrace(); } - - scaledImageCaches[zoomIndex].put(base, scaled); - } - return scaled; - } - - /** - * The actual scaling code. - */ - private Image scale(Image img, int width, int height) { - ImageFilter filter; - - filter = new ImprovedAveragingScaleFilter(img.getWidth(null), - img.getHeight(null), - width, height); - - ImageProducer prod; - prod = new FilteredImageSource(img.getSource(), filter); - return Toolkit.getDefaultToolkit().createImage(prod); - } - - private static Rectangle getImageBounds(Image im) { - return new Rectangle(-im.getWidth(null) / 2, -im.getHeight(null) / 2, im.getWidth(null), im.getHeight(null)); - } - - /** - * The key assigned to each scaled and cached image. Enables easy - * retrieval from the hash table. - */ - private static class ScaledCacheKey { - private Image base; - private Dimension bounds; - - public ScaledCacheKey(Image base, Dimension bounds) { - this.bounds = bounds; - this.base = base; - } - - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof ScaledCacheKey)) return false; - - final ScaledCacheKey scaledCacheKey = (ScaledCacheKey) o; - - if (!base.equals(scaledCacheKey.base)) return false; - if (!bounds.equals(scaledCacheKey.bounds)) return false; - - return true; - } - - public int hashCode() { - int result; - result = base.hashCode(); - result = 29 * result + bounds.hashCode(); - return result; - } - } - - /** - * Draw an outline around legal deployment hexes - */ - private void drawDeployment() { - // only update visible hexes - int drawX = view.x / (int)(HEX_WC*scale) - 1; - int drawY = view.y / (int)(HEX_H*scale) - 1; - - int drawWidth = view.width / (int)(HEX_WC*scale) + 3; - int drawHeight = view.height / (int)(HEX_H*scale) + 3; - IBoard board = game.getBoard(); - // loop through the hexes - for (int i = 0; i < drawHeight; i++) { - for (int j = 0; j < drawWidth; j++) { - Coords c = new Coords(j + drawX, i + drawY); - Point p = getHexLocation(c); - p.translate(-(view.x), -(view.y)); - if (board.isLegalDeployment(c, m_plDeployer)) { - backGraph.setColor(Color.yellow); - int[] xcoords = { p.x + (int)(21*scale), p.x + (int)(62*scale), p.x + (int)(83*scale), p.x + (int)(83*scale), - p.x + (int)(62*scale), p.x + (int)(21*scale), p.x, p.x }; - int[] ycoords = { p.y, p.y, p.y + (int)(35*scale), p.y + (int)(36*scale), p.y + (int)(71*scale), - p.y + (int)(71*scale), p.y + (int)(36*scale), p.y + (int)(35*scale) }; - backGraph.drawPolygon(xcoords, ycoords, 8); - } - } - } - } - - /** - * returns the weapon selected in the mech display, - * or null if none selected or it is not artillery - **/ - private Mounted getSelectedArtilleryWeapon() { - Entity e = clientgui.mechD.getCurrentEntity(); - Mounted weapon = null; - - if(e != null) { - weapon = e.getEquipment(clientgui.mechD.wPan.getSelectedWeaponNum()); - } - if (weapon != null) { - if(!(weapon.getType() instanceof WeaponType && weapon.getType().hasFlag(WeaponType.F_ARTILLERY))) { - weapon = null; - } - //otherwise, a weapon is selected, and it is artillery - } - return weapon; - } - - /** Display artillery modifier in pretargeted hexes - */ - private void drawArtilleryHexes() { - if (clientgui != null) { - Entity e = clientgui.mechD.getCurrentEntity(); - Mounted weapon = getSelectedArtilleryWeapon(); - - if(game.getArtillerySize()==0 && weapon==null) { - return; //nothing to do - } - - if (!e.getOwner().equals(clientgui.getClient().getLocalPlayer())) { - return; // Not my business to see this - } - - int drawX = view.x / (int)(HEX_WC*scale) - 1; - int drawY = view.y / (int)(HEX_H*scale) - 1; - - int drawWidth = view.width / (int)(HEX_WC*scale) + 3; - int drawHeight = view.height / (int)(HEX_H*scale) + 3; - - IBoard board = game.getBoard(); - Image scaledImage; - - // loop through the hexes - for (int i = 0; i < drawHeight; i++) { - for (int j = 0; j < drawWidth; j++) { - Coords c = new Coords(j + drawX, i + drawY); - Point p = getHexLocation(c); - p.translate(-(view.x), -(view.y)); - - if (!board.contains(c)){ continue; } - - if(weapon != null) { - //process targetted hexes - int amod = 0; - //Check the predesignated hexes - if(e.getOwner().getArtyAutoHitHexes().contains(c)) { - amod = TargetRoll.AUTOMATIC_SUCCESS; - } - else { - amod = e.aTracker.getModifier(weapon, c); - } - - if(amod!=0) { - - //draw the crosshairs - if(amod==TargetRoll.AUTOMATIC_SUCCESS) { - //predesignated or already hit - scaledImage = getScaledImage(tileManager.getArtilleryTarget(TilesetManager.ARTILLERY_AUTOHIT)); - } else { - scaledImage = getScaledImage(tileManager.getArtilleryTarget(TilesetManager.ARTILLERY_ADJUSTED)); - } - - backGraph.drawImage(scaledImage, p.x, p.y, this); - } - } - //process incoming attacks - requires server to update client's view of game - - for(Enumeration attacks=game.getArtilleryAttacks();attacks.hasMoreElements();) { - ArtilleryAttackAction a = (ArtilleryAttackAction)attacks.nextElement(); - - if(a.getWR().waa.getTarget(game).getPosition().equals(c)) { - scaledImage = getScaledImage(tileManager.getArtilleryTarget(TilesetManager.ARTILLERY_INCOMING)); - backGraph.drawImage(scaledImage, p.x, p.y, this); - break; //do not draw multiple times, tooltop will show all attacks - } - } - } - } - } - } - - private Vector getArtilleryAttacksAtLocation(Coords c) { - Vector v = new Vector(); - for(Enumeration attacks=game.getArtilleryAttacks();attacks.hasMoreElements();) { - ArtilleryAttackAction a = (ArtilleryAttackAction)attacks.nextElement(); - - if(a.getWR().waa.getTarget(game).getPosition().equals(c)) { - v.addElement(a); - } - } - return v; - } - - /** - * Writes "MINEFIELD" in minefield hexes... - */ - private void drawMinefields() { - // only update visible hexes - int drawX = view.x / (int)(HEX_WC*scale) - 1; - int drawY = view.y / (int)(HEX_H*scale) - 1; - - int drawWidth = view.width / (int)(HEX_WC*scale) + 3; - int drawHeight = view.height / (int)(HEX_H*scale) + 3; - - IBoard board = game.getBoard(); - // loop through the hexes - for (int i = 0; i < drawHeight; i++) { - for (int j = 0; j < drawWidth; j++) { - Coords c = new Coords(j + drawX, i + drawY); - Point p = getHexLocation(c); - p.translate(-(view.x), -(view.y)); - - if (!board.contains(c)){ continue; } - if (!game.containsMinefield(c)){ continue; } - - Minefield mf = (Minefield) game.getMinefields(c).elementAt(0); - - Image tmpImage = getScaledImage( tileManager.getMinefieldSign()); - backGraph.drawImage( - tmpImage, - p.x + (int)(13*scale), - p.y + (int)(13*scale), - this); - - backGraph.setColor(Color.black); - int nbrMfs = game.getNbrMinefields(c); - if (nbrMfs > 1) { - drawCenteredString(Messages.getString("BoardView1.Multiple"), //$NON-NLS-1$ - p.x, - p.y + (int)(51*scale), - font_minefield, - backGraph); - } else if (nbrMfs == 1) { - switch (mf.getType()) { - case (Minefield.TYPE_CONVENTIONAL) : - drawCenteredString( - Messages.getString("BoardView1.Conventional"), //$NON-NLS-1$ - p.x, - p.y + (int)(51*scale), - font_minefield, - backGraph); - break; - case (Minefield.TYPE_THUNDER) : - drawCenteredString( - Messages.getString("BoardView1.Thunder") + mf.getDamage() + ")", //$NON-NLS-1$ //$NON-NLS-2$ - p.x, - p.y + (int)(51*scale), - font_minefield, - backGraph); - break; - case (Minefield.TYPE_THUNDER_INFERNO) : - drawCenteredString( - Messages.getString("BoardView1.Thunder-Inf") + mf.getDamage() + ")", //$NON-NLS-1$ //$NON-NLS-2$ - p.x, - p.y + (int)(51*scale), - font_minefield, - backGraph); - break; - case (Minefield.TYPE_THUNDER_ACTIVE) : - drawCenteredString( - Messages.getString("BoardView1.Thunder-Actv") + mf.getDamage() + ")", //$NON-NLS-1$ //$NON-NLS-2$ - p.x, - p.y + (int)(51*scale), - font_minefield, - backGraph); - break; - case (Minefield.TYPE_COMMAND_DETONATED) : - drawCenteredString( - Messages.getString("BoardView1.Command-"), //$NON-NLS-1$ - p.x, - p.y + (int)(51*scale), - font_minefield, - backGraph); - drawCenteredString( - Messages.getString("BoardView1.detonated"), //$NON-NLS-1$ - p.x, - p.y + (int)(60*scale), - font_minefield, - backGraph); - break; - case (Minefield.TYPE_VIBRABOMB) : - drawCenteredString( - Messages.getString("BoardView1.Vibrabomb"), //$NON-NLS-1$ - p.x, - p.y + (int)(51*scale), - font_minefield, - backGraph); - if (mf.getPlayerId() == localPlayer.getId()) { - drawCenteredString( - "(" + mf.getSetting() + ")", //$NON-NLS-1$ //$NON-NLS-2$ - p.x, - p.y + (int)(60*scale), - font_minefield, - backGraph); - } - break; - } - } - } - } - } - - private void drawCenteredString( String string, int x, int y, Font font, Graphics graph ){ - FontMetrics currentMetrics = getFontMetrics(font); - int stringWidth = currentMetrics.stringWidth(string); - - x += (int)((hex_size.width - stringWidth)/2); - - graph.setFont(font); - graph.drawString( string, x, y ); - } - - /** - * Updates the board buffer to contain all the hexes needed by the view. - */ - private void updateBoardImage() { - // check to make sure image is big enough - if (boardGraph == null || view.width > boardRect.width - || view.height > boardRect.height) { - /* Ok, some history here. Before the zoom patch, the - boardImage was created with the same size as the view. - After the zoom patch, the boardImage was created with - the same size as the entire board (all maps). This - change ate up a hideous amount of memory (eg: in a 3x3 - map set test with one mech, memory usage went from - about 15MB to 60MB). I have now changed it back to the - old way, and the zoom feature *seems* to still work. - Why the zoom author made the change, I cannot say. */ - boardImage = createImage(view.width, view.height); - //boardImage = createImage(boardSize.width, boardSize.height); - /* ----- */ - - boardGraph = boardImage.getGraphics(); - - // Handle resizes correctly. - checkScrollBounds(); - boardRect = new Rectangle(view); - System.out.println("boardview1: made a new board buffer " + boardRect); //$NON-NLS-1$ - drawHexes(view); - - } - if (!boardRect.union(view).equals(boardRect)) { - moveBoardImage(); - } - } - - /** - * This method creates an image the size of the entire board (all - * mapsheets), draws the hexes onto it, and returns that image. - */ - public Image getEntireBoardImage() { - Image entireBoard = createImage(boardSize.width, boardSize.height); - Graphics temp = boardImage.getGraphics(); - boardGraph = entireBoard.getGraphics(); - drawHexes(new Rectangle(boardSize)); - boardGraph = temp; - return entireBoard; - } - - /** - * Moves the board view to another area. - */ - private void moveBoardImage() { - // salvage the old - - boardGraph.setClip(0, 0, boardRect.width, boardRect.height); - boardGraph.copyArea(0, 0, boardRect.width, boardRect.height, - boardRect.x - view.x, boardRect.y - view.y); - - // what's left to paint? - int midX = Math.max(view.x, boardRect.x); - int midWidth = view.width - Math.abs(view.x - boardRect.x); - Rectangle unLeft = new Rectangle(view.x, view.y, boardRect.x - view.x, view.height); - Rectangle unRight = new Rectangle(boardRect.x + boardRect.width, view.y, view.x -boardRect.x, view.height); - Rectangle unTop = new Rectangle(midX, view.y, midWidth, boardRect.y - view.y); - Rectangle unBottom = new Rectangle(midX, boardRect.y + boardRect.height, midWidth, view.y - boardRect.y); - - // update boardRect - boardRect = new Rectangle(view); - - // paint needed areas - if (unLeft.width > 0) { - drawHexes(unLeft); - } else if (unRight.width > 0) { - drawHexes(unRight); - } - if (unTop.height > 0) { - drawHexes(unTop); - } else if (unBottom.height > 0) { - drawHexes(unBottom); - } - } - - /** - * Redraws all hexes in the specified rectangle - */ - private void drawHexes(Rectangle rect) { - - // rect is the view - int drawX = (int)(rect.x / (HEX_WC*scale))-1; - int drawY = (int)(rect.y / (HEX_H*scale))-1; - - int drawWidth = (int)(rect.width / (HEX_WC*scale))+3; - int drawHeight = (int)(rect.height / (HEX_H*scale))+3; - - // only draw what we came to draw - boardGraph.setClip(rect.x - boardRect.x, rect.y - boardRect.y, - rect.width, rect.height); - - // clear, if we need to - if (rect.x < (21*scale)) { - boardGraph.clearRect( - rect.x - boardRect.x, rect.y - boardRect.y, - (int)(21*scale) - rect.x, rect.height); - } - if (rect.y < (36*scale)) { - boardGraph.clearRect( - rect.x - boardRect.x, rect.y - boardRect.y, - rect.width, (int)(36*scale) - rect.y); - } - if (rect.x > boardSize.width - view.width - (21*scale)) { - boardGraph.clearRect( - boardRect.width - (int)(21*scale), rect.y - boardRect.y, - (int)(21*scale), rect.height); - } - if (rect.y > boardSize.height - view.height - (int)(36*scale)) { - boardGraph.clearRect( - rect.x - boardRect.x, boardRect.height - (int)(36*scale), - rect.width, (int)(36*scale)); - } - - // draw some hexes - for (int i = 0; i < drawHeight; i++) { - for (int j = 0; j < drawWidth; j++) { - drawHex(new Coords(j + drawX, i + drawY)); - } - } - } - - /** - * Redraws a hex and all the hexes immediately around it. Used when the - * hex is on the screen, as opposed to when it is scrolling onto the screen, - * so it resets the clipping rectangle before drawing. - */ - private void redrawAround(Coords c) { - boardGraph.setClip(0, 0, boardRect.width, boardRect.height); - drawHex(c); - drawHex(c.translated(0)); - drawHex(c.translated(1)); - drawHex(c.translated(2)); - drawHex(c.translated(3)); - drawHex(c.translated(4)); - drawHex(c.translated(5)); - } - - /** - * Draws a hex onto the board buffer. This assumes that boardRect is - * current, and does not check if the hex is visible. - */ - private void drawHex(Coords c) { - if (!game.getBoard().contains(c)) { - return; - } - - final IHex hex = game.getBoard().getHex(c); - final Point hexLoc = getHexLocation(c); - - int level = hex.getElevation(); - int depth = hex.depth(); - - // offset drawing point - - int drawX = hexLoc.x - boardRect.x; - int drawY = hexLoc.y - boardRect.y; - - // draw picture - Image baseImage = tileManager.baseFor(hex); - Image scaledImage = getScaledImage(baseImage); - - boardGraph.drawImage(scaledImage, drawX, drawY, this); - - if (tileManager.supersFor(hex) != null) { - for (Iterator i = tileManager.supersFor(hex).iterator(); i.hasNext();){ - scaledImage = getScaledImage((Image)i.next()); - boardGraph.drawImage(scaledImage, drawX, drawY, this); - } - } - - if(GUIPreferences.getInstance().getBoolean(GUIPreferences.ADVANCED_DARKEN_MAP_AT_NIGHT) && - game.getOptions().booleanOption("night_battle") && - !game.isPositionIlluminated(c)) { - scaledImage = getScaledImage(tileManager.getNightFog()); - boardGraph.drawImage(scaledImage, drawX, drawY, this); - } - boardGraph.setColor(GUIPreferences.getInstance().getMapTextColor()); - - // draw hex number - if (scale >= 0.5){ - drawCenteredString( - c.getBoardNum(), - drawX, - drawY + (int)(12*scale), - font_hexnum, - boardGraph); - } - // level | depth - if (level != 0 && depth == 0 && zoomIndex > 3) { - drawCenteredString( - Messages.getString("BoardView1.LEVEL") + level, //$NON-NLS-1$ - drawX, - drawY + (int)(70*scale), - font_elev, - boardGraph); - } else if (depth != 0 && level == 0 && zoomIndex > 3 ) { - drawCenteredString( - Messages.getString("BoardView1.DEPTH") + depth, //$NON-NLS-1$ - drawX, - drawY + (int)(70*scale), - font_elev, - boardGraph); - } else if (level != 0 && depth != 0 && zoomIndex > 3) { - drawCenteredString( - Messages.getString("BoardView1.LEVEL") + level, //$NON-NLS-1$ - drawX, - drawY + (int)(60*scale), - font_elev, - boardGraph); - drawCenteredString( - Messages.getString("BoardView1.DEPTH") + depth, //$NON-NLS-1$ - drawX, - drawY + (int)(70*scale), - font_elev, - boardGraph); - } - - // draw elevation borders - boardGraph.setColor(Color.black); - if (drawElevationLine(c, 0)) { - boardGraph.drawLine(drawX + (int)(21*scale), drawY, drawX + (int)(62*scale), drawY); - } - if (drawElevationLine(c, 1)) { - boardGraph.drawLine(drawX + (int)(62*scale), drawY, drawX + (int)(83*scale), drawY + (int)(35*scale)); - } - if (drawElevationLine(c, 2)) { - boardGraph.drawLine(drawX + (int)(83*scale), drawY + (int)(36*scale), drawX + (int)(62*scale), drawY + (int)(71*scale)); - } - if (drawElevationLine(c, 3)) { - boardGraph.drawLine(drawX + (int)(62*scale), drawY + (int)(71*scale), drawX + (int)(21*scale), drawY + (int)(71*scale)); - } - if (drawElevationLine(c, 4)) { - boardGraph.drawLine(drawX + (int)(21*scale), drawY + (int)(71*scale), drawX, drawY + (int)(36*scale)); - } - if (drawElevationLine(c, 5)) { - boardGraph.drawLine(drawX, drawY + (int)(35*scale), drawX + (int)(21*scale), drawY); - } - - // draw mapsheet borders - if(GUIPreferences.getInstance().getShowMapsheets()) { - boardGraph.setColor(GUIPreferences.getInstance().getColor(GUIPreferences.ADVANCED_MAPSHEET_COLOR)); - if(c.x % 16 == 0) { - //left edge of sheet (edge 4 & 5) - boardGraph.drawLine(drawX + (int)(21*scale), drawY + (int)(71*scale), drawX, drawY + (int)(36*scale)); - boardGraph.drawLine(drawX, drawY + (int)(35*scale), drawX + (int)(21*scale), drawY); - } - else if(c.x % 16 == 15) { - //right edge of sheet (edge 1 & 2) - boardGraph.drawLine(drawX + (int)(62*scale), drawY, drawX + (int)(83*scale), drawY + (int)(35*scale)); - boardGraph.drawLine(drawX + (int)(83*scale), drawY + (int)(36*scale), drawX + (int)(62*scale), drawY + (int)(71*scale)); - } - if(c.y % 17 == 0) { - //top edge of sheet (edge 0 and possible 1 & 5) - boardGraph.drawLine(drawX + (int)(21*scale), drawY, drawX + (int)(62*scale), drawY); - if(c.x % 2 == 0) { - boardGraph.drawLine(drawX + (int)(62*scale), drawY, drawX + (int)(83*scale), drawY + (int)(35*scale)); - boardGraph.drawLine(drawX, drawY + (int)(35*scale), drawX + (int)(21*scale), drawY); - } - } else if (c.y % 17 == 16) { - //bottom edge of sheet (edge 3 and possible 2 & 4) - boardGraph.drawLine(drawX + (int)(62*scale), drawY + (int)(71*scale), drawX + (int)(21*scale), drawY + (int)(71*scale)); - if(c.x % 2 == 1) { - boardGraph.drawLine(drawX + (int)(83*scale), drawY + (int)(36*scale), drawX + (int)(62*scale), drawY + (int)(71*scale)); - boardGraph.drawLine(drawX + (int)(21*scale), drawY + (int)(71*scale), drawX, drawY + (int)(36*scale)); - } - } - boardGraph.setColor(Color.black); - } - } - - /** - * Returns true if an elevation line should be drawn between the starting - * hex and the hex in the direction specified. Results should be - * transitive, that is, if a line is drawn in one direction, it should be - * drawn in the opposite direction as well. - */ - private final boolean drawElevationLine(Coords src, int direction) { - final IHex srcHex = game.getBoard().getHex(src); - final IHex destHex = game.getBoard().getHexInDir(src, direction); - return destHex != null && srcHex.floor() != destHex.floor(); - } - - /** - * Returns the absolute position of the upper-left hand corner - * of the hex graphic - */ - private Point getHexLocation(int x, int y) { - return new Point( - x * (int)(HEX_WC*scale), - y * (int)(HEX_H*scale) + ((x & 1) == 1 ? (int)(HEX_H/2*scale) : 0)); - } - private Point getHexLocation(Coords c) { - return getHexLocation(c.x, c.y); - } - - // added by kenn - /** - * Returns the absolute position of the centre - * of the hex graphic - */ - private Point getCentreHexLocation(int x, int y) { - Point p = getHexLocation(x, y); - p.x += (HEX_W/2*scale); - p.y += (HEX_H/2*scale); - return p; - } - private Point getCentreHexLocation(Coords c) { - return getCentreHexLocation(c.x, c.y); - } - // end kenn - - /** - * Returns the coords at the specified point - */ - Coords getCoordsAt(Point p) { - final int x = (p.x + scroll.x - offset.x) / (int)(HEX_WC*scale); - final int y = ((p.y + scroll.y - offset.y) - ((x & 1) == 1 ? (int)(HEX_H/2*scale) : 0)) / (int)(HEX_H*scale); - return new Coords(x, y); - } - - /** - * Shows the tooltip thinger - */ - private void showTooltip() { - try { - final Point tipLoc = new Point(getLocationOnScreen()); - // retrieve tip text - String[] tipText = getTipText(mousePos); - if (tipText == null) { - return; - } - - // update tip text - tipWindow.removeAll(); - tipWindow.add(new TooltipCanvas(tipText)); - tipWindow.pack(); - - tipLoc.translate(mousePos.x, mousePos.y + 20); - - // adjust horizontal location for the tipWindow if it goes off the frame - if (frame.getLocation().x + frame.getSize().width < tipLoc.x + tipWindow.getSize().width + 10) { - if (frame.getSize().width > tipWindow.getSize().width) { - // bound it by the right edge of the frame - tipLoc.x -= tipLoc.x + tipWindow.getSize().width + 10 - frame.getSize().width - frame.getLocation().x; - } - else { - // too big to fit, left justify to the frame (roughly). - // how do I extract the first term of HEX_SIZE to use here?--LDE - tipLoc.x = getLocationOnScreen().x + hex_size.width; - } - } - - // set tip location - tipWindow.setLocation(tipLoc); - - tipWindow.show(); - } catch (Exception e) { - tipWindow = new Window(frame); - } - } - - /** - * The text to be displayed when the mouse is at a certain point - */ - private String[] getTipText(Point point) { - - int stringsSize = 0; - IHex mhex = null; - - // first, we have to determine how much text we are going to have - // are we on a hex? - final Coords mcoords = getCoordsAt(point); - if (GUIPreferences.getInstance().getShowMapHexPopup() && game.getBoard().contains(mcoords)) { - mhex = game.getBoard().getHex(mcoords); - stringsSize += 1; - } - - // check if it's on any entities - for (Iterator i = entitySprites.iterator(); i.hasNext();) { - final EntitySprite eSprite = (EntitySprite)i.next(); - if (eSprite.isInside(point)) { - stringsSize += 3; - } - } - - // check if it's on any attacks - for (Iterator i = attackSprites.iterator(); i.hasNext();) { - final AttackSprite aSprite = (AttackSprite)i.next(); - if (aSprite.isInside(point)) { - stringsSize += 1 + aSprite.weaponDescs.size(); - } - } - - // If the hex contains a building or rubble, make more space. - if ( mhex != null && - (mhex.containsTerrain(Terrains.RUBBLE) || - mhex.containsTerrain(Terrains.BUILDING)) ) { - stringsSize += 1; - } - - stringsSize += game.getNbrMinefields(mcoords); - - // Artillery - final Vector artilleryAttacks = getArtilleryAttacksAtLocation(mcoords); - stringsSize += artilleryAttacks.size(); - - // Artillery fire adjustment - final Mounted selectedWeapon = getSelectedArtilleryWeapon(); - if(selectedWeapon != null) - stringsSize++; - - // if the size is zip, you must a'quit - if (stringsSize == 0) { - return null; - } - - // now we can allocate an array of strings - String[] strings = new String[stringsSize]; - int stringsIndex = 0; - - // are we on a hex? - if (mhex != null) { - strings[stringsIndex] = Messages.getString("BoardView1.Hex") + mcoords.getBoardNum() //$NON-NLS-1$ - + Messages.getString("BoardView1.level") + mhex.getElevation(); //$NON-NLS-1$ - stringsIndex += 1; - - // Do we have rubble? - if ( mhex.containsTerrain(Terrains.RUBBLE) ) { - strings[stringsIndex] = Messages.getString("BoardView1.Rubble"); //$NON-NLS-1$ - stringsIndex += 1; - } - - // Do we have a building? - else if ( mhex.containsTerrain(Terrains.BUILDING) ) { - // Get the building. - Building bldg = game.getBoard().getBuildingAt( mcoords ); - StringBuffer buf = new StringBuffer( Messages.getString("BoardView1.Height") ); //$NON-NLS-1$ - // Each hex of a building has its own elevation. - buf.append( mhex.terrainLevel(Terrains.BLDG_ELEV) ); - buf.append( " " ); //$NON-NLS-1$ - buf.append( bldg.toString() ); - buf.append( Messages.getString("BoardView1.CF") ); //$NON-NLS-1$ - buf.append( bldg.getCurrentCF() ); - strings[stringsIndex] = buf.toString(); - stringsIndex += 1; - } - - if (game.containsMinefield(mcoords)) { - java.util.Vector minefields = game.getMinefields(mcoords); - for (int i = 0; i < minefields.size(); i++){ - Minefield mf = (Minefield) minefields.elementAt(i); - String owner = " (" + game.getPlayer(mf.getPlayerId()).getName() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - - switch (mf.getType()) { - case (Minefield.TYPE_CONVENTIONAL) : - strings[stringsIndex] = mf.getName()+Messages.getString("BoardView1.minefield") +" " + owner; //$NON-NLS-1$ //$NON-NLS-2$ - break; - case (Minefield.TYPE_THUNDER) : - strings[stringsIndex] = mf.getName()+Messages.getString("BoardView1.minefield")+"(" + mf.getDamage() + ")" + owner; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - break; - case (Minefield.TYPE_COMMAND_DETONATED) : - strings[stringsIndex] = mf.getName()+Messages.getString("BoardView1.minefield") +" " + owner; //$NON-NLS-1$ //$NON-NLS-2$ - break; - case (Minefield.TYPE_VIBRABOMB) : - if (mf.getPlayerId() == localPlayer.getId()) { - strings[stringsIndex] = mf.getName()+Messages.getString("BoardView1.minefield")+"(" + mf.getSetting() + ") " + owner; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } else { - strings[stringsIndex] = mf.getName()+Messages.getString("BoardView1.minefield") + " " + owner; //$NON-NLS-1$ //$NON-NLS-2$ - } - break; - case (Minefield.TYPE_THUNDER_ACTIVE) : - strings[stringsIndex] = mf.getName()+Messages.getString("BoardView1.minefield")+"(" + mf.getDamage() + ")" + owner; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - break; - case (Minefield.TYPE_THUNDER_INFERNO) : - strings[stringsIndex] = mf.getName()+Messages.getString("BoardView1.minefield")+"(" + mf.getDamage() + ")" + owner; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - break; - } - stringsIndex++; - } - } - } - // check if it's on any entities - for (Iterator i = entitySprites.iterator(); i.hasNext();) { - final EntitySprite eSprite = (EntitySprite)i.next(); - if (eSprite.isInside(point)) { - final String[] entityStrings = eSprite.getTooltip(); - java.lang.System.arraycopy(entityStrings, 0, strings, stringsIndex, entityStrings.length); - stringsIndex += entityStrings.length; - } - } - - // check if it's on any attacks - for (Iterator i = attackSprites.iterator(); i.hasNext();) { - final AttackSprite aSprite = (AttackSprite)i.next(); - if (aSprite.isInside(point)) { - final String[] attackStrings = aSprite.getTooltip(); - java.lang.System.arraycopy(attackStrings, 0, strings, stringsIndex, attackStrings.length); - stringsIndex += 1 + aSprite.weaponDescs.size(); - } - } - - // check artillery attacks - for(Iterator i = artilleryAttacks.iterator(); i.hasNext();) { - final ArtilleryAttackAction aaa = (ArtilleryAttackAction)i.next(); - final WeaponResult wr = aaa.getWR(); - final Entity ae = game.getEntity(wr.waa.getEntityId()); - String s = null; - if(ae != null) { - if(wr.waa.getWeaponId() > -1) { - Mounted weap = ae.getEquipment(wr.waa.getWeaponId()); - s = weap.getName(); - if(wr.waa.getAmmoId() > -1) { - Mounted ammo = ae.getEquipment(wr.waa.getAmmoId()); - s += "(" + ammo.getName() + ")"; - } - } - } - if(s == null) { - s = Messages.getString("BoardView1.Artillery"); - } - strings[stringsIndex++] = Messages.getString("BoardView1.ArtilleryAttack", - new Object[] { s, new Integer(aaa.turnsTilHit), wr.toHit.getValueAsString() } ); - } - //check artillery fire adjustment - final Entity selectedEntity = clientgui.mechD.getCurrentEntity(); - if(selectedWeapon != null && selectedEntity != null) { - //process targetted hexes - int amod = 0; - //Check the predesignated hexes - if(selectedEntity.getOwner().getArtyAutoHitHexes().contains(mcoords)) { - amod = TargetRoll.AUTOMATIC_SUCCESS; - } - else { - amod = selectedEntity.aTracker.getModifier(selectedWeapon, mcoords); - } - - if(amod==TargetRoll.AUTOMATIC_SUCCESS) { - strings[stringsIndex++] = Messages.getString("BoardView1.ArtilleryAutohit"); - } else { - strings[stringsIndex++] = Messages.getString("BoardView1.ArtilleryAdjustment", new Object[] { new Integer(amod) } ); - } - } - return strings; - } - - /** - * Hides the tooltip thinger - */ - public void hideTooltip() { - tipWindow.setVisible(false); - } - - /** - * Returns true if the tooltip is showing - */ - private boolean isTipShowing() { - return tipWindow.isShowing(); - } - - /** - * Checks if the mouse has been idling for a while and if so, shows the - * tooltip window - */ - private void checkTooltip() { - if (isTipShowing()) { - if (!isTipPossible) { - hideTooltip(); - } - } else if (isTipPossible && System.currentTimeMillis() - lastIdle > GUIPreferences.getInstance().getTooltipDelay()) { - showTooltip(); - } - } - - public void redrawMovingEntity(Entity entity, Coords position, int facing) { - Integer entityId = new Integer( entity.getId() ); - EntitySprite sprite = (EntitySprite) entitySpriteIds.get( entityId ); - Vector newSprites; - Hashtable newSpriteIds; - - if (sprite != null) { - newSprites = new Vector(entitySprites); - newSpriteIds = new Hashtable(entitySpriteIds); - - newSprites.removeElement(sprite); - - entitySprites = newSprites; - entitySpriteIds = newSpriteIds; - } - - MovingEntitySprite mSprite = - (MovingEntitySprite) movingEntitySpriteIds.get( entityId ); - newSprites = new Vector(movingEntitySprites); - newSpriteIds = new Hashtable(movingEntitySpriteIds); - - - if (mSprite != null) { - newSprites.removeElement(mSprite); - } - - if (entity.getPosition() != null) { - mSprite = new MovingEntitySprite(entity, position, facing); - newSprites.addElement(mSprite); - newSpriteIds.put( entityId, mSprite ); - } - - movingEntitySprites = newSprites; - movingEntitySpriteIds = newSpriteIds; - } - - public boolean isMovingUnits() { - return movingUnits.size() > 0; - } - - /** - * Clears the sprite for an entity and prepares it to be re-drawn. - * Replaces the old sprite with the new! - * - * Try to prevent annoying ConcurrentModificationExceptions - */ - public void redrawEntity(Entity entity) { - Integer entityId = new Integer( entity.getId() ); - EntitySprite sprite = (EntitySprite)entitySpriteIds.get( entityId ); - Vector newSprites = new Vector(entitySprites); - Hashtable newSpriteIds = new Hashtable(entitySpriteIds); - - - if (sprite != null) { - newSprites.removeElement(sprite); - } - Coords position = entity.getPosition(); - if (position != null) { - /*drawHex(position); - IHex foo = game.getBoard().getHex(position); - foo.markChanged(); */// TODO: Is this really necessary? - - sprite = new EntitySprite(entity); - newSprites.addElement(sprite); - newSpriteIds.put( entityId, sprite ); - } - - entitySprites = newSprites; - entitySpriteIds = newSpriteIds; - - for (java.util.Enumeration i = C3Sprites.elements(); i.hasMoreElements();) { - final C3Sprite c3sprite = (C3Sprite)i.nextElement(); - if (c3sprite.entityId == entity.getId()) - C3Sprites.removeElement(c3sprite); - else if(c3sprite.masterId == entity.getId()) { - // Only redraw client-to-master; otherwise - // we leave stray lines when we move. - if(entity.hasC3()) { - C3Sprites.addElement(new C3Sprite(game.getEntity(c3sprite.entityId), game.getEntity(c3sprite.masterId))); - } - C3Sprites.removeElement(c3sprite); - - } - } - - if(entity.hasC3() || entity.hasC3i()) addC3Link(entity); - - repaint(100); - } - - /** - * Clears all old entity sprites out of memory and sets up new ones. - */ - private void redrawAllEntities() { - Vector newSprites = new Vector(game.getNoOfEntities()); - Hashtable newSpriteIds = new Hashtable(game.getNoOfEntities()); - Vector newWrecks = new Vector(); - - Enumeration e = game.getWreckedEntities(); - while (e.hasMoreElements()) { - Entity entity = (Entity) e.nextElement(); - if (!(entity instanceof Infantry) && (entity.getPosition() != null)) { - WreckSprite ws = new WreckSprite(entity); - newWrecks.addElement(ws); - } - } - - clearC3Networks(); - for (java.util.Enumeration i = game.getEntities(); i.hasMoreElements();) { - final Entity entity = (Entity)i.nextElement(); - if (entity.getPosition() == null) continue; - - EntitySprite sprite = new EntitySprite(entity); - newSprites.add(sprite); - newSpriteIds.put(new Integer(entity.getId()), sprite); - - if(entity.hasC3() || entity.hasC3i()) addC3Link(entity); - } - - entitySprites = newSprites; - entitySpriteIds = newSpriteIds; - wreckSprites = newWrecks; - - repaint(100); - } - - /** - * Moves the cursor to the new position, or hides it, if newPos is null - */ - private void moveCursor(CursorSprite cursor, Coords newPos) { - final Rectangle oldBounds = new Rectangle(cursor.getBounds()); - if (newPos != null) { - //cursor.setLocation(getHexLocation(newPos)); - cursor.setHexLocation(newPos); - } else { - cursor.setOffScreen(); - } - // repaint affected area - repaintBounds(oldBounds); - repaintBounds(cursor.getBounds()); - } - - - public void centerOnHex(Coords c) { - if ( null == c ) return; - scroll.setLocation(getHexLocation(c)); - scroll.translate((int)(42*scale) - (view.width / 2), (int)(36*scale) - (view.height / 2)); - - isScrolling = false; - checkScrollBounds(); - repaint(); - } - - /** - * Clears the old movement data and draws the new. Since it's less - * expensive to check for and reuse old step sprites than to make a whole - * new one, we do that. - */ - public void drawMovementData(Entity entity, MovePath md) { - Vector temp = pathSprites; - - clearMovementData(); - - for (java.util.Enumeration i = md.getSteps(); i.hasMoreElements();) { - final MoveStep step = (MoveStep)i.nextElement(); - // check old movement path for reusable step sprites - boolean found = false; - for (Iterator j = temp.iterator(); j.hasNext();) { - final StepSprite sprite = (StepSprite)j.next(); - if (sprite.getStep().canReuseSprite(step)) { - pathSprites.addElement(sprite); - found = true; - } - } - if (!found) { - pathSprites.addElement(new StepSprite(step)); - } - } - } - - /** - * Clears current movement data from the screen - */ - public void clearMovementData() { - Vector temp = pathSprites; - pathSprites = new Vector(); - for (Iterator i = temp.iterator(); i.hasNext();) { - final Sprite sprite = (Sprite)i.next(); - repaintBounds(sprite.getBounds()); - } - } - - public void setLocalPlayer(Player p) { - localPlayer = p; - } - - public Player getLocalPlayer() { - return localPlayer; - } - - /** - * Specifies that this should mark the deployment hexes for a player. If - * the player is set to null, no hexes will be marked. - */ - public void markDeploymentHexesFor(Player p) - { - m_plDeployer = p; - } - - /** - * Adds a c3 line to the sprite list. - */ - public void addC3Link(Entity e) { - if (e.getPosition() == null) return; - - if(e.hasC3i()) { - for (java.util.Enumeration i = game.getEntities(); i.hasMoreElements();) { - final Entity fe = (Entity)i.nextElement(); - if (fe.getPosition() == null) return; - if ( e.onSameC3NetworkAs(fe)) { - C3Sprites.addElement(new C3Sprite(e, fe)); - } - } - } - else if(e.getC3Master() != null) { - Entity eMaster = e.getC3Master(); - if (eMaster.getPosition() == null) return; - - // ECM cuts off the network - if (!Compute.isAffectedByECM(e, e.getPosition(), eMaster.getPosition())) { - C3Sprites.addElement(new C3Sprite(e, e.getC3Master())); - } - } - } - - /** - * Adds an attack to the sprite list. - */ - public void addAttack(AttackAction aa) { - // do not make a sprite unless we're aware of both entities - // this is not a great solution but better than a crash - Entity ae = game.getEntity(aa.getEntityId()); - Targetable t = game.getTarget(aa.getTargetType(), aa.getTargetId()); - if (ae == null || t == null || t.getTargetType() == Targetable.TYPE_INARC_POD) { - return; - } - - for (final Iterator i = attackSprites.iterator(); i.hasNext();) { - final AttackSprite sprite = (AttackSprite)i.next(); - - // can we just add this attack to an existing one? - if (sprite.getEntityId() == aa.getEntityId() - && sprite.getTargetId() == aa.getTargetId()) { - // use existing attack, but add this weapon - if (aa instanceof WeaponAttackAction) { - WeaponAttackAction waa = (WeaponAttackAction)aa; - if ( aa.getTargetType() != Targetable.TYPE_HEX_ARTILLERY - && aa.getTargetType() != Targetable.TYPE_HEX_FASCAM - && aa.getTargetType() != Targetable.TYPE_HEX_INFERNO_IV - && aa.getTargetType() != Targetable.TYPE_HEX_VIBRABOMB_IV) { - sprite.addWeapon(waa); - } else if ( waa.getEntity(game).getOwner().getId() == localPlayer.getId()) { - sprite.addWeapon(waa); - } - } - if (aa instanceof KickAttackAction) { - sprite.addWeapon((KickAttackAction)aa); - } - if (aa instanceof PunchAttackAction) { - sprite.addWeapon((PunchAttackAction)aa); - } - if (aa instanceof PushAttackAction) { - sprite.addWeapon((PushAttackAction)aa); - } - if (aa instanceof ClubAttackAction) { - sprite.addWeapon((ClubAttackAction)aa); - } - if (aa instanceof ChargeAttackAction) { - sprite.addWeapon((ChargeAttackAction)aa); - } - if (aa instanceof DfaAttackAction) { - sprite.addWeapon((DfaAttackAction)aa); - } - if (aa instanceof ProtomechPhysicalAttackAction) { - sprite.addWeapon((ProtomechPhysicalAttackAction)aa); - } - return; - } - } - // no re-use possible, add a new one - // don't add a sprite for an artillery attack made by the other player - if (aa instanceof WeaponAttackAction) { - WeaponAttackAction waa = (WeaponAttackAction)aa; - if ( aa.getTargetType() != Targetable.TYPE_HEX_ARTILLERY - && aa.getTargetType() != Targetable.TYPE_HEX_FASCAM - && aa.getTargetType() != Targetable.TYPE_HEX_INFERNO_IV - && aa.getTargetType() != Targetable.TYPE_HEX_VIBRABOMB_IV) { - attackSprites.addElement(new AttackSprite(aa)); - } else if ( waa.getEntity(game).getOwner().getId() == localPlayer.getId()) { - attackSprites.addElement(new AttackSprite(aa)); - } - } else { - attackSprites.addElement(new AttackSprite(aa)); - } - } - - /** Removes all attack sprites from a certain entity */ - public void removeAttacksFor(int entityId) { - // or rather, only keep sprites NOT for that entity - Vector toKeep = new Vector(attackSprites.size()); - for (Iterator i = attackSprites.iterator(); i.hasNext();) { - AttackSprite sprite = (AttackSprite)i.next(); - if (sprite.getEntityId() != entityId) { - toKeep.addElement(sprite); - } - } - this.attackSprites = toKeep; - } - - /** - * Clears out all attacks and re-adds the ones in the current game. - */ - public void refreshAttacks() { - clearAllAttacks(); - for (Enumeration i = game.getActions(); i.hasMoreElements();) { - EntityAction ea = (EntityAction)i.nextElement(); - if (ea instanceof AttackAction) { - addAttack((AttackAction)ea); - } - } - for (Enumeration i = game.getCharges(); i.hasMoreElements();) { - EntityAction ea = (EntityAction)i.nextElement(); - if (ea instanceof AttackAction) { - addAttack((AttackAction)ea); - } - } - } - - public void clearC3Networks() { - C3Sprites.removeAllElements(); - } - - /** - * Clears out all attacks that were being drawn - */ - public void clearAllAttacks() { - attackSprites.removeAllElements(); - } - - public Image baseFor(IHex hex) { - return tileManager.baseFor(hex); - } - - public com.sun.java.util.collections.List supersFor(IHex hex) { - return tileManager.supersFor(hex); - } - - protected void firstLOSHex(Coords c) { - if (useLOSTool) { - moveCursor(secondLOSSprite, null); - moveCursor(firstLOSSprite, c); - } - } - - protected void secondLOSHex(Coords c2, Coords c1) { - if (useLOSTool) { - moveCursor(firstLOSSprite, c1); - moveCursor(secondLOSSprite, c2); - - boolean mechInFirst = GUIPreferences.getInstance().getMechInFirst(); - boolean mechInSecond = GUIPreferences.getInstance().getMechInSecond(); - - LosEffects.AttackInfo ai = new LosEffects.AttackInfo(); - ai.attackPos = c1; - ai.targetPos = c2; - ai.attackHeight = mechInFirst?1:0; - ai.targetHeight = mechInSecond?1:0; - ai.attackAbsHeight = game.getBoard().getHex(c1).floor() + ai.attackHeight; - ai.targetAbsHeight = game.getBoard().getHex(c2).floor() + ai.targetHeight; - - LosEffects le = LosEffects.calculateLos(game, ai); - StringBuffer message = new StringBuffer(); - message.append(Messages.getString("BoardView1.Attacker", new Object[]{ //$NON-NLS-1$ - mechInFirst ? Messages.getString("BoardView1.Mech") : Messages.getString("BoardView1.NonMech"), //$NON-NLS-1$ //$NON-NLS-2$ - c1.getBoardNum()})); - message.append(Messages.getString("BoardView1.Target", new Object[]{ //$NON-NLS-1$ - mechInSecond ? Messages.getString("BoardView1.Mech") : Messages.getString("BoardView1.NonMech"), //$NON-NLS-1$ //$NON-NLS-2$ - c1.getBoardNum()})); - if (!le.canSee()) { - message.append(Messages.getString("BoardView1.LOSBlocked", new Object[]{ //$NON-NLS-1$ - new Integer(c1.distance(c2))})); - } else { - message.append(Messages.getString("BoardView1.LOSNotBlocked", new Object[]{ //$NON-NLS-1$ - new Integer(c1.distance(c2))})); - if (le.getHeavyWoods() > 0) { - message.append(Messages.getString("BoardView1.HeavyWoods", new Object[]{ //$NON-NLS-1$ - new Integer(le.getHeavyWoods())})); - } - if (le.getLightWoods() > 0) { - message.append(Messages.getString("BoardView1.LightWoods", new Object[]{ //$NON-NLS-1$ - new Integer(le.getLightWoods())})); - } - if (le.getLightSmoke() > 0) { - message.append(Messages.getString("BoardView1.LightSmoke", new Object[]{ //$NON-NLS-1$ - new Integer(le.getLightSmoke())})); - } - if (le.getHeavySmoke() > 0) { - if (game.getOptions().booleanOption("maxtech_fire")) { //$NON-NLS-1$ - message.append(Messages.getString("BoardView1.HeavySmoke", new Object[]{ //$NON-NLS-1$ - new Integer(le.getHeavySmoke())})); - } - else { - message.append(Messages.getString("BoardView1.Smoke", new Object[]{ //$NON-NLS-1$ - new Integer(le.getHeavySmoke())})); - } - } - if (le.isTargetCover()) { - message.append(Messages.getString("BoardView1.TargetPartialCover")); //$NON-NLS-1$ - } - if (le.isAttackerCover()) { - message.append(Messages.getString("BoardView1.AttackerPartialCover")); //$NON-NLS-1$ - } - } - AlertDialog alert = new AlertDialog(frame, - Messages.getString("BoardView1.LOSTitle"), //$NON-NLS-1$ - message.toString(), false); - alert.show(); - } - } - - /** - * If the mouse is at the edges of the screen, this - * scrolls the board image on the canvas. - * NOTE: CTL scroll is handled in mouseMoved() - */ - public boolean doScroll() { - final Point oldScroll = new Point(scroll); - boolean s = false; - - if ( isScrolling && GUIPreferences.getInstance().getRightDragScroll()) { - if (! (oldMousePosition == null || mousePos.equals(oldMousePosition)) ) { - scroll.x -= GUIPreferences.getInstance().getScrollSensitivity() * (mousePos.x - oldMousePosition.x); - scroll.y -= GUIPreferences.getInstance().getScrollSensitivity() * (mousePos.y - oldMousePosition.y); - checkScrollBounds(); - oldMousePosition.setLocation(mousePos); - s = !oldScroll.equals(scroll); - scrolled = scrolled || s; - } - } - - if (isScrolling && (GUIPreferences.getInstance().getClickEdgeScroll() ||GUIPreferences.getInstance().getAutoEdgeScroll()) ) { - final int sf = GUIPreferences.getInstance().getScrollSensitivity(); // scroll factor - // adjust x scroll - // scroll when the mouse is at the edges - if (mousePos.x < 100) { - scroll.x -= (100 - mousePos.x) / sf; - } else if (mousePos.x > (backSize.width - 100)) { - scroll.x -= ((backSize.width - 100) - mousePos.x) / sf; - } - // scroll when the mouse is at the edges - if (mousePos.y < 100) { - scroll.y -= (100 - mousePos.y) / sf; - } else if (mousePos.y > (backSize.height - 100)) { - scroll.y -= ((backSize.height - 100) - mousePos.y) / sf; - } - checkScrollBounds(); - if (!oldScroll.equals(scroll)) { - // repaint(); - s = true; - scrolled = s; - } - } - - return s; - } - - /** - * Makes sure that the scroll dimensions stay in bounds - */ - public void checkScrollBounds() { - if (scroll.x < 0) { - scroll.x = 0; - } else if (scroll.x > (boardSize.width - view.width)) { - scroll.x = (boardSize.width - view.width); - } - - if (scroll.y < 0) { - scroll.y = 0; - } else if (scroll.y > (boardSize.height - view.height)) { - scroll.y = (boardSize.height - view.height); - } - - // Update our scroll bars. - if (null != this.vScrollbar) { - this.vScrollbar.setValue (scroll.y); - } - if (null != this.hScrollbar) { - this.hScrollbar.setValue (scroll.x); - } - } - - protected void stopScrolling() { - isScrolling = false; - } - - /** - * Initializes the various overlay polygons with their - * vertices. - */ - public void initPolys() { - // hex polygon - hexPoly = new Polygon(); - hexPoly.addPoint(21, 0); - hexPoly.addPoint(62, 0); - hexPoly.addPoint(83, 35); - hexPoly.addPoint(83, 36); - hexPoly.addPoint(62, 71); - hexPoly.addPoint(21, 71); - hexPoly.addPoint(0, 36); - hexPoly.addPoint(0, 35); - - // facing polygons - facingPolys = new Polygon[6]; - facingPolys[0] = new Polygon(); - facingPolys[0].addPoint(41, 3); - facingPolys[0].addPoint(38, 6); - facingPolys[0].addPoint(45, 6); - facingPolys[0].addPoint(42, 3); - facingPolys[1] = new Polygon(); - facingPolys[1].addPoint(69, 17); - facingPolys[1].addPoint(64, 17); - facingPolys[1].addPoint(68, 23); - facingPolys[1].addPoint(70, 19); - facingPolys[2] = new Polygon(); - facingPolys[2].addPoint(69, 53); - facingPolys[2].addPoint(68, 49); - facingPolys[2].addPoint(64, 55); - facingPolys[2].addPoint(68, 54); - facingPolys[3] = new Polygon(); - facingPolys[3].addPoint(41, 68); - facingPolys[3].addPoint(38, 65); - facingPolys[3].addPoint(45, 65); - facingPolys[3].addPoint(42, 68); - facingPolys[4] = new Polygon(); - facingPolys[4].addPoint(15, 53); - facingPolys[4].addPoint(18, 54); - facingPolys[4].addPoint(15, 48); - facingPolys[4].addPoint(14, 52); - facingPolys[5] = new Polygon(); - facingPolys[5].addPoint(13, 19); - facingPolys[5].addPoint(15, 23); - facingPolys[5].addPoint(19, 17); - facingPolys[5].addPoint(17, 17); - - // movement polygons - movementPolys = new Polygon[8]; - movementPolys[0] = new Polygon(); - movementPolys[0].addPoint(41, 65); - movementPolys[0].addPoint(38, 68); - movementPolys[0].addPoint(45, 68); - movementPolys[0].addPoint(42, 65); - movementPolys[1] = new Polygon(); - movementPolys[1].addPoint(17, 48); - movementPolys[1].addPoint(12, 48); - movementPolys[1].addPoint(16, 54); - movementPolys[1].addPoint(17, 49); - movementPolys[2] = new Polygon(); - movementPolys[2].addPoint(18, 19); - movementPolys[2].addPoint(17, 15); - movementPolys[2].addPoint(13, 21); - movementPolys[2].addPoint(17, 20); - movementPolys[3] = new Polygon(); - movementPolys[3].addPoint(41, 6); - movementPolys[3].addPoint(38, 3); - movementPolys[3].addPoint(45, 3); - movementPolys[3].addPoint(42, 6); - movementPolys[4] = new Polygon(); - movementPolys[4].addPoint(67, 15); - movementPolys[4].addPoint(66, 19); - movementPolys[4].addPoint(67, 20); - movementPolys[4].addPoint(71, 20); - movementPolys[5] = new Polygon(); - movementPolys[5].addPoint(69, 55); - movementPolys[5].addPoint(66, 50); - movementPolys[5].addPoint(67, 49); - movementPolys[5].addPoint(72, 48); - - movementPolys[6] = new Polygon(); // up arrow with tail - movementPolys[6].addPoint(35, 44); - movementPolys[6].addPoint(30, 49); - movementPolys[6].addPoint(33, 49); - movementPolys[6].addPoint(33, 53); - movementPolys[6].addPoint(38, 53); - movementPolys[6].addPoint(38, 49); - movementPolys[6].addPoint(41, 49); - movementPolys[6].addPoint(36, 44); - movementPolys[7] = new Polygon(); // down arrow with tail - movementPolys[7].addPoint(34, 53); - movementPolys[7].addPoint(29, 48); - movementPolys[7].addPoint(32, 48); - movementPolys[7].addPoint(32, 44); - movementPolys[7].addPoint(37, 44); - movementPolys[7].addPoint(37, 48); - movementPolys[7].addPoint(40, 48); - movementPolys[7].addPoint(35, 53); - } - - private synchronized boolean doMoveUnits(long idleTime) { - boolean movingSomething = false; - - if (movingUnits.size() > 0) { - - moveWait += idleTime; - - if (moveWait > GUIPreferences.getInstance().getInt("AdvancedMoveStepDelay")) { - - java.util.Vector spent = new java.util.Vector(); - - for (int i = 0; i < movingUnits.size(); i++) { - Object[] move = (Object[]) movingUnits.elementAt(i); - Entity e = (Entity) move[0]; - java.util.Vector movePath = (java.util.Vector) move[1]; - movingSomething = true; - Entity ge = game.getEntity(e.getId()); - if (movePath.size() > 0) { - UnitLocation loc = - ( (UnitLocation) movePath.elementAt(0) ); - if (ge != null) { - redrawMovingEntity( e, - loc.getCoords(), - loc.getFacing() ); - } - movePath.removeElementAt(0); - } else { - if (ge != null) { - redrawEntity(ge); - } - spent.addElement(move); - } - - } - - for (int i = 0; i < spent.size(); i++) { - Object[] move = (Object[]) spent.elementAt(i); - movingUnits.removeElement(move); - } - moveWait = 0; - - if (movingUnits.size() == 0) { - movingEntitySpriteIds.clear(); - movingEntitySprites.removeAllElements(); - ghostEntitySprites.removeAllElements(); - processBoardViewEvent(new BoardViewEvent(this, BoardViewEvent.FINISHED_MOVING_UNITS)); - } - } - } - return movingSomething; - } - - // - // KeyListener - // - public void keyPressed(KeyEvent ke) { - switch(ke.getKeyCode()) { - case KeyEvent.VK_NUMPAD7 : - scroll.y -= 36; - scroll.x -= 36; - break; - case KeyEvent.VK_NUMPAD8 : - scroll.y -= 36; - break; - case KeyEvent.VK_NUMPAD9 : - scroll.y -= 36; - scroll.x += 36; - break; - case KeyEvent.VK_NUMPAD1 : - scroll.y += 36; - scroll.x -= 36; - break; - case KeyEvent.VK_NUMPAD2 : - scroll.y += 36; - break; - case KeyEvent.VK_NUMPAD3 : - scroll.y += 36; - scroll.x += 36; - break; - case KeyEvent.VK_NUMPAD4 : - scroll.x -= 36; - break; - case KeyEvent.VK_NUMPAD6 : - scroll.x += 36; - break; - case KeyEvent.VK_NUMPAD5 : - // center on the selected entity - java.util.Vector v = game.getPlayerEntities(localPlayer); - Entity se = clientgui == null?null:game.getEntity(clientgui.getSelectedEntityNum()); - for (int i = 0; i < v.size(); i++) { - Entity e = (Entity) v.elementAt(i); - if (e==se) { - centerOnHex(e.getPosition()); - } - } - break; - case KeyEvent.VK_CONTROL : - ctlKeyHeld = true; - initCtlScroll = true; - break; - } - - if (isTipShowing()) { - hideTooltip(); - } - lastIdle = System.currentTimeMillis(); - checkScrollBounds(); - repaint(); - } - - public void keyReleased(KeyEvent ke) { - if (ke.getKeyCode() == KeyEvent.VK_CONTROL) { - ctlKeyHeld = false; - } - } - public void keyTyped(KeyEvent ke) { - } - - // - // MouseListener - // - public void mousePressed(MouseEvent me) { - scrolled = false; // not scrolled yet - - Point point = me.getPoint(); - if ( null == point ) { - return; - } - oldMousePosition = point; - - isTipPossible = false; - for (int i = 0; i < displayables.size(); i++) { - Displayable disp = (Displayable) displayables.elementAt(i); - if (disp.isHit(point, backSize)) { - return; - } - } - - // Disable scrolling when ctrl or alt is held down, since this - // means the user wants to use the LOS/ruler tools. - int mask = InputEvent.CTRL_MASK | InputEvent.ALT_MASK; - if ( !GUIPreferences.getInstance().getRightDragScroll() && - !GUIPreferences.getInstance().getAlwaysRightClickScroll() && - game.getPhase() == IGame.PHASE_FIRING ) { - // In the firing phase, also disable scrolling if - // the right or middle buttons are clicked, since - // this means the user wants to activate the - // popup menu or ruler tool. - mask |= InputEvent.BUTTON2_MASK | InputEvent.BUTTON3_MASK; - } - - // disable auto--edge-scrolling if no option set - if ( !GUIPreferences.getInstance().getAutoEdgeScroll() ) { - mask |= InputEvent.BUTTON1_MASK; - } - // disable edge-scrolling if no option set - if ( !GUIPreferences.getInstance().getClickEdgeScroll() ) { - mask |= InputEvent.BUTTON3_MASK; - } - - if ( GUIPreferences.getInstance().getRightDragScroll() ) { - mask |= InputEvent.BUTTON2_MASK; - } - - if ( (me.getModifiers() & mask ) == 0 ) { - isScrolling = true; //activate scrolling - } else { - isScrolling = false; //activate scrolling - } - - if (isTipShowing()) { - hideTooltip(); - } - - mouseAction(getCoordsAt(point), BOARD_HEX_DRAG, me.getModifiers()); - } - - public void mouseReleased(MouseEvent me) { - isTipPossible = true; - oldMousePosition = mousePos; - - for (int i = 0; i < displayables.size(); i++) { - Displayable disp = (Displayable) displayables.elementAt(i); - if (disp.isReleased()) { - return; - } - } - isScrolling = false; - - // no click action triggered if click was for scrolling the map. Real clicks are without scrolling. - if (scrolled) - return; - if (me.getClickCount() == 1) { - mouseAction(getCoordsAt(me.getPoint()), BOARD_HEX_CLICK, me.getModifiers()); - } else { - mouseAction(getCoordsAt(me.getPoint()), BOARD_HEX_DOUBLECLICK, me.getModifiers()); - } - } - - public void mouseEntered(MouseEvent me) { - } - - public void mouseExited(MouseEvent me) { - isTipPossible = false; - } - public void mouseClicked(MouseEvent me) { - } - - // - // MouseMotionListener - // - public void mouseDragged(MouseEvent me) { - isTipPossible = false; - - Point point = me.getPoint(); - if ( null == point ) { - return; - } - - for (int i = 0; i < displayables.size(); i++) { - Displayable disp = (Displayable) displayables.elementAt(i); - if (disp.isDragged(point, backSize)) { - repaint(); - return; - } - } - mousePos = point; - - // Disable scrolling when ctrl or alt is held down, since this - // means the user wants to use the LOS/ruler tools. - int mask = InputEvent.CTRL_MASK | InputEvent.ALT_MASK; - - if ( !GUIPreferences.getInstance().getRightDragScroll() && - !GUIPreferences.getInstance().getAlwaysRightClickScroll() && - game.getPhase() == IGame.PHASE_FIRING) { - // In the firing phase, also disable scrolling if - // the right or middle buttons are clicked, since - // this means the user wants to activate the - // popup menu or ruler tool. - mask |= InputEvent.BUTTON2_MASK | InputEvent.BUTTON3_MASK; - } - - if ( GUIPreferences.getInstance().getRightDragScroll() ) { - mask |= InputEvent.BUTTON1_MASK | InputEvent.BUTTON2_MASK; - } - - // disable auto--edge-scrolling if no option set - if ( !GUIPreferences.getInstance().getAutoEdgeScroll() ) { - mask |= InputEvent.BUTTON1_MASK; - } - - // disable edge-scrolling if no option set - if ( !GUIPreferences.getInstance().getClickEdgeScroll() && !GUIPreferences.getInstance().getRightDragScroll() ) { - mask |= InputEvent.BUTTON3_MASK; - } - - if ( (me.getModifiers() & mask ) == 0 ) { - isScrolling = true; //activate scrolling - } else { - isScrolling = false; //activate scrolling - } - - mouseAction(getCoordsAt(point), BOARD_HEX_DRAG, me.getModifiers()); - } - - public void mouseMoved(MouseEvent me) { - Point point = me.getPoint(); - if ( null == point ) { - return; - } - - for (int i = 0; i < displayables.size(); i++) { - Displayable disp = (Displayable) displayables.elementAt(i); - if (disp.isBeingDragged()) { - isTipPossible = false; - return; - } - if (backSize != null) { - disp.isMouseOver(point, backSize); - } - } - mousePos = point; - if (isTipShowing()) { - hideTooltip(); - } - if (ctlKeyHeld && GUIPreferences.getInstance().getCtlScroll()) { - if (initCtlScroll) { - previousMouseX = me.getX(); - previousMouseY = me.getY(); - initCtlScroll = false; - } - scroll.x += GUIPreferences.getInstance().getScrollSensitivity() * (me.getX() - previousMouseX); - scroll.y += GUIPreferences.getInstance().getScrollSensitivity() * (me.getY() - previousMouseY); - previousMouseX = me.getX(); - previousMouseY = me.getY(); - checkScrollBounds(); - repaint(); - } - lastIdle = System.currentTimeMillis(); - isTipPossible = true; - } - - /** - * Increases zoomIndex and refreshes the map. - * - */ - public void zoomIn(){ - int tmpZoomIndex = zoomIndex + 1; - if ( isJ2RE == true ){ - zoomIndex++; - zoom(); - } - } - - /** - * Decreases zoomIndex and refreshes the map. - * - */ - public void zoomOut(){ - if ( isJ2RE == true ){ - zoomIndex--; - zoom(); - } - } - - /** - * zoomIndex is a reference to a static array of scale factors. - * The index ranges from 0 to 9 and by default is set to 7 which corresponds - * to a scale of 1.0 (draws megamek images at normal size). To zoom out the - * index needs to be set to a lower value. To zoom in make it larger. - * If only zooming a step at a time use the zoomIn and zoomOut methods instead. - * - * @param zoomIndex - */ - public void setZoomIndex( int zoomIndex ){ - if ( isJ2RE == true ){ - this.zoomIndex = zoomIndex; - zoom(); - } - } - - public int getZoomIndex(){ - return zoomIndex; - } - - private void checkZoomIndex(){ - if ( zoomIndex > ZOOM_FACTORS.length-1 ) { - zoomIndex = ZOOM_FACTORS.length-1; - } - if ( zoomIndex < 0 ) zoomIndex = 0; - } - - // - // Changes hex dimensions and refreshes the map with the new scale - // - private void zoom(){ - checkZoomIndex(); - scale = ZOOM_FACTORS[zoomIndex]; - GUIPreferences.getInstance().setMapZoomIndex(zoomIndex); - - hex_size = new Dimension((int)(HEX_W*scale), (int)(HEX_H*scale)); - - final Dimension size = getSize(); - //Coords c = getCoordsAt(new Point((int)(size.width/2), (int)(size.height/2))); - - boardGraph=null; - backGraph=null; - hasZoomed=true; - - updateBoardSize(); - - view.setLocation(scroll); - view.setSize(getOptimalView(size)); - offset.setLocation(getOptimalOffset(size)); - - updateFontSizes(); - updateBoardImage(); - - update(this.getGraphics()); - } - - private void updateFontSizes(){ - if ( zoomIndex <= 4 ) { - font_elev = FONT_7; - font_hexnum = FONT_7; - font_minefield = FONT_7; - } - if ( zoomIndex <= 5 & zoomIndex > 4 ){ - font_elev = FONT_8; - font_hexnum = FONT_8; - font_minefield = FONT_8; - } - if ( zoomIndex > 5 ){ - font_elev = FONT_9; - font_hexnum = FONT_9; - font_minefield = FONT_9; - } - } - - /** - * Displays a bit of text in a box. - * - * TODO: make multi-line - */ - private class TooltipCanvas extends Canvas - { - private String[] tipStrings; - private Dimension size; - - public TooltipCanvas(String[] tipStrings) { - this.tipStrings = tipStrings; - - // setup - setFont(new Font("SansSerif", Font.PLAIN, 12)); //$NON-NLS-1$ - setBackground(SystemColor.info); - setForeground(SystemColor.infoText); - - // determine size - final FontMetrics fm = getFontMetrics(getFont()); - int width = 0; - for (int i = 0; i < tipStrings.length; i++) { - if (fm.stringWidth(tipStrings[i]) > width) { - width = fm.stringWidth(tipStrings[i]); - } - } - size = new Dimension(width + 5, fm.getAscent() * tipStrings.length + 4); - setSize(size); - } - - public void paint(Graphics g) { - final FontMetrics fm = getFontMetrics(getFont()); - g.setColor(getBackground()); - g.fillRect(0, 0, size.width, size.height); - g.setColor(getForeground()); - g.drawRect(0, 0, size.width - 1, size.height - 1); - for (int i = 0; i < tipStrings.length; i++) { - g.drawString(tipStrings[i], 2, (i + 1) * fm.getAscent()); - } - } - } - - - /** - * Everything in the main map view is either the board or it's a sprite - * displayed on top of the board. Most sprites store a transparent image - * which they draw onto the screen when told to. Sprites keep a bounds - * rectangle, so it's easy to tell when they'return onscreen. - */ - private abstract class Sprite implements ImageObserver - { - protected Rectangle bounds; - protected Image image; - - /** - * Do any necessary preparation. This is called after creation, - * but before drawing, when a device context is ready to draw with. - */ - public abstract void prepare(); - - /** - * When we draw our buffered images, it's necessary to implement - * the ImageObserver interface. This provides the necesasry - * functionality. - */ - public boolean imageUpdate(Image image, int infoflags, int x, int y, - int width, int height) { - if (infoflags == ImageObserver.ALLBITS) { - prepare(); - repaint(); - return false; - } else { - return true; - } - } - - /** - * Returns our bounding rectangle. The coordinates here are stored - * with the top left corner of the _board_ being 0, 0, so these do - * not always correspond to screen coordinates. - */ - public Rectangle getBounds() { - return bounds; - } - - /** - * Are we ready to draw? By default, checks to see that our buffered - * image has been created. - */ - public boolean isReady() { - return image != null; - } - - /** - * Draws this sprite onto the specified graphics context. - */ - public void drawOnto(Graphics g, int x, int y, ImageObserver observer) { - drawOnto(g, x, y, observer, false); - } - - public void drawOnto(Graphics g, int x, int y, ImageObserver observer, boolean makeTranslucent) { - if (isReady()) { - Image tmpImage; - if (zoomIndex == BASE_ZOOM_INDEX ){ - tmpImage = image; - } else { - tmpImage = getScaledImage(image); - } - if (makeTranslucent && isJ2RE) { - Graphics2D g2 = (Graphics2D) g; - g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)); - g2.drawImage(tmpImage, x, y, observer); - g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f)); - } else { - g.drawImage(tmpImage, x, y, observer); - } - } else { - // grrr... we'll be ready next time! - prepare(); - } - } - - /** - * Returns true if the point is inside this sprite. Uses board - * coordinates, not screen coordinates. By default, just checks our - * bounding rectangle, though some sprites override this for a smaller - * sensitive area. - */ - public boolean isInside(Point point) { - return bounds.contains(point); - } - - /** - * Since most sprites being drawn correspond to something in the game, - * this returns a little info for a tooltip. - */ - private String[] getTooltip() { - return null; - } - } - - /** - * Sprite for a cursor. Just a hexagon outline in a specified color. - */ - private class CursorSprite extends Sprite - { - private Color color; - private Coords hexLoc; - - public CursorSprite(Color color) { - this.color = color; - this.bounds = new Rectangle(hexPoly.getBounds().width + 1, - hexPoly.getBounds().height + 1); - this.image = null; - - // start offscreen - setOffScreen(); - } - - public void prepare() { - // create image for buffer - Image tempImage = createImage(bounds.width, bounds.height); - Graphics graph = tempImage.getGraphics(); - - // fill with key color - graph.setColor(new Color(TRANSPARENT)); - graph.fillRect(0, 0, bounds.width, bounds.height); - // draw attack poly - graph.setColor(color); - graph.drawPolygon(hexPoly); - - // create final image - this.image = createImage(new FilteredImageSource(tempImage.getSource(), - new KeyAlphaFilter(TRANSPARENT))); - } - - public void setOffScreen(){ - bounds.setLocation(-100, -100); - hexLoc = new Coords(-2, -2); - } - - public void setHexLocation( Coords hexLoc ){ - this.hexLoc = hexLoc; - bounds.setLocation(getHexLocation(hexLoc)); - } - - public Rectangle getBounds(){ - this.bounds = new Rectangle(hexPoly.getBounds().width + 1, - hexPoly.getBounds().height + 1); - bounds.setLocation(getHexLocation( hexLoc )); - - return bounds; - } - } - - - private class GhostEntitySprite extends Sprite { - private Entity entity; - private Rectangle entityRect; - private Rectangle modelRect; - - public GhostEntitySprite(Entity entity) { - this.entity = entity; - - String shortName = entity.getShortName(); - Font font = new Font("SansSerif", Font.PLAIN, 10); //$NON-NLS-1$ - modelRect = new Rectangle(47, 55, - getFontMetrics(font).stringWidth(shortName) + 1, - getFontMetrics(font).getAscent()); - Rectangle tempBounds = new Rectangle(hex_size).union(modelRect); - tempBounds.setLocation(getHexLocation(entity.getPosition())); - - this.bounds = tempBounds; - this.entityRect = new Rectangle( - bounds.x + (int)(20*scale), - bounds.y + (int)(14*scale), - (int)(44*scale), - (int)(44*scale)); - this.image = null; - } - - /** - * Creates the sprite for this entity. It is an extra pain to - * create transparent images in AWT. - */ - public void prepare() { - // create image for buffer - Image tempImage; - Graphics graph; - try { - tempImage = createImage(bounds.width, bounds.height); - graph = tempImage.getGraphics(); - } catch (NullPointerException ex) { - // argh! but I want it! - return; - } - - // fill with key color - graph.setColor(new Color(TRANSPARENT)); - graph.fillRect(0, 0, bounds.width, bounds.height); - - // draw entity image - graph.drawImage(tileManager.imageFor(entity), 0, 0, this); - - // create final image - this.image = createImage(new FilteredImageSource(tempImage.getSource(), - new KeyAlphaFilter(TRANSPARENT))); - } - - public Rectangle getBounds(){ - Rectangle tempBounds = new Rectangle(hex_size).union(modelRect); - tempBounds.setLocation(getHexLocation(entity.getPosition())); - this.bounds = tempBounds; - - this.entityRect = new Rectangle(bounds.x + (int)(20*scale), - bounds.y + (int)(14*scale), - (int)(44*scale), - (int)(44*scale)); - - return bounds; - } - - public void drawOnto(Graphics g, int x, int y, ImageObserver observer) { - drawOnto(g, x, y, observer, true); - } - - } - - private class MovingEntitySprite extends Sprite { - private int facing; - private Entity entity; - private Rectangle entityRect; - private Rectangle modelRect; - - public MovingEntitySprite(Entity entity, Coords position, int facing) { - this.entity = entity; - this.facing = facing; - - String shortName = entity.getShortName(); - Font font = new Font("SansSerif", Font.PLAIN, 10); //$NON-NLS-1$ - modelRect = new Rectangle(47, 55, - getFontMetrics(font).stringWidth(shortName) + 1, - getFontMetrics(font).getAscent()); - Rectangle tempBounds = new Rectangle(hex_size).union(modelRect); - tempBounds.setLocation(getHexLocation(position)); - - this.bounds = tempBounds; - this.entityRect = new Rectangle(bounds.x + (int)(20*scale), - bounds.y + (int)(14*scale), - (int)(44*scale), - (int)(44*scale)); - this.image = null; - } - - /** - * Creates the sprite for this entity. It is an extra pain to - * create transparent images in AWT. - */ - public void prepare() { - // create image for buffer - Image tempImage; - Graphics graph; - try { - tempImage = createImage(bounds.width, bounds.height); - graph = tempImage.getGraphics(); - } catch (NullPointerException ex) { - // argh! but I want it! - return; - } - - // fill with key color - graph.setColor(new Color(TRANSPARENT)); - graph.fillRect(0, 0, bounds.width, bounds.height); - - // draw entity image - graph.drawImage(tileManager.imageFor(entity, facing), 0, 0, this); - - // create final image - this.image = createImage(new FilteredImageSource(tempImage.getSource(), - new KeyAlphaFilter(TRANSPARENT))); - } - } - - - /** - * Sprite for an wreck. Consists - * of an image, drawn from the Tile Manager and an identification label. - */ - private class WreckSprite extends Sprite - { - private Entity entity; - private Rectangle entityRect; - private Rectangle modelRect; - - public WreckSprite(Entity entity) { - this.entity = entity; - - String shortName = entity.getShortName(); - - Font font = new Font("SansSerif", Font.PLAIN, 10); //$NON-NLS-1$ - modelRect = new Rectangle(47, 55, - getFontMetrics(font).stringWidth(shortName) + 1, - getFontMetrics(font).getAscent()); - Rectangle tempBounds = new Rectangle(hex_size).union(modelRect); - tempBounds.setLocation(getHexLocation(entity.getPosition())); - - this.bounds = tempBounds; - this.entityRect = new Rectangle( - bounds.x + (int)(20*scale), - bounds.y + (int)(14*scale), - (int)(44*scale), - (int)(44*scale)); - this.image = null; - } - - public Rectangle getBounds(){ - Rectangle tempBounds = new Rectangle(hex_size).union(modelRect); - tempBounds.setLocation(getHexLocation(entity.getPosition())); - this.bounds = tempBounds; - - this.entityRect = new Rectangle( - bounds.x + (int)(20*scale), - bounds.y + (int)(14*scale), - (int)(44*scale), - (int)(44*scale)); - - return bounds; - } - - /** - * Creates the sprite for this entity. It is an extra pain to - * create transparent images in AWT. - */ - public void prepare() { - // figure out size - String shortName = entity.getShortName(); - Font font = new Font("SansSerif", Font.PLAIN, 10); //$NON-NLS-1$ - Rectangle tempRect = - new Rectangle(47, 55, - getFontMetrics(font).stringWidth(shortName) + 1, - getFontMetrics(font).getAscent()); - - // create image for buffer - Image tempImage; - Graphics graph; - try { - tempImage = createImage(bounds.width, bounds.height); - graph = tempImage.getGraphics(); - } catch (NullPointerException ex) { - // argh! but I want it! - return; - } - - // fill with key color - graph.setColor(new Color(TRANSPARENT)); - graph.fillRect(0, 0, bounds.width, bounds.height); - - // Draw wreck image,if we've got one. - Image wreck = tileManager.wreckMarkerFor(entity); - if ( null != wreck ) { - graph.drawImage( wreck, 0, 0, this ); - } - - // draw box with shortName - Color text = Color.lightGray; - Color bkgd = Color.darkGray; - Color bord = Color.black; - - graph.setFont(font); - graph.setColor(bord); - graph.fillRect(tempRect.x, tempRect.y, - tempRect.width, tempRect.height); - tempRect.translate(-1, -1); - graph.setColor(bkgd); - graph.fillRect(tempRect.x, tempRect.y, - tempRect.width, tempRect.height); - graph.setColor(text); - graph.drawString(shortName, tempRect.x + 1, - tempRect.y + tempRect.height - 1); - - // create final image - this.image = createImage - (new FilteredImageSource(tempImage.getSource(), - new KeyAlphaFilter(TRANSPARENT))); - } - - /** - * Overrides to provide for a smaller sensitive area. - */ - public boolean isInside(Point point) { - return false; - } - - } - /** - * Sprite for an entity. Changes whenever the entity changes. Consists - * of an image, drawn from the Tile Manager; facing and possibly secondary - * facing arrows; armor and internal bars; and an identification label. - */ - private class EntitySprite extends Sprite - { - private Entity entity; - private Rectangle entityRect; - private Rectangle modelRect; - - public EntitySprite(Entity entity) { - this.entity = entity; - - String shortName = entity.getShortName(); - - if (entity.getMovementMode() == IEntityMovementMode.VTOL) { - shortName = shortName.concat(" (FL: ").concat(Integer.toString(entity.getElevation())).concat(")"); - } - Font font = new Font("SansSerif", Font.PLAIN, 10); //$NON-NLS-1$ - modelRect = new Rectangle(47, 55, - getFontMetrics(font).stringWidth(shortName) + 1, - getFontMetrics(font).getAscent()); - Rectangle tempBounds = new Rectangle(hex_size).union(modelRect); - tempBounds.setLocation(getHexLocation(entity.getPosition())); - - this.bounds = tempBounds; - this.entityRect = new Rectangle(bounds.x + (int)(20*scale), - bounds.y + (int)(14*scale), - (int)(44*scale), - (int)(44*scale)); - this.image = null; - } - - public Rectangle getBounds(){ - Rectangle tempBounds = new Rectangle(hex_size).union(modelRect); - tempBounds.setLocation(getHexLocation(entity.getPosition())); - this.bounds = tempBounds; - - this.entityRect = new Rectangle( - bounds.x + (int)(20*scale), - bounds.y + (int)(14*scale), - (int)(44*scale), - (int)(44*scale)); - - return bounds; - } - - public void drawOnto(Graphics g, int x, int y, ImageObserver observer) { - if (trackThisEntitiesVisibilityInfo(this.entity) - && !this.entity.isVisibleToEnemy()) { - // create final image with translucency - drawOnto(g, x, y, observer, true); - } else { - drawOnto(g, x, y, observer, false); - } - } - - /** - * Creates the sprite for this entity. It is an extra pain to - * create transparent images in AWT. - */ - public void prepare() { - // figure out size - String shortName = entity.getShortName(); - if (entity.getMovementMode() == IEntityMovementMode.VTOL) { - shortName = shortName.concat(" (FL: ").concat(Integer.toString(entity.getElevation())).concat(")"); - } - if (PreferenceManager.getClientPreferences().getShowUnitId()) { - shortName+=(Messages.getString("BoardView1.ID")+entity.getId()); //$NON-NLS-1$ - } - Font font = new Font("SansSerif", Font.PLAIN, 10); //$NON-NLS-1$ - Rectangle tempRect = - new Rectangle(47, 55, - getFontMetrics(font).stringWidth(shortName) + 1, - getFontMetrics(font).getAscent()); - - // create image for buffer - Image tempImage; - Graphics graph; - try { - tempImage = createImage(bounds.width, bounds.height); - graph = tempImage.getGraphics(); - } catch (NullPointerException ex) { - // argh! but I want it! - return; - } - - // fill with key color - graph.setColor(new Color(TRANSPARENT)); - graph.fillRect(0, 0, bounds.width, bounds.height); - - // draw entity image - graph.drawImage(tileManager.imageFor(entity), 0, 0, this); - - // draw box with shortName - Color text, bkgd, bord; - if (entity.isDone()) { - text = Color.lightGray; - bkgd = Color.darkGray; - bord = Color.black; - } else if (entity.isImmobile()) { - text = Color.darkGray; - bkgd = Color.black; - bord = Color.lightGray; - } else { - text = Color.black; - bkgd = Color.lightGray; - bord = Color.darkGray; - } - graph.setFont(font); - graph.setColor(bord); - graph.fillRect(tempRect.x, tempRect.y, - tempRect.width, tempRect.height); - tempRect.translate(-1, -1); - graph.setColor(bkgd); - graph.fillRect(tempRect.x, tempRect.y, - tempRect.width, tempRect.height); - graph.setColor(text); - graph.drawString(shortName, tempRect.x + 1, - tempRect.y + tempRect.height - 1); - - // draw facing - graph.setColor(Color.white); - if (entity.getFacing() != -1) { - graph.drawPolygon(facingPolys[entity.getFacing()]); - } - - // determine secondary facing for non-mechs & flipped arms - int secFacing = entity.getFacing(); - if (!(entity instanceof Mech || entity instanceof Protomech)) { - secFacing = entity.getSecondaryFacing(); - } else if (entity.getArmsFlipped()) { - secFacing = (entity.getFacing() + 3) % 6; - } - // draw red secondary facing arrow if necessary - if (secFacing != -1 && secFacing != entity.getFacing()) { - graph.setColor(Color.red); - graph.drawPolygon(facingPolys[secFacing]); - } - - // Determine if the entity is a tank with a locked turret. - boolean turretLocked = false; - if ( entity instanceof Tank && - !( (Tank) entity ).hasNoTurret() && - !entity.canChangeSecondaryFacing() ) { - turretLocked = true; - } - - // draw condition strings - if ( entity.isImmobile() && !entity.isProne() && !turretLocked ) { - // draw "IMMOBILE" - graph.setColor(Color.darkGray); - graph.drawString(Messages.getString("BoardView1.IMMOBILE"), 18, 39); //$NON-NLS-1$ - graph.setColor(Color.red); - graph.drawString(Messages.getString("BoardView1.IMMOBILE"), 17, 38); //$NON-NLS-1$ - } else if (!entity.isImmobile() && entity.isProne()) { - // draw "PRONE" - graph.setColor(Color.darkGray); - graph.drawString(Messages.getString("BoardView1.PRONE"), 26, 39); //$NON-NLS-1$ - graph.setColor(Color.yellow); - graph.drawString(Messages.getString("BoardView1.PRONE"), 25, 38); //$NON-NLS-1$ - } else if ( !entity.isImmobile() && turretLocked ) { - // draw "LOCKED" - graph.setColor(Color.darkGray); - graph.drawString(Messages.getString("BoardView1.LOCKED"), 22, 39); //$NON-NLS-1$ - graph.setColor(Color.yellow); - graph.drawString(Messages.getString("BoardView1.LOCKED"), 21, 38); //$NON-NLS-1$ - } else if (entity.isImmobile() && entity.isProne()) { - // draw "IMMOBILE" and "PRONE" - graph.setColor(Color.darkGray); - graph.drawString(Messages.getString("BoardView1.IMMOBILE"), 18, 35); //$NON-NLS-1$ - graph.drawString(Messages.getString("BoardView1.PRONE"), 26, 48); //$NON-NLS-1$ - graph.setColor(Color.red); - graph.drawString(Messages.getString("BoardView1.IMMOBILE"), 17, 34); //$NON-NLS-1$ - graph.setColor(Color.yellow); - graph.drawString(Messages.getString("BoardView1.PRONE"), 25, 47); //$NON-NLS-1$ - } else if ( entity.isImmobile() && turretLocked ) { - // draw "IMMOBILE" and "LOCKED" - graph.setColor(Color.darkGray); - graph.drawString(Messages.getString("BoardView1.IMMOBILE"), 18, 35); //$NON-NLS-1$ - graph.drawString(Messages.getString("BoardView1.LOCKED"), 22, 48); //$NON-NLS-1$ - graph.setColor(Color.red); - graph.drawString(Messages.getString("BoardView1.IMMOBILE"), 17, 34); //$NON-NLS-1$ - graph.setColor(Color.yellow); - graph.drawString(Messages.getString("BoardView1.LOCKED"), 21, 47); //$NON-NLS-1$ - } - - // If this unit is being swarmed or is swarming another, say so. - if ( Entity.NONE != entity.getSwarmAttackerId() ) { - // draw "SWARMED" - graph.setColor(Color.darkGray); - graph.drawString(Messages.getString("BoardView1.SWARMED"), 17, 22); //$NON-NLS-1$ - graph.setColor(Color.red); - graph.drawString(Messages.getString("BoardView1.SWARMED"), 16, 21); //$NON-NLS-1$ - } - - // If this unit is transporting another, say so. - if ((entity.getLoadedUnits()).size() > 0) { - // draw "T" - graph.setColor(Color.darkGray); - graph.drawString("T", 20, 71); //$NON-NLS-1$ - graph.setColor(Color.black); - graph.drawString("T", 19, 70); //$NON-NLS-1$ - } - - // If this unit is stuck, say so. - if ((entity.isStuck())) { - graph.setColor(Color.darkGray); - graph.drawString(Messages.getString("BoardView1.STUCK"), 26, 61); //$NON-NLS-1$ - graph.setColor(Color.orange); - graph.drawString(Messages.getString("BoardView1.STUCK"), 25, 60); //$NON-NLS-1$ - - } - - // If this unit is currently unknown to the enemy, say so. - if (trackThisEntitiesVisibilityInfo(entity)) { - if (!entity.isSeenByEnemy()) { - // draw "U" - graph.setColor(Color.darkGray); - graph.drawString("U", 30, 71); //$NON-NLS-1$ - graph.setColor(Color.black); - graph.drawString("U", 29, 70); //$NON-NLS-1$ - } else if (!entity.isVisibleToEnemy() && !isJ2RE) { - // If this unit is currently hidden from the enemy, say so. - // draw "H" - graph.setColor(Color.darkGray); - graph.drawString("H", 30, 71); //$NON-NLS-1$ - graph.setColor(Color.black); - graph.drawString("H", 29, 70); //$NON-NLS-1$ - } - } - - //Lets draw our armor and internal status bars - int baseBarLength = 23; - int barLength = 0; - double percentRemaining = 0.00; - - percentRemaining = entity.getArmorRemainingPercent(); - barLength = (int)(baseBarLength * percentRemaining); - - graph.setColor(Color.darkGray); - graph.fillRect(56, 7, 23, 3); - graph.setColor(Color.lightGray); - graph.fillRect(55, 6, 23, 3); - graph.setColor(getStatusBarColor(percentRemaining)); - graph.fillRect(55, 6, barLength, 3); - - percentRemaining = entity.getInternalRemainingPercent(); - barLength = (int)(baseBarLength * percentRemaining); - - graph.setColor(Color.darkGray); - graph.fillRect(56, 11, 23, 3); - graph.setColor(Color.lightGray); - graph.fillRect(55, 10, 23, 3); - graph.setColor(getStatusBarColor(percentRemaining)); - graph.fillRect(55, 10, barLength, 3); - - // create final image - this.image = createImage(new FilteredImageSource(tempImage.getSource(), - new KeyAlphaFilter(TRANSPARENT))); - } - - /* - * We only want to show double-blind visibility indicators on - * our own mechs and teammates mechs (assuming team vision option). - */ - private boolean trackThisEntitiesVisibilityInfo(Entity e) { - if (getLocalPlayer() == null) { - return false; - } - - if (game.getOptions().booleanOption("double_blind") //$NON-NLS-1$ - && (e.getOwner().getId() == getLocalPlayer().getId() - || (game.getOptions().booleanOption("team_vision") //$NON-NLS-1$ - && e.getOwner().getTeam() == getLocalPlayer().getTeam()))) { - return true; - } else { - return false; - } - } - - private Color getStatusBarColor(double percentRemaining) { - if ( percentRemaining <= .25 ) - return Color.red; - else if ( percentRemaining <= .75 ) - return Color.yellow; - else - return new Color(16, 196, 16); - } - - /** - * Overrides to provide for a smaller sensitive area. - */ - public boolean isInside(Point point) { - return entityRect.contains( point.x + view.x - offset.x, - point.y + view.y - offset.y); - } - - private String[] getTooltip() { - String[] tipStrings = new String[3]; - StringBuffer buffer; - - buffer = new StringBuffer(); - buffer.append( entity.getChassis() ) - .append( " (" ) //$NON-NLS-1$ - .append( entity.getOwner().getName() ) - .append( "); " ) //$NON-NLS-1$ - .append( entity.getCrew().getGunnery() ) - .append( "/" ) //$NON-NLS-1$ - .append( entity.getCrew().getPiloting() ) - .append( Messages.getString("BoardView1.pilot") ); //$NON-NLS-1$ - int numAdv = entity.getCrew().countAdvantages(); - if (numAdv > 0) { - buffer.append( " <" ) //$NON-NLS-1$ - .append( numAdv ) - .append( Messages.getString("BoardView1.advs") ); //$NON-NLS-1$ - } - tipStrings[0] = buffer.toString(); - - buffer = new StringBuffer(); - buffer.append( Messages.getString("BoardView1.move") ) //$NON-NLS-1$ - .append( entity.getMovementAbbr(entity.moved) ) - .append( ":" ) //$NON-NLS-1$ - .append( entity.delta_distance ) - .append( " (+" ) //$NON-NLS-1$ - .append( Compute.getTargetMovementModifier - (game, entity.getId()).getValue() ) - .append( ");" ) //$NON-NLS-1$ - .append( Messages.getString("BoardView1.Heat") ) //$NON-NLS-1$ - .append( entity.heat ); - if (entity.isDone()) - buffer.append(" (").append(Messages.getString("BoardView1.done")).append(")"); - tipStrings[1] = buffer.toString(); - - buffer = new StringBuffer(); - buffer.append( Messages.getString("BoardView1.Armor") ) //$NON-NLS-1$ - .append( entity.getTotalArmor() ) - .append( Messages.getString("BoardView1.internal") ) //$NON-NLS-1$ - .append( entity.getTotalInternal() ); - tipStrings[2] = buffer.toString(); - - return tipStrings; - } - } - - /** - * Sprite for a step in a movement path. Only one sprite should exist for - * any hex in a path. Contains a colored number, and arrows indicating - * entering, exiting or turning. - */ - private class StepSprite extends Sprite - { - private MoveStep step; - - public StepSprite(MoveStep step) { - this.step = step; - - // step is the size of the hex that this step is in - bounds = new Rectangle(getHexLocation(step.getPosition()), hex_size); - this.image = null; - } - - public void prepare() { - // create image for buffer - Image tempImage = createImage(bounds.width, bounds.height); - Graphics graph = tempImage.getGraphics(); - - // fill with key color - graph.setColor(new Color(TRANSPARENT)); - graph.fillRect(0, 0, bounds.width, bounds.height); - - // setup some variables - final Point stepPos = getHexLocation(step.getPosition()); - stepPos.translate(-bounds.x, -bounds.y); - final Polygon facingPoly = facingPolys[step.getFacing()]; - final Polygon movePoly = movementPolys[step.getFacing()]; - Point offsetCostPos; - Polygon myPoly; - Color col; - // set color - switch (step.getMovementType()) { - case IEntityMovementType.MOVE_RUN: - case IEntityMovementType.MOVE_VTOL_RUN: - if (step.isUsingMASC()) { - col = GUIPreferences.getInstance().getColor("AdvancedMoveMASCColor"); - } else { - col = GUIPreferences.getInstance().getColor("AdvancedMoveRunColor"); - } - break; - case IEntityMovementType.MOVE_JUMP : - col = GUIPreferences.getInstance().getColor("AdvancedMoveJumpColor"); - break; - case IEntityMovementType.MOVE_ILLEGAL : - col = GUIPreferences.getInstance().getColor("AdvancedMoveIllegalColor"); - break; - default : - if (step.getType()==MovePath.STEP_BACKWARDS) { - col = GUIPreferences.getInstance().getColor("AdvancedMoveBackColor"); - } else { - col = GUIPreferences.getInstance().getColor("AdvancedMoveDefaultColor"); - } - break; - } - - // draw arrows and cost for the step - switch (step.getType()) { - case MovePath.STEP_FORWARDS : - case MovePath.STEP_BACKWARDS : - case MovePath.STEP_CHARGE : - case MovePath.STEP_DFA : - case MovePath.STEP_LATERAL_LEFT : - case MovePath.STEP_LATERAL_RIGHT : - case MovePath.STEP_LATERAL_LEFT_BACKWARDS : - case MovePath.STEP_LATERAL_RIGHT_BACKWARDS : - // draw arrows showing them entering the next - myPoly = new Polygon(movePoly.xpoints, movePoly.ypoints, - movePoly.npoints); - graph.setColor(Color.darkGray); - myPoly.translate(stepPos.x + 1, stepPos.y + 1); - graph.drawPolygon(myPoly); - graph.setColor(col); - myPoly.translate(-1, -1); - graph.drawPolygon(myPoly); - // draw movement cost - drawMovementCost(step, stepPos, graph, col, true); - break; - case MovePath.STEP_GO_PRONE: - // draw arrow indicating dropping prone - Polygon downPoly = movementPolys[7]; - myPoly = new Polygon(downPoly.xpoints, downPoly.ypoints, downPoly.npoints); - graph.setColor(Color.darkGray); - myPoly.translate(stepPos.x, stepPos.y); - graph.drawPolygon(myPoly); - graph.setColor(col); - myPoly.translate(-1, -1); - graph.drawPolygon(myPoly); - offsetCostPos = new Point(stepPos.x + 1, stepPos.y + 15); - drawMovementCost(step, offsetCostPos, graph, col, false); - break; - case MovePath.STEP_GET_UP: - // draw arrow indicating standing up - Polygon upPoly = movementPolys[6]; - myPoly = new Polygon(upPoly.xpoints, upPoly.ypoints, upPoly.npoints); - graph.setColor(Color.darkGray); - myPoly.translate(stepPos.x, stepPos.y); - graph.drawPolygon(myPoly); - graph.setColor(col); - myPoly.translate(-1, -1); - graph.drawPolygon(myPoly); - offsetCostPos = new Point(stepPos.x, stepPos.y + 15); - drawMovementCost(step, offsetCostPos, graph, col, false); - break; - case MovePath.STEP_TURN_LEFT: - case MovePath.STEP_TURN_RIGHT: - // draw arrows showing the facing - myPoly = new Polygon(facingPoly.xpoints, facingPoly.ypoints, - facingPoly.npoints); - graph.setColor(Color.darkGray); - myPoly.translate(stepPos.x + 1, stepPos.y + 1); - graph.drawPolygon(myPoly); - graph.setColor(col); - myPoly.translate(-1, -1); - graph.drawPolygon(myPoly); - break; - case MovePath.STEP_LOAD: - // Announce load. - String load = Messages.getString("BoardView1.Load"); //$NON-NLS-1$ - if (step.isPastDanger()) { - load = "(" + load + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - graph.setFont(new Font("SansSerif", Font.PLAIN, 12)); //$NON-NLS-1$ - int loadX = stepPos.x + 42 - (graph.getFontMetrics(graph.getFont()).stringWidth(load) / 2); - graph.setColor(Color.darkGray); - graph.drawString(load, loadX, stepPos.y + 39); - graph.setColor(col); - graph.drawString(load, loadX - 1, stepPos.y + 38); - break; - case MovePath.STEP_UNLOAD: - // Announce unload. - String unload = Messages.getString("BoardView1.Unload"); //$NON-NLS-1$ - if (step.isPastDanger()) { - unload = "(" + unload + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - graph.setFont(new Font("SansSerif", Font.PLAIN, 12)); //$NON-NLS-1$ - int unloadX = stepPos.x + 42 - (graph.getFontMetrics(graph.getFont()).stringWidth(unload) / 2); - int unloadY = stepPos.y + 38 + graph.getFontMetrics(graph.getFont()).getHeight(); - graph.setColor(Color.darkGray); - graph.drawString(unload, unloadX, unloadY + 1); - graph.setColor(col); - graph.drawString(unload, unloadX - 1, unloadY); - break; - - default : - break; - } - - // create final image - this.image = createImage(new FilteredImageSource(tempImage.getSource(), - new KeyAlphaFilter(TRANSPARENT))); - } - - public Rectangle getBounds(){ - bounds = new Rectangle(getHexLocation(step.getPosition()), hex_size); - return bounds; - } - - public MoveStep getStep() { - return step; - } - - private void drawMovementCost(MoveStep step, Point stepPos, Graphics graph, Color col, boolean shiftFlag) { - String costString = null; - StringBuffer costStringBuf = new StringBuffer(); - costStringBuf.append( step.getMpUsed() ); - - // If the step is using a road bonus, mark it. - if ( step.isPavementStep() && step.getParent().getEntity() instanceof Tank ) { - costStringBuf.append( "+" ); //$NON-NLS-1$ - } - - // If the step is dangerous, mark it. - if ( step.isDanger() ) { - costStringBuf.append( "*" ); //$NON-NLS-1$ - } - - // If the step is past danger, mark that. - if (step.isPastDanger()) { - costStringBuf.insert( 0, "(" ); //$NON-NLS-1$ - costStringBuf.append( ")" ); //$NON-NLS-1$ - } - - if (step.isUsingMASC()) { - costStringBuf.append("["); //$NON-NLS-1$ - costStringBuf.append(step.getTargetNumberMASC()); - costStringBuf.append("+]"); //$NON-NLS-1$ - } - - if (step.getMovementType() == IEntityMovementType.MOVE_VTOL_RUN || - step.getMovementType() == IEntityMovementType.MOVE_VTOL_RUN) { - costStringBuf.append("{").append(step.getElevation()).append("}"); - } - - // Convert the buffer to a String and draw it. - costString = costStringBuf.toString(); - graph.setFont(new Font("SansSerif", Font.PLAIN, 12)); //$NON-NLS-1$ - int costX = stepPos.x + 42; - if (shiftFlag) { - costX -= (graph.getFontMetrics(graph.getFont()).stringWidth(costString) / 2); - } - graph.setColor(Color.darkGray); - graph.drawString(costString, costX, stepPos.y + 39); - graph.setColor(col); - graph.drawString(costString, costX - 1, stepPos.y + 38); - } - - } - - /** - * Sprite and info for a C3 network. Does not actually use the image buffer - * as this can be horribly inefficient for long diagonal lines. - */ - private class C3Sprite extends Sprite - { - private Polygon C3Poly; - - protected int entityId; - protected int masterId; - protected Entity entityE; - protected Entity entityM; - - Color spriteColor; - - public C3Sprite(Entity e, Entity m) { - this.entityE = e; - this.entityM = m; - this.entityId = e.getId(); - this.masterId = m.getId(); - this.spriteColor = PlayerColors.getColor(e.getOwner().getColorIndex()); - - if(e.getPosition() == null || m.getPosition() == null) { - C3Poly = new Polygon(); - C3Poly.addPoint(0, 0); - C3Poly.addPoint(1,0); - C3Poly.addPoint(0,1); - this.bounds = new Rectangle(C3Poly.getBounds()); - bounds.setSize(bounds.getSize().width + 1, bounds.getSize().height + 1); - this.image = null; - return; - } - - makePoly(); - - // set bounds - this.bounds = new Rectangle(C3Poly.getBounds()); - bounds.setSize(bounds.getSize().width + 1, bounds.getSize().height + 1); - - // move poly to upper right of image - C3Poly.translate(-bounds.getLocation().x, -bounds.getLocation().y); - - // set names & stuff - - // nullify image - this.image = null; - } - - public void prepare() { - } - - private void makePoly( ){ - // make a polygon - final Point a = getHexLocation(entityE.getPosition()); - final Point t = getHexLocation(entityM.getPosition()); - - final double an = (entityE.getPosition().radian(entityM.getPosition()) + (Math.PI * 1.5)) % (Math.PI * 2); // angle - final double lw = scale*C3_LINE_WIDTH; // line width - - C3Poly = new Polygon(); - C3Poly.addPoint( - a.x + (int)(scale*(HEX_W/2) - (int)Math.round(Math.sin(an) * lw)), - a.y + (int)(scale*(HEX_H/2) + (int)Math.round(Math.cos(an) * lw))); - C3Poly.addPoint( - a.x + (int)(scale*(HEX_W/2) + (int)Math.round(Math.sin(an) * lw)), - a.y + (int)(scale*(HEX_H/2) - (int)Math.round(Math.cos(an) * lw))); - C3Poly.addPoint( - t.x + (int)(scale*(HEX_W/2) + (int)Math.round(Math.sin(an) * lw)), - t.y + (int)(scale*(HEX_H/2) - (int)Math.round(Math.cos(an) * lw))); - C3Poly.addPoint( - t.x + (int)(scale*(HEX_W/2) - (int)Math.round(Math.sin(an) * lw)), - t.y + (int)(scale*(HEX_H/2) + (int)Math.round(Math.cos(an) * lw))); - } - - public Rectangle getBounds(){ - makePoly(); - // set bounds - this.bounds = new Rectangle(C3Poly.getBounds()); - bounds.setSize(bounds.getSize().width + 1, bounds.getSize().height + 1); - - // move poly to upper right of image - C3Poly.translate(-bounds.getLocation().x, -bounds.getLocation().y); - this.image = null; - - return bounds; - } - - public boolean isReady() { - return true; - } - - public void drawOnto(Graphics g, int x, int y, ImageObserver observer) { - //makePoly(); - - Polygon drawPoly = new Polygon(C3Poly.xpoints, C3Poly.ypoints, C3Poly.npoints); - drawPoly.translate(x, y); - - g.setColor(spriteColor); - g.fillPolygon(drawPoly); - g.setColor(Color.black); - g.drawPolygon(drawPoly); - } - - /** - * Return true if the point is inside our polygon - */ - public boolean isInside(Point point) { - return C3Poly.contains(point.x + view.x - bounds.x - offset.x, - point.y + view.y - bounds.y - offset.y); - } - - } - - /** - * Sprite and info for an attack. Does not actually use the image buffer - * as this can be horribly inefficient for long diagonal lines. - * - * Appears as an arrow. Arrow becoming cut in half when two Meks attacking - * each other. - */ - private class AttackSprite extends Sprite - { - private java.util.Vector attacks = new java.util.Vector(); - private Point a; - private Point t; - private double an; - private StraightArrowPolygon attackPoly; - private Color attackColor; - private int entityId; - private int targetType; - private int targetId; - private String attackerDesc; - private String targetDesc; - private Vector weaponDescs = new Vector(); - private final Entity ae; - private final Targetable target; - - public AttackSprite(AttackAction attack) { - this.attacks.addElement(attack); - this.entityId = attack.getEntityId(); - this.targetType = attack.getTargetType(); - this.targetId = attack.getTargetId(); - this.ae = game.getEntity(attack.getEntityId()); - this.target = game.getTarget(targetType, targetId); - - // color? - attackColor = PlayerColors.getColor(ae.getOwner().getColorIndex()); - //angle of line connecting two hexes - this.an = (ae.getPosition().radian(target.getPosition()) + (Math.PI * 1.5)) % (Math.PI * 2); // angle - makePoly(); - - // set bounds - this.bounds = new Rectangle(attackPoly.getBounds()); - bounds.setSize(bounds.getSize().width + 1, bounds.getSize().height + 1); - // move poly to upper right of image - attackPoly.translate(-bounds.getLocation().x, -bounds.getLocation().y); - - // set names & stuff - attackerDesc = ae.getDisplayName(); - targetDesc = target.getDisplayName(); - if (attack instanceof WeaponAttackAction) { - addWeapon((WeaponAttackAction)attack); - } - if (attack instanceof KickAttackAction) { - addWeapon((KickAttackAction)attack); - } - if (attack instanceof PunchAttackAction) { - addWeapon((PunchAttackAction)attack); - } - if (attack instanceof PushAttackAction) { - addWeapon((PushAttackAction)attack); - } - if (attack instanceof ClubAttackAction) { - addWeapon((ClubAttackAction)attack); - } - if (attack instanceof ChargeAttackAction) { - addWeapon((ChargeAttackAction)attack); - } - if (attack instanceof DfaAttackAction) { - addWeapon((DfaAttackAction)attack); - } - if (attack instanceof ProtomechPhysicalAttackAction) { - addWeapon((ProtomechPhysicalAttackAction)attack); - } - - // nullify image - this.image = null; - } - - private void makePoly(){ - // make a polygon - this.a = getHexLocation(ae.getPosition()); - this.t = getHexLocation(target.getPosition()); - // OK, that is actually not good. I do not like hard coded figures. - // HEX_W/2 - x distance in pixels from origin of hex bounding box to the center of hex. - // HEX_H/2 - y distance in pixels from origin of hex bounding box to the center of hex. - // 18 - is actually 36/2 - we do not want arrows to start and end directly - // in the centes of hex and hiding mek under. - - a.x = a.x + (int)(HEX_W/2*scale) + (int)Math.round(Math.cos(an) * (int)(18*scale)); - t.x = t.x + (int)(HEX_W/2*scale) - (int)Math.round(Math.cos(an) * (int)(18*scale)); - a.y = a.y + (int)(HEX_H/2*scale) + (int)Math.round(Math.sin(an) * (int)(18*scale)); - t.y = t.y + (int)(HEX_H/2*scale) - (int)Math.round(Math.sin(an) * (int)(18*scale)); - - // Checking if given attack is mutual. In this case we building halved arrow - if (isMutualAttack()){ - attackPoly = new StraightArrowPolygon(a, t, (int)(8*scale), (int)(12*scale), true); - } else { - attackPoly = new StraightArrowPolygon(a, t, (int)(4*scale), (int)(8*scale), false); - } - } - - public Rectangle getBounds(){ - makePoly(); - // set bounds - this.bounds = new Rectangle(attackPoly.getBounds()); - bounds.setSize(bounds.getSize().width + 1, bounds.getSize().height + 1); - // move poly to upper right of image - attackPoly.translate(-bounds.getLocation().x, -bounds.getLocation().y); - - return bounds; - } - - /** If we have build full arrow already with single attack and have got - * counter attack from our target lately - lets change arrow to halved. - */ - public void rebuildToHalvedPolygon(){ - attackPoly = new StraightArrowPolygon(a, t, (int)(8*scale), (int)(12*scale), true); - // set bounds - this.bounds = new Rectangle(attackPoly.getBounds()); - bounds.setSize(bounds.getSize().width + 1, bounds.getSize().height + 1); - // move poly to upper right of image - attackPoly.translate(-bounds.getLocation().x, -bounds.getLocation().y); - } - /** Cheking if attack is mutual and changing target arrow to half-arrow - */ - private boolean isMutualAttack(){ - for (final Iterator i = attackSprites.iterator(); i.hasNext();) { - final AttackSprite sprite = (AttackSprite)i.next(); - if (sprite.getEntityId() == this.targetId && sprite.getTargetId() == this.entityId) { - sprite.rebuildToHalvedPolygon(); - return true; - } - } - return false; - } - - public void prepare() { - } - - public boolean isReady() { - return true; - } - - public void drawOnto(Graphics g, int x, int y, ImageObserver observer) { - Polygon drawPoly = new Polygon(attackPoly.xpoints, attackPoly.ypoints, attackPoly.npoints); - drawPoly.translate(x, y); - - g.setColor(attackColor); - g.fillPolygon(drawPoly); - g.setColor(Color.gray.darker()); - g.drawPolygon(drawPoly); - } - - /** - * Return true if the point is inside our polygon - */ - public boolean isInside(Point point) { - return attackPoly.contains(point.x + view.x - bounds.x - offset.x, - point.y + view.y - bounds.y - offset.y); - } - - public int getEntityId() { - return entityId; - } - - public int getTargetId() { - return targetId; - } - - /** - * Adds a weapon to this attack - */ - public void addWeapon(WeaponAttackAction attack) { - final Entity entity = game.getEntity(attack.getEntityId()); - final WeaponType wtype = (WeaponType)entity.getEquipment(attack.getWeaponId()).getType(); - final String roll = attack.toHit(game).getValueAsString(); - weaponDescs.addElement( wtype.getName() + Messages.getString("BoardView1.needs") + roll ); //$NON-NLS-1$ - } - - public void addWeapon(KickAttackAction attack) { - String bufer = ""; //$NON-NLS-1$ - String rollLeft = ""; //$NON-NLS-1$ - String rollRight = ""; //$NON-NLS-1$ - final int leg = attack.getLeg(); - switch (leg){ - case KickAttackAction.BOTH: - rollLeft = KickAttackAction.toHit( game, attack.getEntityId(), game.getTarget(attack.getTargetType(), attack.getTargetId()), KickAttackAction.LEFT).getValueAsString(); - rollRight = KickAttackAction.toHit( game, attack.getEntityId(), game.getTarget(attack.getTargetType(), attack.getTargetId()), KickAttackAction.RIGHT).getValueAsString(); - bufer = Messages.getString("BoardView1.kickBoth", new Object[]{rollLeft,rollRight}); //$NON-NLS-1$ - break; - case KickAttackAction.LEFT: - rollLeft = KickAttackAction.toHit( game, attack.getEntityId(), game.getTarget(attack.getTargetType(), attack.getTargetId()), KickAttackAction.LEFT).getValueAsString(); - bufer = Messages.getString("BoardView1.kickLeft", new Object[]{rollLeft}); //$NON-NLS-1$ - break; - case KickAttackAction.RIGHT: - rollRight = KickAttackAction.toHit( game, attack.getEntityId(), game.getTarget(attack.getTargetType(), attack.getTargetId()), KickAttackAction.RIGHT).getValueAsString(); - bufer = Messages.getString("BoardView1.kickRight", new Object[]{rollRight}); //$NON-NLS-1$ - break; - } - weaponDescs.addElement(bufer); - } - - public void addWeapon(PunchAttackAction attack) { - String bufer = ""; //$NON-NLS-1$ - String rollLeft = ""; //$NON-NLS-1$ - String rollRight = ""; //$NON-NLS-1$ - final int arm = attack.getArm(); - switch (arm){ - case PunchAttackAction.BOTH: - rollLeft = PunchAttackAction.toHit( game, attack.getEntityId(), game.getTarget(attack.getTargetType(), attack.getTargetId()), PunchAttackAction.LEFT).getValueAsString(); - rollRight = PunchAttackAction.toHit( game, attack.getEntityId(), game.getTarget(attack.getTargetType(), attack.getTargetId()), PunchAttackAction.RIGHT).getValueAsString(); - bufer = Messages.getString("BoardView1.punchBoth", new Object[]{rollLeft,rollRight}); //$NON-NLS-1$ - break; - case PunchAttackAction.LEFT: - rollLeft = PunchAttackAction.toHit( game, attack.getEntityId(), game.getTarget(attack.getTargetType(), attack.getTargetId()), PunchAttackAction.LEFT).getValueAsString(); - bufer = Messages.getString("BoardView1.punchLeft", new Object[]{rollLeft}); //$NON-NLS-1$ - break; - case PunchAttackAction.RIGHT: - rollRight = PunchAttackAction.toHit( game, attack.getEntityId(), game.getTarget(attack.getTargetType(), attack.getTargetId()), PunchAttackAction.RIGHT).getValueAsString(); - bufer = Messages.getString("BoardView1.punchRight", new Object[]{rollRight}); //$NON-NLS-1$ - break; - } - weaponDescs.addElement(bufer); - } - - public void addWeapon(PushAttackAction attack) { - final String roll = attack.toHit(game).getValueAsString(); - weaponDescs.addElement(Messages.getString("BoardView1.push", new Object[]{roll})); //$NON-NLS-1$ - } - - public void addWeapon(ClubAttackAction attack) { - final String roll = attack.toHit(game).getValueAsString(); - final String club = attack.getClub().getName(); - weaponDescs.addElement(Messages.getString("BoardView1.hit", new Object[]{club,roll})); //$NON-NLS-1$ - } - - public void addWeapon(ChargeAttackAction attack) { - final String roll = attack.toHit(game).getValueAsString(); - weaponDescs.addElement(Messages.getString("BoardView1.charge", new Object[]{roll})); //$NON-NLS-1$ - } - public void addWeapon(DfaAttackAction attack) { - final String roll = attack.toHit(game).getValueAsString(); - weaponDescs.addElement(Messages.getString("BoardView1.DFA", new Object[]{roll})); //$NON-NLS-1$ - } - public void addWeapon(ProtomechPhysicalAttackAction attack) { - final String roll = attack.toHit(game).getValueAsString(); - weaponDescs.addElement(Messages.getString("BoardView1.proto", new Object[]{roll})); //$NON-NLS-1$ - } - - private String[] getTooltip() { - String[] tipStrings = new String[1 + weaponDescs.size()]; - int tip = 1; - tipStrings[0] = attackerDesc + " "+Messages.getString("BoardView1.on")+" " + targetDesc; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - for (Iterator i = weaponDescs.iterator(); i.hasNext();) { - tipStrings[tip++] = (String)i.next(); - } - return tipStrings; - } - } - - /** - * Determine if the tile manager's images have been loaded. - * - * @return true if all images have been loaded. - * false if more need to be loaded. - */ - public boolean isTileImagesLoaded() { - return this.tileManager.isLoaded(); - } - - public void setUseLOSTool(boolean use) { - useLOSTool = use; - } - - public TilesetManager getTilesetManager() { - return tileManager; - } - - // added by kenn - public void drawRuler(Coords s, Coords e, Color sc, Color ec) { - rulerStart = s; - rulerEnd = e; - rulerStartColor = sc; - rulerEndColor = ec; - - repaint(); - } - // end kenn - - /** - * @param lastCursor The lastCursor to set. - */ - public void setLastCursor(Coords lastCursor) { - this.lastCursor = lastCursor; - } - - /** - * @return Returns the lastCursor. - */ - public Coords getLastCursor() { - return lastCursor; - } - - /** - * @param highlighted The highlighted to set. - */ - public void setHighlighted(Coords highlighted) { - this.highlighted = highlighted; - } - - /** - * @return Returns the highlighted. - */ - public Coords getHighlighted() { - return highlighted; - } - - /** - * @param selected The selected to set. - */ - public void setSelected(Coords selected) { - this.selected = selected; - } - - /** - * @return Returns the selected. - */ - public Coords getSelected() { - return selected; - } - - /** - * @param firstLOS The firstLOS to set. - */ - public void setFirstLOS(Coords firstLOS) { - this.firstLOS = firstLOS; - } - - /** - * @return Returns the firstLOS. - */ - public Coords getFirstLOS() { - return firstLOS; - } - - /** - * Determines if this Board contains the Coords, - * and if so, "selects" that Coords. - * - * @param coords the Coords. - */ - public void select(Coords coords) { - if(coords == null || game.getBoard().contains(coords)) { - setSelected(coords); - moveCursor(selectedSprite, coords); - moveCursor(firstLOSSprite, null); - moveCursor(secondLOSSprite, null); - processBoardViewEvent(new BoardViewEvent(this, coords, null, BoardViewEvent.BOARD_HEX_SELECTED,0)); - } - } - - /** - * "Selects" the specified Coords. - * - * @param x the x coordinate. - * @param y the y coordinate. - */ - public void select(int x, int y) { - select(new Coords(x, y)); - } - - /** - * Determines if this Board contains the Coords, - * and if so, highlights that Coords. - * - * @param coords the Coords. - */ - public void highlight(Coords coords) { - if(coords == null || game.getBoard().contains(coords)) { - setHighlighted(coords); - moveCursor(highlightSprite, coords); - moveCursor(firstLOSSprite, null); - moveCursor(secondLOSSprite, null); - processBoardViewEvent(new BoardViewEvent(this, coords, null, BoardViewEvent.BOARD_HEX_HIGHLIGHTED, 0)); - } - } - - /** - * Highlights the specified Coords. - * - * @param x the x coordinate. - * @param y the y coordinate. - */ - public void highlight(int x, int y) { - highlight(new Coords(x, y)); - } - - /** - * Determines if this Board contains the Coords, - * and if so, "cursors" that Coords. - * - * @param coords the Coords. - */ - public void cursor(Coords coords) { - if(coords == null || game.getBoard().contains(coords)) { - if(getLastCursor() == null || coords == null || !coords.equals(getLastCursor())) { - setLastCursor(coords); - moveCursor(cursorSprite, coords); - moveCursor(firstLOSSprite, null); - moveCursor(secondLOSSprite, null); - processBoardViewEvent(new BoardViewEvent(this, coords, null, BoardViewEvent.BOARD_HEX_CURSOR, 0)); - } else { - setLastCursor(coords); - } - } - } - - /** - * "Cursors" the specified Coords. - * - * @param x the x coordinate. - * @param y the y coordinate. - */ - public void cursor(int x, int y) { - cursor(new Coords(x, y)); - } - - public void checkLOS(Coords c) { - if(c == null || game.getBoard().contains(c)) { - if (getFirstLOS() == null) { - setFirstLOS(c); - firstLOSHex(c); - processBoardViewEvent(new BoardViewEvent(this, c, null, BoardViewEvent.BOARD_FIRST_LOS_HEX, 0)); - } else { - secondLOSHex(c,getFirstLOS()); - processBoardViewEvent(new BoardViewEvent(this, c, null, BoardViewEvent.BOARD_SECOND_LOS_HEX, 0)); - setFirstLOS(null); - } - } - } - - /** - * Determines if this Board contains the (x, y) Coords, - * and if so, notifies listeners about the specified mouse - * action. - */ - public void mouseAction(int x, int y, int mtype, int modifiers) { - if(game.getBoard().contains(x, y)) { - Coords c = new Coords(x, y); - switch(mtype) { - case BOARD_HEX_CLICK : - if ((modifiers & java.awt.event.InputEvent.CTRL_MASK) != 0) { - checkLOS(c); - } else { - processBoardViewEvent(new BoardViewEvent(this, c, null, BoardViewEvent.BOARD_HEX_CLICKED, modifiers)); - } - break; - case BOARD_HEX_DOUBLECLICK : - processBoardViewEvent(new BoardViewEvent(this, c, null, BoardViewEvent.BOARD_HEX_DOUBLECLICKED, modifiers)); - break; - case BOARD_HEX_DRAG : - processBoardViewEvent(new BoardViewEvent(this, c, null, BoardViewEvent.BOARD_HEX_DRAGGED, modifiers)); - break; - } - } - } - - /** - * Notifies listeners about the specified mouse action. - * - * @param coords the Coords. - */ - public void mouseAction(Coords coords, int mtype, int modifiers) { - mouseAction(coords.x, coords.y, mtype, modifiers); - } - - /** - * Return, whether a popup may be drawn, this currently means, whether no scrolling took place. - */ - public boolean mayDrawPopup() { - return !scrolled; - } - - /* (non-Javadoc) - * @see megamek.common.BoardListener#boardNewBoard(megamek.common.BoardEvent) - */ - public void boardNewBoard(BoardEvent b) { - updateBoard(); - } - - /* (non-Javadoc) - * @see megamek.common.BoardListener#boardChangedHex(megamek.common.BoardEvent) - */ - public void boardChangedHex(BoardEvent b) { - IHex hex = game.getBoard().getHex(b.getCoords()); - tileManager.clearHex(hex); - tileManager.waitForHex(hex); - if (boardGraph != null) { - redrawAround(b.getCoords()); - } - } - - //TODO Is there a better solution? - //This is required because the BoardView creates the redraw thread - //that must be stopped explicitly - public void die() { - redrawWorker.stop(); - } - - private GameListener gameListener = new GameListenerAdapter(){ - - public void gameEntityNew(GameEntityNewEvent e) { - redrawAllEntities(); - } - - public void gameEntityRemove(GameEntityRemoveEvent e) { - redrawAllEntities(); - } - - public void gameEntityChange(GameEntityChangeEvent e) { - java.util.Vector mp = e.getMovePath(); - if (mp != null && mp.size() > 0 && GUIPreferences.getInstance().getShowMoveStep()) { - addMovingUnit(e.getEntity(), mp); - }else { - redrawEntity(e.getEntity()); - } - } - - public void gameNewAction(GameNewActionEvent e) { - EntityAction ea = e.getAction(); - if (ea instanceof AttackAction) { - addAttack((AttackAction)ea); - } - } - - public void gameBoardNew(GameBoardNewEvent e) { - IBoard b = e.getOldBoard(); - if (b != null) { - b.removeBoardListener(BoardView1.this); - } - b = e.getNewBoard(); - if (b != null) { - b.addBoardListener(BoardView1.this); - } - updateBoard(); - } - - public void gameBoardChanged(GameBoardChangeEvent e) { - boardImage = null; - boardGraph = null; - redrawAllEntities(); - } - }; - - protected void updateBoard() { - updateBoardSize(); - backGraph = null; - backImage = null; - backSize = null; - boardImage = null; - boardGraph = null; - tileManager.reset(); - redrawAllEntities(); - } - - /* - * It's not quite polished solution, but on other hand it's better then nothing. - */ - protected class RedrawWorker implements Runnable { - - private boolean finished = false; - - public void start() { - Thread thread = new Thread(this, "BoardView RedrawWorker Thread"); //$NON-NLS-1$ - thread.start(); - - } - - public void stop() { - finished = true; - } - - public void run() { - long lastTime = System.currentTimeMillis(); - long currentTime = System.currentTimeMillis(); - while (!finished) { - try { - Thread.sleep(20); - } catch(InterruptedException ex) { - // duh? - } - if (finished) { - break; - } - if (!isShowing()) { - currentTime = System.currentTimeMillis(); - lastTime = currentTime; - continue; - } - currentTime = System.currentTimeMillis(); - boolean redraw = false; - for (int i = 0; i < displayables.size(); i++) { - Displayable disp = (Displayable) displayables.elementAt(i); - if (!disp.isSliding()) { - disp.setIdleTime(currentTime - lastTime, true); - } else { - redraw = redraw || disp.slide(); - } - } - if (backSize != null) { - redraw = redraw || doMoveUnits(currentTime - lastTime); - redraw = redraw || doScroll(); - checkTooltip(); - } else { - repaint(100); - } - if (redraw) { - repaint(); - } - lastTime = currentTime; - } - } - } -} diff --git a/java/cvsvintage/BoardView1_1.214_1.215_v1.java b/java/cvsvintage/BoardView1_1.214_1.215_v1.java deleted file mode 100644 index cb9c54c..0000000 --- a/java/cvsvintage/BoardView1_1.214_1.215_v1.java +++ /dev/null @@ -1,4253 +0,0 @@ -/* - * MegaMek - - * Copyright (C) 2000,2001,2002,2003,2004,2005 Ben Mazur (bmazur@sev.org) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -package megamek.client.ui.AWT; - -// Defines Iterator class for JDK v1.1 -import com.sun.java.util.collections.*; -import java.awt.*; -import java.awt.event.*; -import java.awt.image.*; -import java.util.Enumeration; - -import megamek.client.event.BoardViewEvent; -import megamek.client.event.BoardViewListener; -import megamek.client.ui.AWT.util.*; -import megamek.common.*; -import megamek.common.actions.*; -import megamek.common.event.BoardEvent; -import megamek.common.event.BoardListener; -import megamek.common.event.GameEntityRemoveEvent; -import megamek.common.event.GameNewActionEvent; -import megamek.common.event.GameBoardNewEvent; -import megamek.common.event.GameBoardChangeEvent; -import megamek.common.event.GameEntityChangeEvent; -import megamek.common.event.GameEntityNewEvent; -import megamek.common.event.GameListener; -import megamek.common.event.GameListenerAdapter; -import megamek.common.preference.PreferenceManager; - -import java.util.Properties; - -/** - * Displays the board; lets the user scroll around and select points on it. - */ -public class BoardView1 - extends Canvas - implements IBoardView, BoardListener, MouseListener, MouseMotionListener, KeyListener, AdjustmentListener -{ - private static final int TRANSPARENT = 0xFFFF00FF; - - // the dimensions of megamek's hex images - private static final int HEX_W = 84; - private static final int HEX_H = 72; - private static final int HEX_WC = HEX_W - HEX_W/4; - - // The list of valid zoom factors. Other values cause map aliasing, - // I can't be bothered figuring out why. - Ben - private static final float[] ZOOM_FACTORS = - { 0.30f, 0.41f, 0.50f, - 0.60f, 0.68f, 0.79f, - 0.90f, 1.00f - //1.09f, 1.17f - }; - - private ImageCache[] scaledImageCaches; - - // the index of zoom factor 1.00f - private static final int BASE_ZOOM_INDEX = 7; - - // line width of the c3 network lines - private static final int C3_LINE_WIDTH = 1; - - private static Font FONT_7 = new Font("SansSerif", Font.PLAIN, 7); //$NON-NLS-1$ - private static Font FONT_8 = new Font("SansSerif", Font.PLAIN, 8); //$NON-NLS-1$ - private static Font FONT_9 = new Font("SansSerif", Font.PLAIN, 9); //$NON-NLS-1$ - private static Font FONT_10 = new Font("SansSerif", Font.PLAIN, 10); //$NON-NLS-1$ - private static Font FONT_12 = new Font("SansSerif", Font.PLAIN, 12); //$NON-NLS-1$ - - private Dimension hex_size = null; - private boolean isJ2RE; - - private Font font_hexnum = FONT_10; - private Font font_elev = FONT_9; - private Font font_minefield = FONT_12; - - private IGame game; - private Frame frame; - - private Point mousePos = new Point(); - private Rectangle view = new Rectangle(); - private Point offset = new Point(); - private Dimension boardSize; - - // scrolly stuff: - private Scrollbar vScrollbar = null; - private Scrollbar hScrollbar = null; - private boolean isScrolling = false; - private Point scroll = new Point(); - private boolean initCtlScroll; - private boolean ctlKeyHeld = false; - private int previousMouseX; - private int previousMouseY; - - // back buffer to draw to - private Image backImage; - private Dimension backSize; - private Graphics backGraph; - - // buffer for all the hexes you can possibly see - private Image boardImage; - private Rectangle boardRect; - private Graphics boardGraph; - - // entity sprites - private Vector entitySprites = new Vector(); - private Hashtable entitySpriteIds = new Hashtable(); - - // sprites for the three selection cursors - private CursorSprite cursorSprite; - private CursorSprite highlightSprite; - private CursorSprite selectedSprite; - private CursorSprite firstLOSSprite; - private CursorSprite secondLOSSprite; - - // sprite for current movement - private Vector pathSprites = new Vector(); - - // vector of sprites for all firing lines - private Vector attackSprites = new Vector(); - - // vector of sprites for C3 network lines - private Vector C3Sprites = new Vector(); - - // tooltip stuff - private Window tipWindow; - private boolean isTipPossible = false; - private long lastIdle; - - private TilesetManager tileManager = null; - - // polygons for a few things - private Polygon hexPoly; - private Polygon[] facingPolys; - private Polygon[] movementPolys; - - // the player who owns this BoardView's client - private Player localPlayer = null; - - // should we mark deployment hexes for a player? - private Player m_plDeployer = null; - - // should be able to turn it off(board editor) - private boolean useLOSTool = true; - - // Initial scale factor for sprites and map - private boolean hasZoomed = false; - public int zoomIndex; - private float scale; - private Hashtable scaledImageCache = new Hashtable(); - - // Displayables (Chat box, etc.) - private Vector displayables = new Vector(); - - // Move units step by step - private Vector movingUnits = new Vector(); - private long moveWait = 0; - - // moving entity sprites - private Vector movingEntitySprites = new Vector(); - private Hashtable movingEntitySpriteIds = new Hashtable(); - private Vector ghostEntitySprites = new Vector(); - protected transient Vector boardListeners = new Vector(); - - // wreck sprites - private Vector wreckSprites = new Vector(); - - private Coords rulerStart; // added by kenn - private Coords rulerEnd; // added by kenn - private Color rulerStartColor; // added by kenn - private Color rulerEndColor; // added by kenn - - // Position of the mouse before right mouse button was pressed. Used to have an anchor for scrolling - private Point oldMousePosition = null; - - // Indicate that a scrolling took place, so no popup should be drawn on right mouse button release - private boolean scrolled = false; - - private Coords lastCursor; - private Coords highlighted; - private Coords selected; - private Coords firstLOS; - - private ClientGUI clientgui; - - private RedrawWorker redrawWorker = new RedrawWorker(); - - /** - * Construct a new board view for the specified game - */ - public BoardView1(IGame game, Frame frame) throws java.io.IOException { - this(game, frame, null); - } - - /** - * Construct a new board view for the specified game - */ - public BoardView1(IGame game, Frame frame, ClientGUI clientgui) throws java.io.IOException { - this.clientgui = clientgui; - this.game = game; - this.frame = frame; - - tileManager = new TilesetManager(this); - - game.addGameListener(gameListener); - game.getBoard().addBoardListener(this); - redrawWorker.start(); - addKeyListener(this); - addMouseListener(this); - addMouseMotionListener(this); - /* MouseWheelListener isn't a v1.3.1 API ** - try{ - addMouseWheelListener( new MouseWheelListener(){ - public void mouseWheelMoved(MouseWheelEvent we){ - if (we.getWheelRotation() > 0){ - zoomIn(); - } else { - zoomOut(); - } - } - }); - } catch ( Throwable error ){ - System.out.println("Mouse wheel not supported by this jvm"); - } - /* MouseWheelListener isn't a v1.3.1 API */ - - // only use scaling if we're using Java 2, otherwise we get memory leaks etc. - Properties p = System.getProperties(); - String javaVersion = p.getProperty( "java.version" ); //$NON-NLS-1$ - if ( javaVersion.charAt(2) == '1' ){ - isJ2RE = false; - zoomIndex = BASE_ZOOM_INDEX; - } else { - isJ2RE = true; - zoomIndex = GUIPreferences.getInstance().getMapZoomIndex(); - checkZoomIndex(); - hasZoomed = true; - } - scale = ZOOM_FACTORS[ zoomIndex ]; - - updateFontSizes(); - updateBoardSize(); - - // tooltip - tipWindow = new Window(frame); - - hex_size = new Dimension((int)(HEX_W*scale), (int)(HEX_H*scale)); - - initPolys(); - - cursorSprite = new CursorSprite(Color.cyan); - highlightSprite = new CursorSprite(Color.white); - selectedSprite = new CursorSprite(Color.blue); - firstLOSSprite = new CursorSprite(Color.red); - secondLOSSprite = new CursorSprite(Color.red); - - scaledImageCaches = new ImageCache[ZOOM_FACTORS.length]; - for(int i = 0;iScrollbar - * @param horizontal - the horizontal Scrollbar - */ - public void setScrollbars (Scrollbar vertical, Scrollbar horizontal) { - this.vScrollbar = vertical; - this.hScrollbar = horizontal; - - // When the scroll bars are adjusted, update our offset. - this.vScrollbar.addAdjustmentListener (this); - this.hScrollbar.addAdjustmentListener (this); - } - - /** - * Update ourself when a scroll bar is adjusted. - * - * @param event - the AdjustmentEvent that caused this call. - */ - public void adjustmentValueChanged (AdjustmentEvent event) { - Point oldPt = this.scroll; - Point newPt = new Point (oldPt.x, oldPt.y); - if (event.getAdjustable().getOrientation() == Adjustable.VERTICAL) { - newPt.y = event.getValue(); - } else { - newPt.x = event.getValue(); - } - this.scroll.setLocation (newPt); - this.repaint(); - } - - public void paint(Graphics g) { - update(g); - } - - /** - * Draw the screen! - */ - public void update(Graphics g) { - // Limit our size to the viewport of the scroll pane. - final Dimension size = getSize(); - // final long startTime = System.currentTimeMillis(); // commentme - - // Make sure our scrollbars have the right sizes. - // N.B. A buggy Sun implementation makes me to do this here instead - // of updateBoardSize() (which is where *I* think it belongs). - if (null != this.vScrollbar) { - this.vScrollbar.setVisibleAmount (size.height); - this.vScrollbar.setBlockIncrement (size.height); - this.vScrollbar.setUnitIncrement ((int) (scale * HEX_H / 2.0)); - this.vScrollbar.setMaximum (boardSize.height); - } - if (null != this.hScrollbar) { - this.hScrollbar.setVisibleAmount (size.width); - this.hScrollbar.setBlockIncrement (size.width); - this.hScrollbar.setUnitIncrement ((int) (scale * HEX_W / 2.0)); - this.hScrollbar.setMaximum (boardSize.width); - } - - // update view, offset - view.setLocation(scroll); - view.setSize(getOptimalView(size)); - offset.setLocation(getOptimalOffset(size)); - - if (!this.isTileImagesLoaded()) { - g.drawString(Messages.getString("BoardView1.loadingImages"), 20, 50); //$NON-NLS-1$ - if (!tileManager.isStarted()) { - System.out.println("boardview1: loading images for board"); //$NON-NLS-1$ - tileManager.loadNeededImages(game); - } - return; - } - - // make sure back buffer is valid - if (backGraph == null || !view.getSize().equals(backSize)) { - // make new back buffer - backSize = view.getSize(); - backImage = createImage(backSize.width, backSize.height); - backGraph = backImage.getGraphics(); - } - - // make sure board rectangle contains our current view rectangle - if (boardImage == null || !boardRect.union(view).equals(boardRect)) { - updateBoardImage(); - } - - // draw onto the back buffer: - - // draw the board - backGraph.drawImage(boardImage, 0, 0, this); - - // draw wrecks - if (GUIPreferences.getInstance().getShowWrecks()) { - drawSprites(wreckSprites); - } - - // Minefield signs all over the place! - drawMinefields(); - - // Artillery targets - drawArtilleryHexes(); - - // draw highlight border - drawSprite(highlightSprite); - - // draw cursors - drawSprite(cursorSprite); - drawSprite(selectedSprite); - drawSprite(firstLOSSprite); - drawSprite(secondLOSSprite); - - // draw deployment indicators - if (m_plDeployer != null) { - drawDeployment(); - } - - // draw C3 links - drawSprites(C3Sprites); - - // draw onscreen entities - drawSprites(entitySprites); - - // draw moving onscreen entities - drawSprites(movingEntitySprites); - - // draw ghost onscreen entities - drawSprites(ghostEntitySprites); - - // draw onscreen attacks - drawSprites(attackSprites); - - // draw movement, if valid - drawSprites(pathSprites); - - // added by kenn - // draw the ruler line - if (rulerStart != null) { - Point start = getCentreHexLocation(rulerStart); - if (rulerEnd != null) { - Point end = getCentreHexLocation(rulerEnd); - backGraph.setColor(Color.yellow); - backGraph.drawLine(start.x - boardRect.x, start.y - boardRect.y, end.x - boardRect.x, end.y - boardRect.y); - - backGraph.setColor(rulerEndColor); - backGraph.fillRect(end.x - boardRect.x - 1, end.y - boardRect.y - 1, 2, 2); - } - - backGraph.setColor(rulerStartColor); - backGraph.fillRect(start.x - boardRect.x - 1, start.y - boardRect.y - 1, 2, 2); - } - // end kenn - - // draw all the "displayables" - for (int i = 0; i < displayables.size(); i++) { - Displayable disp = (Displayable) displayables.elementAt(i); - disp.draw(backGraph, backSize); - } - - // draw the back buffer onto the screen - // first clear the entire view if the map has been zoomed - if ( hasZoomed == true ){ - Image tmpImage = createImage( size.width, size.height ); - Graphics tmpGraphics = tmpImage.getGraphics(); - tmpGraphics.drawImage(backImage, offset.x, offset.y, this); - g.drawImage(tmpImage, 0, 0, this); - hasZoomed=false; - } else { - g.drawImage(backImage, offset.x, offset.y, this); - } - //g.drawString(""+scale, 10, 10); - - // final long finishTime = System.currentTimeMillis();//commentme - // System.out.println("BoardView1: updated screen in " + (finishTime - startTime) + " ms."); //commentme - } - - /** - * Updates the boardSize variable with the proper values for this board. - */ - private void updateBoardSize() { - int width = game.getBoard().getWidth() * (int)(HEX_WC*scale) + (int)(HEX_W/4*scale); - int height = game.getBoard().getHeight() * (int)(HEX_H*scale) + (int)(HEX_H/2*scale); - boardSize = new Dimension(width, height); - } - - /** - * Think up the size of the view rectangle based on the size of the component - * and the size of board - */ - private Dimension getOptimalView(Dimension size) { - return new Dimension( - Math.min(size.width, boardSize.width), - Math.min(size.height, boardSize.height)); - } - - /** - * Where should the offset be for this screen size? - */ - private Point getOptimalOffset(Dimension size) { - int ox = 0; - int oy = 0; - if (size.width > boardSize.width) { - ox = (size.width - boardSize.width) / 2; - } - if (size.height > boardSize.height) { - oy = (size.height - boardSize.height) / 2; - } - return new Point(ox, oy); - } - - /** - * Repaint the bounds of a sprite, offset by view - */ - private void repaintBounds(Rectangle bounds) { - if (view != null) { - repaint(bounds.x - view.x + offset.x, bounds.y - view.y + offset.y, bounds.width, bounds.height); - } - } - - /** - * Looks through a vector of buffered images and draws them if they're - * onscreen. - */ - private synchronized void drawSprites(Vector spriteVector) { - for (int i = 0; i < spriteVector.size(); i++) { - final Sprite sprite = (Sprite)spriteVector.get(i); - drawSprite(sprite); - } - } - - /** - * Draws a sprite, if it is in the current view - */ - private final void drawSprite(Sprite sprite) { - if (view.intersects(sprite.getBounds())) { - final int drawX = sprite.getBounds().x - view.x; - final int drawY = sprite.getBounds().y - view.y; - if (!sprite.isReady()) { - sprite.prepare(); - } - sprite.drawOnto(backGraph, drawX, drawY, this); - } - } - - /** - * Manages a cache of scaled images. - */ - private Image getScaledImage(Image base) { - if (base == null) { - return null; - } - if ( zoomIndex == BASE_ZOOM_INDEX ) { - return base; - } - - - Image scaled = (Image) scaledImageCaches[zoomIndex].get(base); - if (scaled == null) { - Dimension d = getImageBounds(base).getSize(); - d.width *= scale; - d.height *= scale; - - scaled = scale(base, d.width, d.height); - - MediaTracker tracker = new MediaTracker(this); - tracker.addImage( scaled, 1 ); - // Wait for image to load - try{ - tracker.waitForID( 1 ); - } catch ( InterruptedException e ){ e.printStackTrace(); } - - scaledImageCaches[zoomIndex].put(base, scaled); - } - return scaled; - } - - /** - * The actual scaling code. - */ - private Image scale(Image img, int width, int height) { - ImageFilter filter; - - filter = new ImprovedAveragingScaleFilter(img.getWidth(null), - img.getHeight(null), - width, height); - - ImageProducer prod; - prod = new FilteredImageSource(img.getSource(), filter); - return Toolkit.getDefaultToolkit().createImage(prod); - } - - private static Rectangle getImageBounds(Image im) { - return new Rectangle(-im.getWidth(null) / 2, -im.getHeight(null) / 2, im.getWidth(null), im.getHeight(null)); - } - - /** - * The key assigned to each scaled and cached image. Enables easy - * retrieval from the hash table. - */ - private static class ScaledCacheKey { - private Image base; - private Dimension bounds; - - public ScaledCacheKey(Image base, Dimension bounds) { - this.bounds = bounds; - this.base = base; - } - - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof ScaledCacheKey)) return false; - - final ScaledCacheKey scaledCacheKey = (ScaledCacheKey) o; - - if (!base.equals(scaledCacheKey.base)) return false; - if (!bounds.equals(scaledCacheKey.bounds)) return false; - - return true; - } - - public int hashCode() { - int result; - result = base.hashCode(); - result = 29 * result + bounds.hashCode(); - return result; - } - } - - /** - * Draw an outline around legal deployment hexes - */ - private void drawDeployment() { - // only update visible hexes - int drawX = view.x / (int)(HEX_WC*scale) - 1; - int drawY = view.y / (int)(HEX_H*scale) - 1; - - int drawWidth = view.width / (int)(HEX_WC*scale) + 3; - int drawHeight = view.height / (int)(HEX_H*scale) + 3; - IBoard board = game.getBoard(); - // loop through the hexes - for (int i = 0; i < drawHeight; i++) { - for (int j = 0; j < drawWidth; j++) { - Coords c = new Coords(j + drawX, i + drawY); - Point p = getHexLocation(c); - p.translate(-(view.x), -(view.y)); - if (board.isLegalDeployment(c, m_plDeployer)) { - backGraph.setColor(Color.yellow); - int[] xcoords = { p.x + (int)(21*scale), p.x + (int)(62*scale), p.x + (int)(83*scale), p.x + (int)(83*scale), - p.x + (int)(62*scale), p.x + (int)(21*scale), p.x, p.x }; - int[] ycoords = { p.y, p.y, p.y + (int)(35*scale), p.y + (int)(36*scale), p.y + (int)(71*scale), - p.y + (int)(71*scale), p.y + (int)(36*scale), p.y + (int)(35*scale) }; - backGraph.drawPolygon(xcoords, ycoords, 8); - } - } - } - } - - /** - * returns the weapon selected in the mech display, - * or null if none selected or it is not artillery - **/ - private Mounted getSelectedArtilleryWeapon() { - Entity e = clientgui.mechD.getCurrentEntity(); - Mounted weapon = null; - - if(e != null) { - weapon = e.getEquipment(clientgui.mechD.wPan.getSelectedWeaponNum()); - } - if (weapon != null) { - if(!(weapon.getType() instanceof WeaponType && weapon.getType().hasFlag(WeaponType.F_ARTILLERY))) { - weapon = null; - } - //otherwise, a weapon is selected, and it is artillery - } - return weapon; - } - - /** Display artillery modifier in pretargeted hexes - */ - private void drawArtilleryHexes() { - if (clientgui != null) { - Entity e = clientgui.mechD.getCurrentEntity(); - Mounted weapon = getSelectedArtilleryWeapon(); - - if(game.getArtillerySize()==0 && weapon==null) { - return; //nothing to do - } - - if (!e.getOwner().equals(clientgui.getClient().getLocalPlayer())) { - return; // Not my business to see this - } - - int drawX = view.x / (int)(HEX_WC*scale) - 1; - int drawY = view.y / (int)(HEX_H*scale) - 1; - - int drawWidth = view.width / (int)(HEX_WC*scale) + 3; - int drawHeight = view.height / (int)(HEX_H*scale) + 3; - - IBoard board = game.getBoard(); - Image scaledImage; - - // loop through the hexes - for (int i = 0; i < drawHeight; i++) { - for (int j = 0; j < drawWidth; j++) { - Coords c = new Coords(j + drawX, i + drawY); - Point p = getHexLocation(c); - p.translate(-(view.x), -(view.y)); - - if (!board.contains(c)){ continue; } - - if(weapon != null) { - //process targetted hexes - int amod = 0; - //Check the predesignated hexes - if(e.getOwner().getArtyAutoHitHexes().contains(c)) { - amod = TargetRoll.AUTOMATIC_SUCCESS; - } - else { - amod = e.aTracker.getModifier(weapon, c); - } - - if(amod!=0) { - - //draw the crosshairs - if(amod==TargetRoll.AUTOMATIC_SUCCESS) { - //predesignated or already hit - scaledImage = getScaledImage(tileManager.getArtilleryTarget(TilesetManager.ARTILLERY_AUTOHIT)); - } else { - scaledImage = getScaledImage(tileManager.getArtilleryTarget(TilesetManager.ARTILLERY_ADJUSTED)); - } - - backGraph.drawImage(scaledImage, p.x, p.y, this); - } - } - //process incoming attacks - requires server to update client's view of game - - for(Enumeration attacks=game.getArtilleryAttacks();attacks.hasMoreElements();) { - ArtilleryAttackAction a = (ArtilleryAttackAction)attacks.nextElement(); - - if(a.getWR().waa.getTarget(game).getPosition().equals(c)) { - scaledImage = getScaledImage(tileManager.getArtilleryTarget(TilesetManager.ARTILLERY_INCOMING)); - backGraph.drawImage(scaledImage, p.x, p.y, this); - break; //do not draw multiple times, tooltop will show all attacks - } - } - } - } - } - } - - private Vector getArtilleryAttacksAtLocation(Coords c) { - Vector v = new Vector(); - for(Enumeration attacks=game.getArtilleryAttacks();attacks.hasMoreElements();) { - ArtilleryAttackAction a = (ArtilleryAttackAction)attacks.nextElement(); - - if(a.getWR().waa.getTarget(game).getPosition().equals(c)) { - v.addElement(a); - } - } - return v; - } - - /** - * Writes "MINEFIELD" in minefield hexes... - */ - private void drawMinefields() { - // only update visible hexes - int drawX = view.x / (int)(HEX_WC*scale) - 1; - int drawY = view.y / (int)(HEX_H*scale) - 1; - - int drawWidth = view.width / (int)(HEX_WC*scale) + 3; - int drawHeight = view.height / (int)(HEX_H*scale) + 3; - - IBoard board = game.getBoard(); - // loop through the hexes - for (int i = 0; i < drawHeight; i++) { - for (int j = 0; j < drawWidth; j++) { - Coords c = new Coords(j + drawX, i + drawY); - Point p = getHexLocation(c); - p.translate(-(view.x), -(view.y)); - - if (!board.contains(c)){ continue; } - if (!game.containsMinefield(c)){ continue; } - - Minefield mf = (Minefield) game.getMinefields(c).elementAt(0); - - Image tmpImage = getScaledImage( tileManager.getMinefieldSign()); - backGraph.drawImage( - tmpImage, - p.x + (int)(13*scale), - p.y + (int)(13*scale), - this); - - backGraph.setColor(Color.black); - int nbrMfs = game.getNbrMinefields(c); - if (nbrMfs > 1) { - drawCenteredString(Messages.getString("BoardView1.Multiple"), //$NON-NLS-1$ - p.x, - p.y + (int)(51*scale), - font_minefield, - backGraph); - } else if (nbrMfs == 1) { - switch (mf.getType()) { - case (Minefield.TYPE_CONVENTIONAL) : - drawCenteredString( - Messages.getString("BoardView1.Conventional"), //$NON-NLS-1$ - p.x, - p.y + (int)(51*scale), - font_minefield, - backGraph); - break; - case (Minefield.TYPE_THUNDER) : - drawCenteredString( - Messages.getString("BoardView1.Thunder") + mf.getDamage() + ")", //$NON-NLS-1$ //$NON-NLS-2$ - p.x, - p.y + (int)(51*scale), - font_minefield, - backGraph); - break; - case (Minefield.TYPE_THUNDER_INFERNO) : - drawCenteredString( - Messages.getString("BoardView1.Thunder-Inf") + mf.getDamage() + ")", //$NON-NLS-1$ //$NON-NLS-2$ - p.x, - p.y + (int)(51*scale), - font_minefield, - backGraph); - break; - case (Minefield.TYPE_THUNDER_ACTIVE) : - drawCenteredString( - Messages.getString("BoardView1.Thunder-Actv") + mf.getDamage() + ")", //$NON-NLS-1$ //$NON-NLS-2$ - p.x, - p.y + (int)(51*scale), - font_minefield, - backGraph); - break; - case (Minefield.TYPE_COMMAND_DETONATED) : - drawCenteredString( - Messages.getString("BoardView1.Command-"), //$NON-NLS-1$ - p.x, - p.y + (int)(51*scale), - font_minefield, - backGraph); - drawCenteredString( - Messages.getString("BoardView1.detonated"), //$NON-NLS-1$ - p.x, - p.y + (int)(60*scale), - font_minefield, - backGraph); - break; - case (Minefield.TYPE_VIBRABOMB) : - drawCenteredString( - Messages.getString("BoardView1.Vibrabomb"), //$NON-NLS-1$ - p.x, - p.y + (int)(51*scale), - font_minefield, - backGraph); - if (mf.getPlayerId() == localPlayer.getId()) { - drawCenteredString( - "(" + mf.getSetting() + ")", //$NON-NLS-1$ //$NON-NLS-2$ - p.x, - p.y + (int)(60*scale), - font_minefield, - backGraph); - } - break; - } - } - } - } - } - - private void drawCenteredString( String string, int x, int y, Font font, Graphics graph ){ - FontMetrics currentMetrics = getFontMetrics(font); - int stringWidth = currentMetrics.stringWidth(string); - - x += (int)((hex_size.width - stringWidth)/2); - - graph.setFont(font); - graph.drawString( string, x, y ); - } - - /** - * Updates the board buffer to contain all the hexes needed by the view. - */ - private void updateBoardImage() { - // check to make sure image is big enough - if (boardGraph == null || view.width > boardRect.width - || view.height > boardRect.height) { - /* Ok, some history here. Before the zoom patch, the - boardImage was created with the same size as the view. - After the zoom patch, the boardImage was created with - the same size as the entire board (all maps). This - change ate up a hideous amount of memory (eg: in a 3x3 - map set test with one mech, memory usage went from - about 15MB to 60MB). I have now changed it back to the - old way, and the zoom feature *seems* to still work. - Why the zoom author made the change, I cannot say. */ - boardImage = createImage(view.width, view.height); - //boardImage = createImage(boardSize.width, boardSize.height); - /* ----- */ - - boardGraph = boardImage.getGraphics(); - - // Handle resizes correctly. - checkScrollBounds(); - boardRect = new Rectangle(view); - System.out.println("boardview1: made a new board buffer " + boardRect); //$NON-NLS-1$ - drawHexes(view); - - } - if (!boardRect.union(view).equals(boardRect)) { - moveBoardImage(); - } - } - - /** - * This method creates an image the size of the entire board (all - * mapsheets), draws the hexes onto it, and returns that image. - */ - public Image getEntireBoardImage() { - Image entireBoard = createImage(boardSize.width, boardSize.height); - Graphics temp = boardImage.getGraphics(); - boardGraph = entireBoard.getGraphics(); - drawHexes(new Rectangle(boardSize)); - boardGraph = temp; - return entireBoard; - } - - /** - * Moves the board view to another area. - */ - private void moveBoardImage() { - // salvage the old - - boardGraph.setClip(0, 0, boardRect.width, boardRect.height); - boardGraph.copyArea(0, 0, boardRect.width, boardRect.height, - boardRect.x - view.x, boardRect.y - view.y); - - // what's left to paint? - int midX = Math.max(view.x, boardRect.x); - int midWidth = view.width - Math.abs(view.x - boardRect.x); - Rectangle unLeft = new Rectangle(view.x, view.y, boardRect.x - view.x, view.height); - Rectangle unRight = new Rectangle(boardRect.x + boardRect.width, view.y, view.x -boardRect.x, view.height); - Rectangle unTop = new Rectangle(midX, view.y, midWidth, boardRect.y - view.y); - Rectangle unBottom = new Rectangle(midX, boardRect.y + boardRect.height, midWidth, view.y - boardRect.y); - - // update boardRect - boardRect = new Rectangle(view); - - // paint needed areas - if (unLeft.width > 0) { - drawHexes(unLeft); - } else if (unRight.width > 0) { - drawHexes(unRight); - } - if (unTop.height > 0) { - drawHexes(unTop); - } else if (unBottom.height > 0) { - drawHexes(unBottom); - } - } - - /** - * Redraws all hexes in the specified rectangle - */ - private void drawHexes(Rectangle rect) { - - // rect is the view - int drawX = (int)(rect.x / (HEX_WC*scale))-1; - int drawY = (int)(rect.y / (HEX_H*scale))-1; - - int drawWidth = (int)(rect.width / (HEX_WC*scale))+3; - int drawHeight = (int)(rect.height / (HEX_H*scale))+3; - - // only draw what we came to draw - boardGraph.setClip(rect.x - boardRect.x, rect.y - boardRect.y, - rect.width, rect.height); - - // clear, if we need to - if (rect.x < (21*scale)) { - boardGraph.clearRect( - rect.x - boardRect.x, rect.y - boardRect.y, - (int)(21*scale) - rect.x, rect.height); - } - if (rect.y < (36*scale)) { - boardGraph.clearRect( - rect.x - boardRect.x, rect.y - boardRect.y, - rect.width, (int)(36*scale) - rect.y); - } - if (rect.x > boardSize.width - view.width - (21*scale)) { - boardGraph.clearRect( - boardRect.width - (int)(21*scale), rect.y - boardRect.y, - (int)(21*scale), rect.height); - } - if (rect.y > boardSize.height - view.height - (int)(36*scale)) { - boardGraph.clearRect( - rect.x - boardRect.x, boardRect.height - (int)(36*scale), - rect.width, (int)(36*scale)); - } - - // draw some hexes - for (int i = 0; i < drawHeight; i++) { - for (int j = 0; j < drawWidth; j++) { - drawHex(new Coords(j + drawX, i + drawY)); - } - } - } - - /** - * Redraws a hex and all the hexes immediately around it. Used when the - * hex is on the screen, as opposed to when it is scrolling onto the screen, - * so it resets the clipping rectangle before drawing. - */ - private void redrawAround(Coords c) { - boardGraph.setClip(0, 0, boardRect.width, boardRect.height); - drawHex(c); - drawHex(c.translated(0)); - drawHex(c.translated(1)); - drawHex(c.translated(2)); - drawHex(c.translated(3)); - drawHex(c.translated(4)); - drawHex(c.translated(5)); - } - - /** - * Draws a hex onto the board buffer. This assumes that boardRect is - * current, and does not check if the hex is visible. - */ - private void drawHex(Coords c) { - if (!game.getBoard().contains(c)) { - return; - } - - final IHex hex = game.getBoard().getHex(c); - final Point hexLoc = getHexLocation(c); - - int level = hex.getElevation(); - int depth = hex.depth(); - - // offset drawing point - - int drawX = hexLoc.x - boardRect.x; - int drawY = hexLoc.y - boardRect.y; - - // draw picture - Image baseImage = tileManager.baseFor(hex); - Image scaledImage = getScaledImage(baseImage); - - boardGraph.drawImage(scaledImage, drawX, drawY, this); - - if (tileManager.supersFor(hex) != null) { - for (Iterator i = tileManager.supersFor(hex).iterator(); i.hasNext();){ - scaledImage = getScaledImage((Image)i.next()); - boardGraph.drawImage(scaledImage, drawX, drawY, this); - } - } - - if(GUIPreferences.getInstance().getBoolean(GUIPreferences.ADVANCED_DARKEN_MAP_AT_NIGHT) && - game.getOptions().booleanOption("night_battle") && - !game.isPositionIlluminated(c)) { - scaledImage = getScaledImage(tileManager.getNightFog()); - boardGraph.drawImage(scaledImage, drawX, drawY, this); - } - boardGraph.setColor(GUIPreferences.getInstance().getMapTextColor()); - - // draw hex number - if (scale >= 0.5){ - drawCenteredString( - c.getBoardNum(), - drawX, - drawY + (int)(12*scale), - font_hexnum, - boardGraph); - } - // level | depth - if (level != 0 && depth == 0 && zoomIndex > 3) { - drawCenteredString( - Messages.getString("BoardView1.LEVEL") + level, //$NON-NLS-1$ - drawX, - drawY + (int)(70*scale), - font_elev, - boardGraph); - } else if (depth != 0 && level == 0 && zoomIndex > 3 ) { - drawCenteredString( - Messages.getString("BoardView1.DEPTH") + depth, //$NON-NLS-1$ - drawX, - drawY + (int)(70*scale), - font_elev, - boardGraph); - } else if (level != 0 && depth != 0 && zoomIndex > 3) { - drawCenteredString( - Messages.getString("BoardView1.LEVEL") + level, //$NON-NLS-1$ - drawX, - drawY + (int)(60*scale), - font_elev, - boardGraph); - drawCenteredString( - Messages.getString("BoardView1.DEPTH") + depth, //$NON-NLS-1$ - drawX, - drawY + (int)(70*scale), - font_elev, - boardGraph); - } - - // draw elevation borders - boardGraph.setColor(Color.black); - if (drawElevationLine(c, 0)) { - boardGraph.drawLine(drawX + (int)(21*scale), drawY, drawX + (int)(62*scale), drawY); - } - if (drawElevationLine(c, 1)) { - boardGraph.drawLine(drawX + (int)(62*scale), drawY, drawX + (int)(83*scale), drawY + (int)(35*scale)); - } - if (drawElevationLine(c, 2)) { - boardGraph.drawLine(drawX + (int)(83*scale), drawY + (int)(36*scale), drawX + (int)(62*scale), drawY + (int)(71*scale)); - } - if (drawElevationLine(c, 3)) { - boardGraph.drawLine(drawX + (int)(62*scale), drawY + (int)(71*scale), drawX + (int)(21*scale), drawY + (int)(71*scale)); - } - if (drawElevationLine(c, 4)) { - boardGraph.drawLine(drawX + (int)(21*scale), drawY + (int)(71*scale), drawX, drawY + (int)(36*scale)); - } - if (drawElevationLine(c, 5)) { - boardGraph.drawLine(drawX, drawY + (int)(35*scale), drawX + (int)(21*scale), drawY); - } - - // draw mapsheet borders - if(GUIPreferences.getInstance().getShowMapsheets()) { - boardGraph.setColor(GUIPreferences.getInstance().getColor(GUIPreferences.ADVANCED_MAPSHEET_COLOR)); - if(c.x % 16 == 0) { - //left edge of sheet (edge 4 & 5) - boardGraph.drawLine(drawX + (int)(21*scale), drawY + (int)(71*scale), drawX, drawY + (int)(36*scale)); - boardGraph.drawLine(drawX, drawY + (int)(35*scale), drawX + (int)(21*scale), drawY); - } - else if(c.x % 16 == 15) { - //right edge of sheet (edge 1 & 2) - boardGraph.drawLine(drawX + (int)(62*scale), drawY, drawX + (int)(83*scale), drawY + (int)(35*scale)); - boardGraph.drawLine(drawX + (int)(83*scale), drawY + (int)(36*scale), drawX + (int)(62*scale), drawY + (int)(71*scale)); - } - if(c.y % 17 == 0) { - //top edge of sheet (edge 0 and possible 1 & 5) - boardGraph.drawLine(drawX + (int)(21*scale), drawY, drawX + (int)(62*scale), drawY); - if(c.x % 2 == 0) { - boardGraph.drawLine(drawX + (int)(62*scale), drawY, drawX + (int)(83*scale), drawY + (int)(35*scale)); - boardGraph.drawLine(drawX, drawY + (int)(35*scale), drawX + (int)(21*scale), drawY); - } - } else if (c.y % 17 == 16) { - //bottom edge of sheet (edge 3 and possible 2 & 4) - boardGraph.drawLine(drawX + (int)(62*scale), drawY + (int)(71*scale), drawX + (int)(21*scale), drawY + (int)(71*scale)); - if(c.x % 2 == 1) { - boardGraph.drawLine(drawX + (int)(83*scale), drawY + (int)(36*scale), drawX + (int)(62*scale), drawY + (int)(71*scale)); - boardGraph.drawLine(drawX + (int)(21*scale), drawY + (int)(71*scale), drawX, drawY + (int)(36*scale)); - } - } - boardGraph.setColor(Color.black); - } - } - - /** - * Returns true if an elevation line should be drawn between the starting - * hex and the hex in the direction specified. Results should be - * transitive, that is, if a line is drawn in one direction, it should be - * drawn in the opposite direction as well. - */ - private final boolean drawElevationLine(Coords src, int direction) { - final IHex srcHex = game.getBoard().getHex(src); - final IHex destHex = game.getBoard().getHexInDir(src, direction); - return destHex != null && srcHex.floor() != destHex.floor(); - } - - /** - * Returns the absolute position of the upper-left hand corner - * of the hex graphic - */ - private Point getHexLocation(int x, int y) { - return new Point( - x * (int)(HEX_WC*scale), - y * (int)(HEX_H*scale) + ((x & 1) == 1 ? (int)(HEX_H/2*scale) : 0)); - } - private Point getHexLocation(Coords c) { - return getHexLocation(c.x, c.y); - } - - // added by kenn - /** - * Returns the absolute position of the centre - * of the hex graphic - */ - private Point getCentreHexLocation(int x, int y) { - Point p = getHexLocation(x, y); - p.x += (HEX_W/2*scale); - p.y += (HEX_H/2*scale); - return p; - } - private Point getCentreHexLocation(Coords c) { - return getCentreHexLocation(c.x, c.y); - } - // end kenn - - /** - * Returns the coords at the specified point - */ - Coords getCoordsAt(Point p) { - final int x = (p.x + scroll.x - offset.x) / (int)(HEX_WC*scale); - final int y = ((p.y + scroll.y - offset.y) - ((x & 1) == 1 ? (int)(HEX_H/2*scale) : 0)) / (int)(HEX_H*scale); - return new Coords(x, y); - } - - /** - * Shows the tooltip thinger - */ - private void showTooltip() { - try { - final Point tipLoc = new Point(getLocationOnScreen()); - // retrieve tip text - String[] tipText = getTipText(mousePos); - if (tipText == null) { - return; - } - - // update tip text - tipWindow.removeAll(); - tipWindow.add(new TooltipCanvas(tipText)); - tipWindow.pack(); - - tipLoc.translate(mousePos.x, mousePos.y + 20); - - // adjust horizontal location for the tipWindow if it goes off the frame - if (frame.getLocation().x + frame.getSize().width < tipLoc.x + tipWindow.getSize().width + 10) { - if (frame.getSize().width > tipWindow.getSize().width) { - // bound it by the right edge of the frame - tipLoc.x -= tipLoc.x + tipWindow.getSize().width + 10 - frame.getSize().width - frame.getLocation().x; - } - else { - // too big to fit, left justify to the frame (roughly). - // how do I extract the first term of HEX_SIZE to use here?--LDE - tipLoc.x = getLocationOnScreen().x + hex_size.width; - } - } - - // set tip location - tipWindow.setLocation(tipLoc); - - tipWindow.show(); - } catch (Exception e) { - tipWindow = new Window(frame); - } - } - - /** - * The text to be displayed when the mouse is at a certain point - */ - private String[] getTipText(Point point) { - - int stringsSize = 0; - IHex mhex = null; - - // first, we have to determine how much text we are going to have - // are we on a hex? - final Coords mcoords = getCoordsAt(point); - if (GUIPreferences.getInstance().getShowMapHexPopup() && game.getBoard().contains(mcoords)) { - mhex = game.getBoard().getHex(mcoords); - stringsSize += 1; - } - - // check if it's on any entities - for (Iterator i = entitySprites.iterator(); i.hasNext();) { - final EntitySprite eSprite = (EntitySprite)i.next(); - if (eSprite.isInside(point)) { - stringsSize += 3; - } - } - - // check if it's on any attacks - for (Iterator i = attackSprites.iterator(); i.hasNext();) { - final AttackSprite aSprite = (AttackSprite)i.next(); - if (aSprite.isInside(point)) { - stringsSize += 1 + aSprite.weaponDescs.size(); - } - } - - // If the hex contains a building or rubble, make more space. - if ( mhex != null && - (mhex.containsTerrain(Terrains.RUBBLE) || - mhex.containsTerrain(Terrains.BUILDING)) ) { - stringsSize += 1; - } - - stringsSize += game.getNbrMinefields(mcoords); - - // Artillery - final Vector artilleryAttacks = getArtilleryAttacksAtLocation(mcoords); - stringsSize += artilleryAttacks.size(); - - // Artillery fire adjustment - final Mounted selectedWeapon = getSelectedArtilleryWeapon(); - if(selectedWeapon != null) - stringsSize++; - - // if the size is zip, you must a'quit - if (stringsSize == 0) { - return null; - } - - // now we can allocate an array of strings - String[] strings = new String[stringsSize]; - int stringsIndex = 0; - - // are we on a hex? - if (mhex != null) { - strings[stringsIndex] = Messages.getString("BoardView1.Hex") + mcoords.getBoardNum() //$NON-NLS-1$ - + Messages.getString("BoardView1.level") + mhex.getElevation(); //$NON-NLS-1$ - stringsIndex += 1; - - // Do we have rubble? - if ( mhex.containsTerrain(Terrains.RUBBLE) ) { - strings[stringsIndex] = Messages.getString("BoardView1.Rubble"); //$NON-NLS-1$ - stringsIndex += 1; - } - - // Do we have a building? - else if ( mhex.containsTerrain(Terrains.BUILDING) ) { - // Get the building. - Building bldg = game.getBoard().getBuildingAt( mcoords ); - StringBuffer buf = new StringBuffer( Messages.getString("BoardView1.Height") ); //$NON-NLS-1$ - // Each hex of a building has its own elevation. - buf.append( mhex.terrainLevel(Terrains.BLDG_ELEV) ); - buf.append( " " ); //$NON-NLS-1$ - buf.append( bldg.toString() ); - buf.append( Messages.getString("BoardView1.CF") ); //$NON-NLS-1$ - buf.append( bldg.getCurrentCF() ); - strings[stringsIndex] = buf.toString(); - stringsIndex += 1; - } - - if (game.containsMinefield(mcoords)) { - java.util.Vector minefields = game.getMinefields(mcoords); - for (int i = 0; i < minefields.size(); i++){ - Minefield mf = (Minefield) minefields.elementAt(i); - String owner = " (" + game.getPlayer(mf.getPlayerId()).getName() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - - switch (mf.getType()) { - case (Minefield.TYPE_CONVENTIONAL) : - strings[stringsIndex] = mf.getName()+Messages.getString("BoardView1.minefield") +" " + owner; //$NON-NLS-1$ //$NON-NLS-2$ - break; - case (Minefield.TYPE_THUNDER) : - strings[stringsIndex] = mf.getName()+Messages.getString("BoardView1.minefield")+"(" + mf.getDamage() + ")" + owner; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - break; - case (Minefield.TYPE_COMMAND_DETONATED) : - strings[stringsIndex] = mf.getName()+Messages.getString("BoardView1.minefield") +" " + owner; //$NON-NLS-1$ //$NON-NLS-2$ - break; - case (Minefield.TYPE_VIBRABOMB) : - if (mf.getPlayerId() == localPlayer.getId()) { - strings[stringsIndex] = mf.getName()+Messages.getString("BoardView1.minefield")+"(" + mf.getSetting() + ") " + owner; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } else { - strings[stringsIndex] = mf.getName()+Messages.getString("BoardView1.minefield") + " " + owner; //$NON-NLS-1$ //$NON-NLS-2$ - } - break; - case (Minefield.TYPE_THUNDER_ACTIVE) : - strings[stringsIndex] = mf.getName()+Messages.getString("BoardView1.minefield")+"(" + mf.getDamage() + ")" + owner; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - break; - case (Minefield.TYPE_THUNDER_INFERNO) : - strings[stringsIndex] = mf.getName()+Messages.getString("BoardView1.minefield")+"(" + mf.getDamage() + ")" + owner; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - break; - } - stringsIndex++; - } - } - } - // check if it's on any entities - for (Iterator i = entitySprites.iterator(); i.hasNext();) { - final EntitySprite eSprite = (EntitySprite)i.next(); - if (eSprite.isInside(point)) { - final String[] entityStrings = eSprite.getTooltip(); - java.lang.System.arraycopy(entityStrings, 0, strings, stringsIndex, entityStrings.length); - stringsIndex += entityStrings.length; - } - } - - // check if it's on any attacks - for (Iterator i = attackSprites.iterator(); i.hasNext();) { - final AttackSprite aSprite = (AttackSprite)i.next(); - if (aSprite.isInside(point)) { - final String[] attackStrings = aSprite.getTooltip(); - java.lang.System.arraycopy(attackStrings, 0, strings, stringsIndex, attackStrings.length); - stringsIndex += 1 + aSprite.weaponDescs.size(); - } - } - - // check artillery attacks - for(Iterator i = artilleryAttacks.iterator(); i.hasNext();) { - final ArtilleryAttackAction aaa = (ArtilleryAttackAction)i.next(); - final WeaponResult wr = aaa.getWR(); - final Entity ae = game.getEntity(wr.waa.getEntityId()); - String s = null; - if(ae != null) { - if(wr.waa.getWeaponId() > -1) { - Mounted weap = ae.getEquipment(wr.waa.getWeaponId()); - s = weap.getName(); - if(wr.waa.getAmmoId() > -1) { - Mounted ammo = ae.getEquipment(wr.waa.getAmmoId()); - s += "(" + ammo.getName() + ")"; - } - } - } - if(s == null) { - s = Messages.getString("BoardView1.Artillery"); - } - strings[stringsIndex++] = Messages.getString("BoardView1.ArtilleryAttack", - new Object[] { s, new Integer(aaa.turnsTilHit), wr.toHit.getValueAsString() } ); - } - //check artillery fire adjustment - final Entity selectedEntity = clientgui.mechD.getCurrentEntity(); - if(selectedWeapon != null && selectedEntity != null) { - //process targetted hexes - int amod = 0; - //Check the predesignated hexes - if(selectedEntity.getOwner().getArtyAutoHitHexes().contains(mcoords)) { - amod = TargetRoll.AUTOMATIC_SUCCESS; - } - else { - amod = selectedEntity.aTracker.getModifier(selectedWeapon, mcoords); - } - - if(amod==TargetRoll.AUTOMATIC_SUCCESS) { - strings[stringsIndex++] = Messages.getString("BoardView1.ArtilleryAutohit"); - } else { - strings[stringsIndex++] = Messages.getString("BoardView1.ArtilleryAdjustment", new Object[] { new Integer(amod) } ); - } - } - return strings; - } - - /** - * Hides the tooltip thinger - */ - public void hideTooltip() { - tipWindow.setVisible(false); - } - - /** - * Returns true if the tooltip is showing - */ - private boolean isTipShowing() { - return tipWindow.isShowing(); - } - - /** - * Checks if the mouse has been idling for a while and if so, shows the - * tooltip window - */ - private void checkTooltip() { - if (isTipShowing()) { - if (!isTipPossible) { - hideTooltip(); - } - } else if (isTipPossible && System.currentTimeMillis() - lastIdle > GUIPreferences.getInstance().getTooltipDelay()) { - showTooltip(); - } - } - - public void redrawMovingEntity(Entity entity, Coords position, int facing) { - Integer entityId = new Integer( entity.getId() ); - EntitySprite sprite = (EntitySprite) entitySpriteIds.get( entityId ); - Vector newSprites; - Hashtable newSpriteIds; - - if (sprite != null) { - newSprites = new Vector(entitySprites); - newSpriteIds = new Hashtable(entitySpriteIds); - - newSprites.removeElement(sprite); - - entitySprites = newSprites; - entitySpriteIds = newSpriteIds; - } - - MovingEntitySprite mSprite = - (MovingEntitySprite) movingEntitySpriteIds.get( entityId ); - newSprites = new Vector(movingEntitySprites); - newSpriteIds = new Hashtable(movingEntitySpriteIds); - - - if (mSprite != null) { - newSprites.removeElement(mSprite); - } - - if (entity.getPosition() != null) { - mSprite = new MovingEntitySprite(entity, position, facing); - newSprites.addElement(mSprite); - newSpriteIds.put( entityId, mSprite ); - } - - movingEntitySprites = newSprites; - movingEntitySpriteIds = newSpriteIds; - } - - public boolean isMovingUnits() { - return movingUnits.size() > 0; - } - - /** - * Clears the sprite for an entity and prepares it to be re-drawn. - * Replaces the old sprite with the new! - * - * Try to prevent annoying ConcurrentModificationExceptions - */ - public void redrawEntity(Entity entity) { - Integer entityId = new Integer( entity.getId() ); - EntitySprite sprite = (EntitySprite)entitySpriteIds.get( entityId ); - Vector newSprites = new Vector(entitySprites); - Hashtable newSpriteIds = new Hashtable(entitySpriteIds); - - - if (sprite != null) { - newSprites.removeElement(sprite); - } - Coords position = entity.getPosition(); - if (position != null) { - /*drawHex(position); - IHex foo = game.getBoard().getHex(position); - foo.markChanged(); */// TODO: Is this really necessary? - - sprite = new EntitySprite(entity); - newSprites.addElement(sprite); - newSpriteIds.put( entityId, sprite ); - } - - entitySprites = newSprites; - entitySpriteIds = newSpriteIds; - - for (java.util.Enumeration i = C3Sprites.elements(); i.hasMoreElements();) { - final C3Sprite c3sprite = (C3Sprite)i.nextElement(); - if (c3sprite.entityId == entity.getId()) - C3Sprites.removeElement(c3sprite); - else if(c3sprite.masterId == entity.getId()) { - // Only redraw client-to-master; otherwise - // we leave stray lines when we move. - if(entity.hasC3()) { - C3Sprites.addElement(new C3Sprite(game.getEntity(c3sprite.entityId), game.getEntity(c3sprite.masterId))); - } - C3Sprites.removeElement(c3sprite); - - } - } - - if(entity.hasC3() || entity.hasC3i()) addC3Link(entity); - - repaint(100); - } - - /** - * Clears all old entity sprites out of memory and sets up new ones. - */ - private void redrawAllEntities() { - Vector newSprites = new Vector(game.getNoOfEntities()); - Hashtable newSpriteIds = new Hashtable(game.getNoOfEntities()); - Vector newWrecks = new Vector(); - - Enumeration e = game.getWreckedEntities(); - while (e.hasMoreElements()) { - Entity entity = (Entity) e.nextElement(); - if (!(entity instanceof Infantry) && (entity.getPosition() != null)) { - WreckSprite ws = new WreckSprite(entity); - newWrecks.addElement(ws); - } - } - - clearC3Networks(); - for (java.util.Enumeration i = game.getEntities(); i.hasMoreElements();) { - final Entity entity = (Entity)i.nextElement(); - if (entity.getPosition() == null) continue; - - EntitySprite sprite = new EntitySprite(entity); - newSprites.add(sprite); - newSpriteIds.put(new Integer(entity.getId()), sprite); - - if(entity.hasC3() || entity.hasC3i()) addC3Link(entity); - } - - entitySprites = newSprites; - entitySpriteIds = newSpriteIds; - wreckSprites = newWrecks; - - repaint(100); - } - - /** - * Moves the cursor to the new position, or hides it, if newPos is null - */ - private void moveCursor(CursorSprite cursor, Coords newPos) { - final Rectangle oldBounds = new Rectangle(cursor.getBounds()); - if (newPos != null) { - //cursor.setLocation(getHexLocation(newPos)); - cursor.setHexLocation(newPos); - } else { - cursor.setOffScreen(); - } - // repaint affected area - repaintBounds(oldBounds); - repaintBounds(cursor.getBounds()); - } - - - public void centerOnHex(Coords c) { - if ( null == c ) return; - scroll.setLocation(getHexLocation(c)); - scroll.translate((int)(42*scale) - (view.width / 2), (int)(36*scale) - (view.height / 2)); - - isScrolling = false; - checkScrollBounds(); - repaint(); - } - - /** - * Clears the old movement data and draws the new. Since it's less - * expensive to check for and reuse old step sprites than to make a whole - * new one, we do that. - */ - public void drawMovementData(Entity entity, MovePath md) { - Vector temp = pathSprites; - - clearMovementData(); - - for (java.util.Enumeration i = md.getSteps(); i.hasMoreElements();) { - final MoveStep step = (MoveStep)i.nextElement(); - // check old movement path for reusable step sprites - boolean found = false; - for (Iterator j = temp.iterator(); j.hasNext();) { - final StepSprite sprite = (StepSprite)j.next(); - if (sprite.getStep().canReuseSprite(step)) { - pathSprites.addElement(sprite); - found = true; - } - } - if (!found) { - pathSprites.addElement(new StepSprite(step)); - } - } - } - - /** - * Clears current movement data from the screen - */ - public void clearMovementData() { - Vector temp = pathSprites; - pathSprites = new Vector(); - for (Iterator i = temp.iterator(); i.hasNext();) { - final Sprite sprite = (Sprite)i.next(); - repaintBounds(sprite.getBounds()); - } - } - - public void setLocalPlayer(Player p) { - localPlayer = p; - } - - public Player getLocalPlayer() { - return localPlayer; - } - - /** - * Specifies that this should mark the deployment hexes for a player. If - * the player is set to null, no hexes will be marked. - */ - public void markDeploymentHexesFor(Player p) - { - m_plDeployer = p; - } - - /** - * Adds a c3 line to the sprite list. - */ - public void addC3Link(Entity e) { - if (e.getPosition() == null) return; - - if(e.hasC3i()) { - for (java.util.Enumeration i = game.getEntities(); i.hasMoreElements();) { - final Entity fe = (Entity)i.nextElement(); - if (fe.getPosition() == null) return; - if ( e.onSameC3NetworkAs(fe)) { - C3Sprites.addElement(new C3Sprite(e, fe)); - } - } - } - else if(e.getC3Master() != null) { - Entity eMaster = e.getC3Master(); - if (eMaster.getPosition() == null) return; - - // ECM cuts off the network - if (!Compute.isAffectedByECM(e, e.getPosition(), eMaster.getPosition())) { - C3Sprites.addElement(new C3Sprite(e, e.getC3Master())); - } - } - } - - /** - * Adds an attack to the sprite list. - */ - public void addAttack(AttackAction aa) { - // do not make a sprite unless we're aware of both entities - // this is not a great solution but better than a crash - Entity ae = game.getEntity(aa.getEntityId()); - Targetable t = game.getTarget(aa.getTargetType(), aa.getTargetId()); - if (ae == null || t == null || t.getTargetType() == Targetable.TYPE_INARC_POD) { - return; - } - - for (final Iterator i = attackSprites.iterator(); i.hasNext();) { - final AttackSprite sprite = (AttackSprite)i.next(); - - // can we just add this attack to an existing one? - if (sprite.getEntityId() == aa.getEntityId() - && sprite.getTargetId() == aa.getTargetId()) { - // use existing attack, but add this weapon - if (aa instanceof WeaponAttackAction) { - WeaponAttackAction waa = (WeaponAttackAction)aa; - if ( aa.getTargetType() != Targetable.TYPE_HEX_ARTILLERY - && aa.getTargetType() != Targetable.TYPE_HEX_FASCAM - && aa.getTargetType() != Targetable.TYPE_HEX_INFERNO_IV - && aa.getTargetType() != Targetable.TYPE_HEX_VIBRABOMB_IV) { - sprite.addWeapon(waa); - } else if ( waa.getEntity(game).getOwner().getId() == localPlayer.getId()) { - sprite.addWeapon(waa); - } - } - if (aa instanceof KickAttackAction) { - sprite.addWeapon((KickAttackAction)aa); - } - if (aa instanceof PunchAttackAction) { - sprite.addWeapon((PunchAttackAction)aa); - } - if (aa instanceof PushAttackAction) { - sprite.addWeapon((PushAttackAction)aa); - } - if (aa instanceof ClubAttackAction) { - sprite.addWeapon((ClubAttackAction)aa); - } - if (aa instanceof ChargeAttackAction) { - sprite.addWeapon((ChargeAttackAction)aa); - } - if (aa instanceof DfaAttackAction) { - sprite.addWeapon((DfaAttackAction)aa); - } - if (aa instanceof ProtomechPhysicalAttackAction) { - sprite.addWeapon((ProtomechPhysicalAttackAction)aa); - } - return; - } - } - // no re-use possible, add a new one - // don't add a sprite for an artillery attack made by the other player - if (aa instanceof WeaponAttackAction) { - WeaponAttackAction waa = (WeaponAttackAction)aa; - if ( aa.getTargetType() != Targetable.TYPE_HEX_ARTILLERY - && aa.getTargetType() != Targetable.TYPE_HEX_FASCAM - && aa.getTargetType() != Targetable.TYPE_HEX_INFERNO_IV - && aa.getTargetType() != Targetable.TYPE_HEX_VIBRABOMB_IV) { - attackSprites.addElement(new AttackSprite(aa)); - } else if ( waa.getEntity(game).getOwner().getId() == localPlayer.getId()) { - attackSprites.addElement(new AttackSprite(aa)); - } - } else { - attackSprites.addElement(new AttackSprite(aa)); - } - } - - /** Removes all attack sprites from a certain entity */ - public void removeAttacksFor(int entityId) { - // or rather, only keep sprites NOT for that entity - Vector toKeep = new Vector(attackSprites.size()); - for (Iterator i = attackSprites.iterator(); i.hasNext();) { - AttackSprite sprite = (AttackSprite)i.next(); - if (sprite.getEntityId() != entityId) { - toKeep.addElement(sprite); - } - } - this.attackSprites = toKeep; - } - - /** - * Clears out all attacks and re-adds the ones in the current game. - */ - public void refreshAttacks() { - clearAllAttacks(); - for (Enumeration i = game.getActions(); i.hasMoreElements();) { - EntityAction ea = (EntityAction)i.nextElement(); - if (ea instanceof AttackAction) { - addAttack((AttackAction)ea); - } - } - for (Enumeration i = game.getCharges(); i.hasMoreElements();) { - EntityAction ea = (EntityAction)i.nextElement(); - if (ea instanceof AttackAction) { - addAttack((AttackAction)ea); - } - } - } - - public void clearC3Networks() { - C3Sprites.removeAllElements(); - } - - /** - * Clears out all attacks that were being drawn - */ - public void clearAllAttacks() { - attackSprites.removeAllElements(); - } - - public Image baseFor(IHex hex) { - return tileManager.baseFor(hex); - } - - public com.sun.java.util.collections.List supersFor(IHex hex) { - return tileManager.supersFor(hex); - } - - protected void firstLOSHex(Coords c) { - if (useLOSTool) { - moveCursor(secondLOSSprite, null); - moveCursor(firstLOSSprite, c); - } - } - - protected void secondLOSHex(Coords c2, Coords c1) { - if (useLOSTool) { - moveCursor(firstLOSSprite, c1); - moveCursor(secondLOSSprite, c2); - - boolean mechInFirst = GUIPreferences.getInstance().getMechInFirst(); - boolean mechInSecond = GUIPreferences.getInstance().getMechInSecond(); - - LosEffects.AttackInfo ai = new LosEffects.AttackInfo(); - ai.attackPos = c1; - ai.targetPos = c2; - ai.attackHeight = mechInFirst?1:0; - ai.targetHeight = mechInSecond?1:0; - ai.attackAbsHeight = game.getBoard().getHex(c1).floor() + ai.attackHeight; - ai.targetAbsHeight = game.getBoard().getHex(c2).floor() + ai.targetHeight; - - LosEffects le = LosEffects.calculateLos(game, ai); - StringBuffer message = new StringBuffer(); - message.append(Messages.getString("BoardView1.Attacker", new Object[]{ //$NON-NLS-1$ - mechInFirst ? Messages.getString("BoardView1.Mech") : Messages.getString("BoardView1.NonMech"), //$NON-NLS-1$ //$NON-NLS-2$ - c1.getBoardNum()})); - message.append(Messages.getString("BoardView1.Target", new Object[]{ //$NON-NLS-1$ - mechInSecond ? Messages.getString("BoardView1.Mech") : Messages.getString("BoardView1.NonMech"), //$NON-NLS-1$ //$NON-NLS-2$ - c1.getBoardNum()})); - if (!le.canSee()) { - message.append(Messages.getString("BoardView1.LOSBlocked", new Object[]{ //$NON-NLS-1$ - new Integer(c1.distance(c2))})); - } else { - message.append(Messages.getString("BoardView1.LOSNotBlocked", new Object[]{ //$NON-NLS-1$ - new Integer(c1.distance(c2))})); - if (le.getHeavyWoods() > 0) { - message.append(Messages.getString("BoardView1.HeavyWoods", new Object[]{ //$NON-NLS-1$ - new Integer(le.getHeavyWoods())})); - } - if (le.getLightWoods() > 0) { - message.append(Messages.getString("BoardView1.LightWoods", new Object[]{ //$NON-NLS-1$ - new Integer(le.getLightWoods())})); - } - if (le.getLightSmoke() > 0) { - message.append(Messages.getString("BoardView1.LightSmoke", new Object[]{ //$NON-NLS-1$ - new Integer(le.getLightSmoke())})); - } - if (le.getHeavySmoke() > 0) { - if (game.getOptions().booleanOption("maxtech_fire")) { //$NON-NLS-1$ - message.append(Messages.getString("BoardView1.HeavySmoke", new Object[]{ //$NON-NLS-1$ - new Integer(le.getHeavySmoke())})); - } - else { - message.append(Messages.getString("BoardView1.Smoke", new Object[]{ //$NON-NLS-1$ - new Integer(le.getHeavySmoke())})); - } - } - if (le.isTargetCover()) { - message.append(Messages.getString("BoardView1.TargetPartialCover")); //$NON-NLS-1$ - } - if (le.isAttackerCover()) { - message.append(Messages.getString("BoardView1.AttackerPartialCover")); //$NON-NLS-1$ - } - } - AlertDialog alert = new AlertDialog(frame, - Messages.getString("BoardView1.LOSTitle"), //$NON-NLS-1$ - message.toString(), false); - alert.show(); - } - } - - /** - * If the mouse is at the edges of the screen, this - * scrolls the board image on the canvas. - * NOTE: CTL scroll is handled in mouseMoved() - */ - public boolean doScroll() { - final Point oldScroll = new Point(scroll); - boolean s = false; - - if ( isScrolling && GUIPreferences.getInstance().getRightDragScroll()) { - if (! (oldMousePosition == null || mousePos.equals(oldMousePosition)) ) { - scroll.x -= GUIPreferences.getInstance().getScrollSensitivity() * (mousePos.x - oldMousePosition.x); - scroll.y -= GUIPreferences.getInstance().getScrollSensitivity() * (mousePos.y - oldMousePosition.y); - checkScrollBounds(); - oldMousePosition.setLocation(mousePos); - s = !oldScroll.equals(scroll); - scrolled = scrolled || s; - } - } - - if (isScrolling && (GUIPreferences.getInstance().getClickEdgeScroll() ||GUIPreferences.getInstance().getAutoEdgeScroll()) ) { - final int sf = GUIPreferences.getInstance().getScrollSensitivity(); // scroll factor - // adjust x scroll - // scroll when the mouse is at the edges - if (mousePos.x < 100) { - scroll.x -= (100 - mousePos.x) / sf; - } else if (mousePos.x > (backSize.width - 100)) { - scroll.x -= ((backSize.width - 100) - mousePos.x) / sf; - } - // scroll when the mouse is at the edges - if (mousePos.y < 100) { - scroll.y -= (100 - mousePos.y) / sf; - } else if (mousePos.y > (backSize.height - 100)) { - scroll.y -= ((backSize.height - 100) - mousePos.y) / sf; - } - checkScrollBounds(); - if (!oldScroll.equals(scroll)) { - // repaint(); - s = true; - scrolled = s; - } - } - - return s; - } - - /** - * Makes sure that the scroll dimensions stay in bounds - */ - public void checkScrollBounds() { - if (scroll.x < 0) { - scroll.x = 0; - } else if (scroll.x > (boardSize.width - view.width)) { - scroll.x = (boardSize.width - view.width); - } - - if (scroll.y < 0) { - scroll.y = 0; - } else if (scroll.y > (boardSize.height - view.height)) { - scroll.y = (boardSize.height - view.height); - } - - // Update our scroll bars. - if (null != this.vScrollbar) { - this.vScrollbar.setValue (scroll.y); - } - if (null != this.hScrollbar) { - this.hScrollbar.setValue (scroll.x); - } - } - - protected void stopScrolling() { - isScrolling = false; - } - - /** - * Initializes the various overlay polygons with their - * vertices. - */ - public void initPolys() { - // hex polygon - hexPoly = new Polygon(); - hexPoly.addPoint(21, 0); - hexPoly.addPoint(62, 0); - hexPoly.addPoint(83, 35); - hexPoly.addPoint(83, 36); - hexPoly.addPoint(62, 71); - hexPoly.addPoint(21, 71); - hexPoly.addPoint(0, 36); - hexPoly.addPoint(0, 35); - - // facing polygons - facingPolys = new Polygon[6]; - facingPolys[0] = new Polygon(); - facingPolys[0].addPoint(41, 3); - facingPolys[0].addPoint(38, 6); - facingPolys[0].addPoint(45, 6); - facingPolys[0].addPoint(42, 3); - facingPolys[1] = new Polygon(); - facingPolys[1].addPoint(69, 17); - facingPolys[1].addPoint(64, 17); - facingPolys[1].addPoint(68, 23); - facingPolys[1].addPoint(70, 19); - facingPolys[2] = new Polygon(); - facingPolys[2].addPoint(69, 53); - facingPolys[2].addPoint(68, 49); - facingPolys[2].addPoint(64, 55); - facingPolys[2].addPoint(68, 54); - facingPolys[3] = new Polygon(); - facingPolys[3].addPoint(41, 68); - facingPolys[3].addPoint(38, 65); - facingPolys[3].addPoint(45, 65); - facingPolys[3].addPoint(42, 68); - facingPolys[4] = new Polygon(); - facingPolys[4].addPoint(15, 53); - facingPolys[4].addPoint(18, 54); - facingPolys[4].addPoint(15, 48); - facingPolys[4].addPoint(14, 52); - facingPolys[5] = new Polygon(); - facingPolys[5].addPoint(13, 19); - facingPolys[5].addPoint(15, 23); - facingPolys[5].addPoint(19, 17); - facingPolys[5].addPoint(17, 17); - - // movement polygons - movementPolys = new Polygon[8]; - movementPolys[0] = new Polygon(); - movementPolys[0].addPoint(41, 65); - movementPolys[0].addPoint(38, 68); - movementPolys[0].addPoint(45, 68); - movementPolys[0].addPoint(42, 65); - movementPolys[1] = new Polygon(); - movementPolys[1].addPoint(17, 48); - movementPolys[1].addPoint(12, 48); - movementPolys[1].addPoint(16, 54); - movementPolys[1].addPoint(17, 49); - movementPolys[2] = new Polygon(); - movementPolys[2].addPoint(18, 19); - movementPolys[2].addPoint(17, 15); - movementPolys[2].addPoint(13, 21); - movementPolys[2].addPoint(17, 20); - movementPolys[3] = new Polygon(); - movementPolys[3].addPoint(41, 6); - movementPolys[3].addPoint(38, 3); - movementPolys[3].addPoint(45, 3); - movementPolys[3].addPoint(42, 6); - movementPolys[4] = new Polygon(); - movementPolys[4].addPoint(67, 15); - movementPolys[4].addPoint(66, 19); - movementPolys[4].addPoint(67, 20); - movementPolys[4].addPoint(71, 20); - movementPolys[5] = new Polygon(); - movementPolys[5].addPoint(69, 55); - movementPolys[5].addPoint(66, 50); - movementPolys[5].addPoint(67, 49); - movementPolys[5].addPoint(72, 48); - - movementPolys[6] = new Polygon(); // up arrow with tail - movementPolys[6].addPoint(35, 44); - movementPolys[6].addPoint(30, 49); - movementPolys[6].addPoint(33, 49); - movementPolys[6].addPoint(33, 53); - movementPolys[6].addPoint(38, 53); - movementPolys[6].addPoint(38, 49); - movementPolys[6].addPoint(41, 49); - movementPolys[6].addPoint(36, 44); - movementPolys[7] = new Polygon(); // down arrow with tail - movementPolys[7].addPoint(34, 53); - movementPolys[7].addPoint(29, 48); - movementPolys[7].addPoint(32, 48); - movementPolys[7].addPoint(32, 44); - movementPolys[7].addPoint(37, 44); - movementPolys[7].addPoint(37, 48); - movementPolys[7].addPoint(40, 48); - movementPolys[7].addPoint(35, 53); - } - - private synchronized boolean doMoveUnits(long idleTime) { - boolean movingSomething = false; - - if (movingUnits.size() > 0) { - - moveWait += idleTime; - - if (moveWait > GUIPreferences.getInstance().getInt("AdvancedMoveStepDelay")) { - - java.util.Vector spent = new java.util.Vector(); - - for (int i = 0; i < movingUnits.size(); i++) { - Object[] move = (Object[]) movingUnits.elementAt(i); - Entity e = (Entity) move[0]; - java.util.Vector movePath = (java.util.Vector) move[1]; - movingSomething = true; - Entity ge = game.getEntity(e.getId()); - if (movePath.size() > 0) { - UnitLocation loc = - ( (UnitLocation) movePath.elementAt(0) ); - if (ge != null) { - redrawMovingEntity( e, - loc.getCoords(), - loc.getFacing() ); - } - movePath.removeElementAt(0); - } else { - if (ge != null) { - redrawEntity(ge); - } - spent.addElement(move); - } - - } - - for (int i = 0; i < spent.size(); i++) { - Object[] move = (Object[]) spent.elementAt(i); - movingUnits.removeElement(move); - } - moveWait = 0; - - if (movingUnits.size() == 0) { - movingEntitySpriteIds.clear(); - movingEntitySprites.removeAllElements(); - ghostEntitySprites.removeAllElements(); - processBoardViewEvent(new BoardViewEvent(this, BoardViewEvent.FINISHED_MOVING_UNITS)); - } - } - } - return movingSomething; - } - - // - // KeyListener - // - public void keyPressed(KeyEvent ke) { - switch(ke.getKeyCode()) { - case KeyEvent.VK_NUMPAD7 : - scroll.y -= 36; - scroll.x -= 36; - break; - case KeyEvent.VK_NUMPAD8 : - scroll.y -= 36; - break; - case KeyEvent.VK_NUMPAD9 : - scroll.y -= 36; - scroll.x += 36; - break; - case KeyEvent.VK_NUMPAD1 : - scroll.y += 36; - scroll.x -= 36; - break; - case KeyEvent.VK_NUMPAD2 : - scroll.y += 36; - break; - case KeyEvent.VK_NUMPAD3 : - scroll.y += 36; - scroll.x += 36; - break; - case KeyEvent.VK_NUMPAD4 : - scroll.x -= 36; - break; - case KeyEvent.VK_NUMPAD6 : - scroll.x += 36; - break; - case KeyEvent.VK_NUMPAD5 : - // center on the selected entity - java.util.Vector v = game.getPlayerEntities(localPlayer); - Entity se = clientgui == null?null:game.getEntity(clientgui.getSelectedEntityNum()); - for (int i = 0; i < v.size(); i++) { - Entity e = (Entity) v.elementAt(i); - if (e==se) { - centerOnHex(e.getPosition()); - } - } - break; - case KeyEvent.VK_CONTROL : - ctlKeyHeld = true; - initCtlScroll = true; - break; - } - - if (isTipShowing()) { - hideTooltip(); - } - lastIdle = System.currentTimeMillis(); - checkScrollBounds(); - repaint(); - } - - public void keyReleased(KeyEvent ke) { - if (ke.getKeyCode() == KeyEvent.VK_CONTROL) { - ctlKeyHeld = false; - } - } - public void keyTyped(KeyEvent ke) { - } - - // - // MouseListener - // - public void mousePressed(MouseEvent me) { - scrolled = false; // not scrolled yet - - Point point = me.getPoint(); - if ( null == point ) { - return; - } - oldMousePosition = point; - - isTipPossible = false; - for (int i = 0; i < displayables.size(); i++) { - Displayable disp = (Displayable) displayables.elementAt(i); - if (disp.isHit(point, backSize)) { - return; - } - } - - // Disable scrolling when ctrl or alt is held down, since this - // means the user wants to use the LOS/ruler tools. - int mask = InputEvent.CTRL_MASK | InputEvent.ALT_MASK; - if ( !GUIPreferences.getInstance().getRightDragScroll() && - !GUIPreferences.getInstance().getAlwaysRightClickScroll() && - game.getPhase() == IGame.PHASE_FIRING ) { - // In the firing phase, also disable scrolling if - // the right or middle buttons are clicked, since - // this means the user wants to activate the - // popup menu or ruler tool. - mask |= InputEvent.BUTTON2_MASK | InputEvent.BUTTON3_MASK; - } - - // disable auto--edge-scrolling if no option set - if ( !GUIPreferences.getInstance().getAutoEdgeScroll() ) { - mask |= InputEvent.BUTTON1_MASK; - } - // disable edge-scrolling if no option set - if ( !GUIPreferences.getInstance().getClickEdgeScroll() ) { - mask |= InputEvent.BUTTON3_MASK; - } - - if ( GUIPreferences.getInstance().getRightDragScroll() ) { - mask |= InputEvent.BUTTON2_MASK; - } - - if ( (me.getModifiers() & mask ) == 0 ) { - isScrolling = true; //activate scrolling - } else { - isScrolling = false; //activate scrolling - } - - if (isTipShowing()) { - hideTooltip(); - } - - mouseAction(getCoordsAt(point), BOARD_HEX_DRAG, me.getModifiers()); - } - - public void mouseReleased(MouseEvent me) { - isTipPossible = true; - oldMousePosition = mousePos; - - for (int i = 0; i < displayables.size(); i++) { - Displayable disp = (Displayable) displayables.elementAt(i); - if (disp.isReleased()) { - return; - } - } - isScrolling = false; - - // no click action triggered if click was for scrolling the map. Real clicks are without scrolling. - if (scrolled) - return; - if (me.getClickCount() == 1) { - mouseAction(getCoordsAt(me.getPoint()), BOARD_HEX_CLICK, me.getModifiers()); - } else { - mouseAction(getCoordsAt(me.getPoint()), BOARD_HEX_DOUBLECLICK, me.getModifiers()); - } - } - - public void mouseEntered(MouseEvent me) { - } - - public void mouseExited(MouseEvent me) { - isTipPossible = false; - } - public void mouseClicked(MouseEvent me) { - } - - // - // MouseMotionListener - // - public void mouseDragged(MouseEvent me) { - isTipPossible = false; - - Point point = me.getPoint(); - if ( null == point ) { - return; - } - - for (int i = 0; i < displayables.size(); i++) { - Displayable disp = (Displayable) displayables.elementAt(i); - if (disp.isDragged(point, backSize)) { - repaint(); - return; - } - } - mousePos = point; - - // Disable scrolling when ctrl or alt is held down, since this - // means the user wants to use the LOS/ruler tools. - int mask = InputEvent.CTRL_MASK | InputEvent.ALT_MASK; - - if ( !GUIPreferences.getInstance().getRightDragScroll() && - !GUIPreferences.getInstance().getAlwaysRightClickScroll() && - game.getPhase() == IGame.PHASE_FIRING) { - // In the firing phase, also disable scrolling if - // the right or middle buttons are clicked, since - // this means the user wants to activate the - // popup menu or ruler tool. - mask |= InputEvent.BUTTON2_MASK | InputEvent.BUTTON3_MASK; - } - - if ( GUIPreferences.getInstance().getRightDragScroll() ) { - mask |= InputEvent.BUTTON1_MASK | InputEvent.BUTTON2_MASK; - } - - // disable auto--edge-scrolling if no option set - if ( !GUIPreferences.getInstance().getAutoEdgeScroll() ) { - mask |= InputEvent.BUTTON1_MASK; - } - - // disable edge-scrolling if no option set - if ( !GUIPreferences.getInstance().getClickEdgeScroll() && !GUIPreferences.getInstance().getRightDragScroll() ) { - mask |= InputEvent.BUTTON3_MASK; - } - - if ( (me.getModifiers() & mask ) == 0 ) { - isScrolling = true; //activate scrolling - } else { - isScrolling = false; //activate scrolling - } - - mouseAction(getCoordsAt(point), BOARD_HEX_DRAG, me.getModifiers()); - } - - public void mouseMoved(MouseEvent me) { - Point point = me.getPoint(); - if ( null == point ) { - return; - } - - for (int i = 0; i < displayables.size(); i++) { - Displayable disp = (Displayable) displayables.elementAt(i); - if (disp.isBeingDragged()) { - isTipPossible = false; - return; - } - if (backSize != null) { - disp.isMouseOver(point, backSize); - } - } - mousePos = point; - if (isTipShowing()) { - hideTooltip(); - } - if (ctlKeyHeld && GUIPreferences.getInstance().getCtlScroll()) { - if (initCtlScroll) { - previousMouseX = me.getX(); - previousMouseY = me.getY(); - initCtlScroll = false; - } - scroll.x += GUIPreferences.getInstance().getScrollSensitivity() * (me.getX() - previousMouseX); - scroll.y += GUIPreferences.getInstance().getScrollSensitivity() * (me.getY() - previousMouseY); - previousMouseX = me.getX(); - previousMouseY = me.getY(); - checkScrollBounds(); - repaint(); - } - lastIdle = System.currentTimeMillis(); - isTipPossible = true; - } - - /** - * Increases zoomIndex and refreshes the map. - * - */ - public void zoomIn(){ - int tmpZoomIndex = zoomIndex + 1; - if ( isJ2RE == true ){ - zoomIndex++; - zoom(); - } - } - - /** - * Decreases zoomIndex and refreshes the map. - * - */ - public void zoomOut(){ - if ( isJ2RE == true ){ - zoomIndex--; - zoom(); - } - } - - /** - * zoomIndex is a reference to a static array of scale factors. - * The index ranges from 0 to 9 and by default is set to 7 which corresponds - * to a scale of 1.0 (draws megamek images at normal size). To zoom out the - * index needs to be set to a lower value. To zoom in make it larger. - * If only zooming a step at a time use the zoomIn and zoomOut methods instead. - * - * @param zoomIndex - */ - public void setZoomIndex( int zoomIndex ){ - if ( isJ2RE == true ){ - this.zoomIndex = zoomIndex; - zoom(); - } - } - - public int getZoomIndex(){ - return zoomIndex; - } - - private void checkZoomIndex(){ - if ( zoomIndex > ZOOM_FACTORS.length-1 ) { - zoomIndex = ZOOM_FACTORS.length-1; - } - if ( zoomIndex < 0 ) zoomIndex = 0; - } - - // - // Changes hex dimensions and refreshes the map with the new scale - // - private void zoom(){ - checkZoomIndex(); - scale = ZOOM_FACTORS[zoomIndex]; - GUIPreferences.getInstance().setMapZoomIndex(zoomIndex); - - hex_size = new Dimension((int)(HEX_W*scale), (int)(HEX_H*scale)); - - final Dimension size = getSize(); - //Coords c = getCoordsAt(new Point((int)(size.width/2), (int)(size.height/2))); - - boardGraph=null; - backGraph=null; - hasZoomed=true; - - updateBoardSize(); - - view.setLocation(scroll); - view.setSize(getOptimalView(size)); - offset.setLocation(getOptimalOffset(size)); - - updateFontSizes(); - updateBoardImage(); - - update(this.getGraphics()); - } - - private void updateFontSizes(){ - if ( zoomIndex <= 4 ) { - font_elev = FONT_7; - font_hexnum = FONT_7; - font_minefield = FONT_7; - } - if ( zoomIndex <= 5 & zoomIndex > 4 ){ - font_elev = FONT_8; - font_hexnum = FONT_8; - font_minefield = FONT_8; - } - if ( zoomIndex > 5 ){ - font_elev = FONT_9; - font_hexnum = FONT_9; - font_minefield = FONT_9; - } - } - - /** - * Displays a bit of text in a box. - * - * TODO: make multi-line - */ - private class TooltipCanvas extends Canvas - { - private String[] tipStrings; - private Dimension size; - - public TooltipCanvas(String[] tipStrings) { - this.tipStrings = tipStrings; - - // setup - setFont(new Font("SansSerif", Font.PLAIN, 12)); //$NON-NLS-1$ - setBackground(SystemColor.info); - setForeground(SystemColor.infoText); - - // determine size - final FontMetrics fm = getFontMetrics(getFont()); - int width = 0; - for (int i = 0; i < tipStrings.length; i++) { - if (fm.stringWidth(tipStrings[i]) > width) { - width = fm.stringWidth(tipStrings[i]); - } - } - size = new Dimension(width + 5, fm.getAscent() * tipStrings.length + 4); - setSize(size); - } - - public void paint(Graphics g) { - final FontMetrics fm = getFontMetrics(getFont()); - g.setColor(getBackground()); - g.fillRect(0, 0, size.width, size.height); - g.setColor(getForeground()); - g.drawRect(0, 0, size.width - 1, size.height - 1); - for (int i = 0; i < tipStrings.length; i++) { - g.drawString(tipStrings[i], 2, (i + 1) * fm.getAscent()); - } - } - } - - - /** - * Everything in the main map view is either the board or it's a sprite - * displayed on top of the board. Most sprites store a transparent image - * which they draw onto the screen when told to. Sprites keep a bounds - * rectangle, so it's easy to tell when they'return onscreen. - */ - private abstract class Sprite implements ImageObserver - { - protected Rectangle bounds; - protected Image image; - - /** - * Do any necessary preparation. This is called after creation, - * but before drawing, when a device context is ready to draw with. - */ - public abstract void prepare(); - - /** - * When we draw our buffered images, it's necessary to implement - * the ImageObserver interface. This provides the necesasry - * functionality. - */ - public boolean imageUpdate(Image image, int infoflags, int x, int y, - int width, int height) { - if (infoflags == ImageObserver.ALLBITS) { - prepare(); - repaint(); - return false; - } else { - return true; - } - } - - /** - * Returns our bounding rectangle. The coordinates here are stored - * with the top left corner of the _board_ being 0, 0, so these do - * not always correspond to screen coordinates. - */ - public Rectangle getBounds() { - return bounds; - } - - /** - * Are we ready to draw? By default, checks to see that our buffered - * image has been created. - */ - public boolean isReady() { - return image != null; - } - - /** - * Draws this sprite onto the specified graphics context. - */ - public void drawOnto(Graphics g, int x, int y, ImageObserver observer) { - drawOnto(g, x, y, observer, false); - } - - public void drawOnto(Graphics g, int x, int y, ImageObserver observer, boolean makeTranslucent) { - if (isReady()) { - Image tmpImage; - if (zoomIndex == BASE_ZOOM_INDEX ){ - tmpImage = image; - } else { - tmpImage = getScaledImage(image); - } - if (makeTranslucent && isJ2RE) { - Graphics2D g2 = (Graphics2D) g; - g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)); - g2.drawImage(tmpImage, x, y, observer); - g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f)); - } else { - g.drawImage(tmpImage, x, y, observer); - } - } else { - // grrr... we'll be ready next time! - prepare(); - } - } - - /** - * Returns true if the point is inside this sprite. Uses board - * coordinates, not screen coordinates. By default, just checks our - * bounding rectangle, though some sprites override this for a smaller - * sensitive area. - */ - public boolean isInside(Point point) { - return bounds.contains(point); - } - - /** - * Since most sprites being drawn correspond to something in the game, - * this returns a little info for a tooltip. - */ - private String[] getTooltip() { - return null; - } - } - - /** - * Sprite for a cursor. Just a hexagon outline in a specified color. - */ - private class CursorSprite extends Sprite - { - private Color color; - private Coords hexLoc; - - public CursorSprite(Color color) { - this.color = color; - this.bounds = new Rectangle(hexPoly.getBounds().width + 1, - hexPoly.getBounds().height + 1); - this.image = null; - - // start offscreen - setOffScreen(); - } - - public void prepare() { - // create image for buffer - Image tempImage = createImage(bounds.width, bounds.height); - Graphics graph = tempImage.getGraphics(); - - // fill with key color - graph.setColor(new Color(TRANSPARENT)); - graph.fillRect(0, 0, bounds.width, bounds.height); - // draw attack poly - graph.setColor(color); - graph.drawPolygon(hexPoly); - - // create final image - this.image = createImage(new FilteredImageSource(tempImage.getSource(), - new KeyAlphaFilter(TRANSPARENT))); - } - - public void setOffScreen(){ - bounds.setLocation(-100, -100); - hexLoc = new Coords(-2, -2); - } - - public void setHexLocation( Coords hexLoc ){ - this.hexLoc = hexLoc; - bounds.setLocation(getHexLocation(hexLoc)); - } - - public Rectangle getBounds(){ - this.bounds = new Rectangle(hexPoly.getBounds().width + 1, - hexPoly.getBounds().height + 1); - bounds.setLocation(getHexLocation( hexLoc )); - - return bounds; - } - } - - - private class GhostEntitySprite extends Sprite { - private Entity entity; - private Rectangle entityRect; - private Rectangle modelRect; - - public GhostEntitySprite(Entity entity) { - this.entity = entity; - - String shortName = entity.getShortName(); - Font font = new Font("SansSerif", Font.PLAIN, 10); //$NON-NLS-1$ - modelRect = new Rectangle(47, 55, - getFontMetrics(font).stringWidth(shortName) + 1, - getFontMetrics(font).getAscent()); - Rectangle tempBounds = new Rectangle(hex_size).union(modelRect); - tempBounds.setLocation(getHexLocation(entity.getPosition())); - - this.bounds = tempBounds; - this.entityRect = new Rectangle( - bounds.x + (int)(20*scale), - bounds.y + (int)(14*scale), - (int)(44*scale), - (int)(44*scale)); - this.image = null; - } - - /** - * Creates the sprite for this entity. It is an extra pain to - * create transparent images in AWT. - */ - public void prepare() { - // create image for buffer - Image tempImage; - Graphics graph; - try { - tempImage = createImage(bounds.width, bounds.height); - graph = tempImage.getGraphics(); - } catch (NullPointerException ex) { - // argh! but I want it! - return; - } - - // fill with key color - graph.setColor(new Color(TRANSPARENT)); - graph.fillRect(0, 0, bounds.width, bounds.height); - - // draw entity image - graph.drawImage(tileManager.imageFor(entity), 0, 0, this); - - // create final image - this.image = createImage(new FilteredImageSource(tempImage.getSource(), - new KeyAlphaFilter(TRANSPARENT))); - } - - public Rectangle getBounds(){ - Rectangle tempBounds = new Rectangle(hex_size).union(modelRect); - tempBounds.setLocation(getHexLocation(entity.getPosition())); - this.bounds = tempBounds; - - this.entityRect = new Rectangle(bounds.x + (int)(20*scale), - bounds.y + (int)(14*scale), - (int)(44*scale), - (int)(44*scale)); - - return bounds; - } - - public void drawOnto(Graphics g, int x, int y, ImageObserver observer) { - drawOnto(g, x, y, observer, true); - } - - } - - private class MovingEntitySprite extends Sprite { - private int facing; - private Entity entity; - private Rectangle entityRect; - private Rectangle modelRect; - - public MovingEntitySprite(Entity entity, Coords position, int facing) { - this.entity = entity; - this.facing = facing; - - String shortName = entity.getShortName(); - Font font = new Font("SansSerif", Font.PLAIN, 10); //$NON-NLS-1$ - modelRect = new Rectangle(47, 55, - getFontMetrics(font).stringWidth(shortName) + 1, - getFontMetrics(font).getAscent()); - Rectangle tempBounds = new Rectangle(hex_size).union(modelRect); - tempBounds.setLocation(getHexLocation(position)); - - this.bounds = tempBounds; - this.entityRect = new Rectangle(bounds.x + (int)(20*scale), - bounds.y + (int)(14*scale), - (int)(44*scale), - (int)(44*scale)); - this.image = null; - } - - /** - * Creates the sprite for this entity. It is an extra pain to - * create transparent images in AWT. - */ - public void prepare() { - // create image for buffer - Image tempImage; - Graphics graph; - try { - tempImage = createImage(bounds.width, bounds.height); - graph = tempImage.getGraphics(); - } catch (NullPointerException ex) { - // argh! but I want it! - return; - } - - // fill with key color - graph.setColor(new Color(TRANSPARENT)); - graph.fillRect(0, 0, bounds.width, bounds.height); - - // draw entity image - graph.drawImage(tileManager.imageFor(entity, facing), 0, 0, this); - - // create final image - this.image = createImage(new FilteredImageSource(tempImage.getSource(), - new KeyAlphaFilter(TRANSPARENT))); - } - } - - - /** - * Sprite for an wreck. Consists - * of an image, drawn from the Tile Manager and an identification label. - */ - private class WreckSprite extends Sprite - { - private Entity entity; - private Rectangle entityRect; - private Rectangle modelRect; - - public WreckSprite(Entity entity) { - this.entity = entity; - - String shortName = entity.getShortName(); - - Font font = new Font("SansSerif", Font.PLAIN, 10); //$NON-NLS-1$ - modelRect = new Rectangle(47, 55, - getFontMetrics(font).stringWidth(shortName) + 1, - getFontMetrics(font).getAscent()); - Rectangle tempBounds = new Rectangle(hex_size).union(modelRect); - tempBounds.setLocation(getHexLocation(entity.getPosition())); - - this.bounds = tempBounds; - this.entityRect = new Rectangle( - bounds.x + (int)(20*scale), - bounds.y + (int)(14*scale), - (int)(44*scale), - (int)(44*scale)); - this.image = null; - } - - public Rectangle getBounds(){ - Rectangle tempBounds = new Rectangle(hex_size).union(modelRect); - tempBounds.setLocation(getHexLocation(entity.getPosition())); - this.bounds = tempBounds; - - this.entityRect = new Rectangle( - bounds.x + (int)(20*scale), - bounds.y + (int)(14*scale), - (int)(44*scale), - (int)(44*scale)); - - return bounds; - } - - /** - * Creates the sprite for this entity. It is an extra pain to - * create transparent images in AWT. - */ - public void prepare() { - // figure out size - String shortName = entity.getShortName(); - Font font = new Font("SansSerif", Font.PLAIN, 10); //$NON-NLS-1$ - Rectangle tempRect = - new Rectangle(47, 55, - getFontMetrics(font).stringWidth(shortName) + 1, - getFontMetrics(font).getAscent()); - - // create image for buffer - Image tempImage; - Graphics graph; - try { - tempImage = createImage(bounds.width, bounds.height); - graph = tempImage.getGraphics(); - } catch (NullPointerException ex) { - // argh! but I want it! - return; - } - - // fill with key color - graph.setColor(new Color(TRANSPARENT)); - graph.fillRect(0, 0, bounds.width, bounds.height); - - // Draw wreck image,if we've got one. - Image wreck = tileManager.wreckMarkerFor(entity); - if ( null != wreck ) { - graph.drawImage( wreck, 0, 0, this ); - } - - // draw box with shortName - Color text = Color.lightGray; - Color bkgd = Color.darkGray; - Color bord = Color.black; - - graph.setFont(font); - graph.setColor(bord); - graph.fillRect(tempRect.x, tempRect.y, - tempRect.width, tempRect.height); - tempRect.translate(-1, -1); - graph.setColor(bkgd); - graph.fillRect(tempRect.x, tempRect.y, - tempRect.width, tempRect.height); - graph.setColor(text); - graph.drawString(shortName, tempRect.x + 1, - tempRect.y + tempRect.height - 1); - - // create final image - this.image = createImage - (new FilteredImageSource(tempImage.getSource(), - new KeyAlphaFilter(TRANSPARENT))); - } - - /** - * Overrides to provide for a smaller sensitive area. - */ - public boolean isInside(Point point) { - return false; - } - - } - /** - * Sprite for an entity. Changes whenever the entity changes. Consists - * of an image, drawn from the Tile Manager; facing and possibly secondary - * facing arrows; armor and internal bars; and an identification label. - */ - private class EntitySprite extends Sprite - { - private Entity entity; - private Rectangle entityRect; - private Rectangle modelRect; - - public EntitySprite(Entity entity) { - this.entity = entity; - - String shortName = entity.getShortName(); - - if (entity.getMovementMode() == IEntityMovementMode.VTOL) { - shortName = shortName.concat(" (FL: ").concat(Integer.toString(entity.getElevation())).concat(")"); - } - Font font = new Font("SansSerif", Font.PLAIN, 10); //$NON-NLS-1$ - modelRect = new Rectangle(47, 55, - getFontMetrics(font).stringWidth(shortName) + 1, - getFontMetrics(font).getAscent()); - Rectangle tempBounds = new Rectangle(hex_size).union(modelRect); - tempBounds.setLocation(getHexLocation(entity.getPosition())); - - this.bounds = tempBounds; - this.entityRect = new Rectangle(bounds.x + (int)(20*scale), - bounds.y + (int)(14*scale), - (int)(44*scale), - (int)(44*scale)); - this.image = null; - } - - public Rectangle getBounds(){ - Rectangle tempBounds = new Rectangle(hex_size).union(modelRect); - tempBounds.setLocation(getHexLocation(entity.getPosition())); - this.bounds = tempBounds; - - this.entityRect = new Rectangle( - bounds.x + (int)(20*scale), - bounds.y + (int)(14*scale), - (int)(44*scale), - (int)(44*scale)); - - return bounds; - } - - public void drawOnto(Graphics g, int x, int y, ImageObserver observer) { - if (trackThisEntitiesVisibilityInfo(this.entity) - && !this.entity.isVisibleToEnemy()) { - // create final image with translucency - drawOnto(g, x, y, observer, true); - } else { - drawOnto(g, x, y, observer, false); - } - } - - /** - * Creates the sprite for this entity. It is an extra pain to - * create transparent images in AWT. - */ - public void prepare() { - // figure out size - String shortName = entity.getShortName(); - if (entity.getMovementMode() == IEntityMovementMode.VTOL) { - shortName = shortName.concat(" (FL: ").concat(Integer.toString(entity.getElevation())).concat(")"); - } - if (PreferenceManager.getClientPreferences().getShowUnitId()) { - shortName+=(Messages.getString("BoardView1.ID")+entity.getId()); //$NON-NLS-1$ - } - Font font = new Font("SansSerif", Font.PLAIN, 10); //$NON-NLS-1$ - Rectangle tempRect = - new Rectangle(47, 55, - getFontMetrics(font).stringWidth(shortName) + 1, - getFontMetrics(font).getAscent()); - - // create image for buffer - Image tempImage; - Graphics graph; - try { - tempImage = createImage(bounds.width, bounds.height); - graph = tempImage.getGraphics(); - } catch (NullPointerException ex) { - // argh! but I want it! - return; - } - - // fill with key color - graph.setColor(new Color(TRANSPARENT)); - graph.fillRect(0, 0, bounds.width, bounds.height); - - // draw entity image - graph.drawImage(tileManager.imageFor(entity), 0, 0, this); - - // draw box with shortName - Color text, bkgd, bord; - if (entity.isDone()) { - text = Color.lightGray; - bkgd = Color.darkGray; - bord = Color.black; - } else if (entity.isImmobile()) { - text = Color.darkGray; - bkgd = Color.black; - bord = Color.lightGray; - } else { - text = Color.black; - bkgd = Color.lightGray; - bord = Color.darkGray; - } - graph.setFont(font); - graph.setColor(bord); - graph.fillRect(tempRect.x, tempRect.y, - tempRect.width, tempRect.height); - tempRect.translate(-1, -1); - graph.setColor(bkgd); - graph.fillRect(tempRect.x, tempRect.y, - tempRect.width, tempRect.height); - graph.setColor(text); - graph.drawString(shortName, tempRect.x + 1, - tempRect.y + tempRect.height - 1); - - // draw facing - graph.setColor(Color.white); - if (entity.getFacing() != -1) { - graph.drawPolygon(facingPolys[entity.getFacing()]); - } - - // determine secondary facing for non-mechs & flipped arms - int secFacing = entity.getFacing(); - if (!(entity instanceof Mech || entity instanceof Protomech)) { - secFacing = entity.getSecondaryFacing(); - } else if (entity.getArmsFlipped()) { - secFacing = (entity.getFacing() + 3) % 6; - } - // draw red secondary facing arrow if necessary - if (secFacing != -1 && secFacing != entity.getFacing()) { - graph.setColor(Color.red); - graph.drawPolygon(facingPolys[secFacing]); - } - - // Determine if the entity is a tank with a locked turret. - boolean turretLocked = false; - if ( entity instanceof Tank && - !( (Tank) entity ).hasNoTurret() && - !entity.canChangeSecondaryFacing() ) { - turretLocked = true; - } - - // draw condition strings - if ( entity.isImmobile() && !entity.isProne() && !turretLocked ) { - // draw "IMMOBILE" - graph.setColor(Color.darkGray); - graph.drawString(Messages.getString("BoardView1.IMMOBILE"), 18, 39); //$NON-NLS-1$ - graph.setColor(Color.red); - graph.drawString(Messages.getString("BoardView1.IMMOBILE"), 17, 38); //$NON-NLS-1$ - } else if (!entity.isImmobile() && entity.isProne()) { - // draw "PRONE" - graph.setColor(Color.darkGray); - graph.drawString(Messages.getString("BoardView1.PRONE"), 26, 39); //$NON-NLS-1$ - graph.setColor(Color.yellow); - graph.drawString(Messages.getString("BoardView1.PRONE"), 25, 38); //$NON-NLS-1$ - } else if ( !entity.isImmobile() && turretLocked ) { - // draw "LOCKED" - graph.setColor(Color.darkGray); - graph.drawString(Messages.getString("BoardView1.LOCKED"), 22, 39); //$NON-NLS-1$ - graph.setColor(Color.yellow); - graph.drawString(Messages.getString("BoardView1.LOCKED"), 21, 38); //$NON-NLS-1$ - } else if (entity.isImmobile() && entity.isProne()) { - // draw "IMMOBILE" and "PRONE" - graph.setColor(Color.darkGray); - graph.drawString(Messages.getString("BoardView1.IMMOBILE"), 18, 35); //$NON-NLS-1$ - graph.drawString(Messages.getString("BoardView1.PRONE"), 26, 48); //$NON-NLS-1$ - graph.setColor(Color.red); - graph.drawString(Messages.getString("BoardView1.IMMOBILE"), 17, 34); //$NON-NLS-1$ - graph.setColor(Color.yellow); - graph.drawString(Messages.getString("BoardView1.PRONE"), 25, 47); //$NON-NLS-1$ - } else if ( entity.isImmobile() && turretLocked ) { - // draw "IMMOBILE" and "LOCKED" - graph.setColor(Color.darkGray); - graph.drawString(Messages.getString("BoardView1.IMMOBILE"), 18, 35); //$NON-NLS-1$ - graph.drawString(Messages.getString("BoardView1.LOCKED"), 22, 48); //$NON-NLS-1$ - graph.setColor(Color.red); - graph.drawString(Messages.getString("BoardView1.IMMOBILE"), 17, 34); //$NON-NLS-1$ - graph.setColor(Color.yellow); - graph.drawString(Messages.getString("BoardView1.LOCKED"), 21, 47); //$NON-NLS-1$ - } - - // If this unit is being swarmed or is swarming another, say so. - if ( Entity.NONE != entity.getSwarmAttackerId() ) { - // draw "SWARMED" - graph.setColor(Color.darkGray); - graph.drawString(Messages.getString("BoardView1.SWARMED"), 17, 22); //$NON-NLS-1$ - graph.setColor(Color.red); - graph.drawString(Messages.getString("BoardView1.SWARMED"), 16, 21); //$NON-NLS-1$ - } - - // If this unit is transporting another, say so. - if ((entity.getLoadedUnits()).size() > 0) { - // draw "T" - graph.setColor(Color.darkGray); - graph.drawString("T", 20, 71); //$NON-NLS-1$ - graph.setColor(Color.black); - graph.drawString("T", 19, 70); //$NON-NLS-1$ - } - - // If this unit is stuck, say so. - if ((entity.isStuck())) { - graph.setColor(Color.darkGray); - graph.drawString(Messages.getString("BoardView1.STUCK"), 26, 61); //$NON-NLS-1$ - graph.setColor(Color.orange); - graph.drawString(Messages.getString("BoardView1.STUCK"), 25, 60); //$NON-NLS-1$ - - } - - // If this unit is currently unknown to the enemy, say so. - if (trackThisEntitiesVisibilityInfo(entity)) { - if (!entity.isSeenByEnemy()) { - // draw "U" - graph.setColor(Color.darkGray); - graph.drawString("U", 30, 71); //$NON-NLS-1$ - graph.setColor(Color.black); - graph.drawString("U", 29, 70); //$NON-NLS-1$ - } else if (!entity.isVisibleToEnemy() && !isJ2RE) { - // If this unit is currently hidden from the enemy, say so. - // draw "H" - graph.setColor(Color.darkGray); - graph.drawString("H", 30, 71); //$NON-NLS-1$ - graph.setColor(Color.black); - graph.drawString("H", 29, 70); //$NON-NLS-1$ - } - } - - //Lets draw our armor and internal status bars - int baseBarLength = 23; - int barLength = 0; - double percentRemaining = 0.00; - - percentRemaining = entity.getArmorRemainingPercent(); - barLength = (int)(baseBarLength * percentRemaining); - - graph.setColor(Color.darkGray); - graph.fillRect(56, 7, 23, 3); - graph.setColor(Color.lightGray); - graph.fillRect(55, 6, 23, 3); - graph.setColor(getStatusBarColor(percentRemaining)); - graph.fillRect(55, 6, barLength, 3); - - percentRemaining = entity.getInternalRemainingPercent(); - barLength = (int)(baseBarLength * percentRemaining); - - graph.setColor(Color.darkGray); - graph.fillRect(56, 11, 23, 3); - graph.setColor(Color.lightGray); - graph.fillRect(55, 10, 23, 3); - graph.setColor(getStatusBarColor(percentRemaining)); - graph.fillRect(55, 10, barLength, 3); - - // create final image - this.image = createImage(new FilteredImageSource(tempImage.getSource(), - new KeyAlphaFilter(TRANSPARENT))); - } - - /* - * We only want to show double-blind visibility indicators on - * our own mechs and teammates mechs (assuming team vision option). - */ - private boolean trackThisEntitiesVisibilityInfo(Entity e) { - if (getLocalPlayer() == null) { - return false; - } - - if (game.getOptions().booleanOption("double_blind") //$NON-NLS-1$ - && (e.getOwner().getId() == getLocalPlayer().getId() - || (game.getOptions().booleanOption("team_vision") //$NON-NLS-1$ - && e.getOwner().getTeam() == getLocalPlayer().getTeam()))) { - return true; - } else { - return false; - } - } - - private Color getStatusBarColor(double percentRemaining) { - if ( percentRemaining <= .25 ) - return Color.red; - else if ( percentRemaining <= .75 ) - return Color.yellow; - else - return new Color(16, 196, 16); - } - - /** - * Overrides to provide for a smaller sensitive area. - */ - public boolean isInside(Point point) { - return entityRect.contains( point.x + view.x - offset.x, - point.y + view.y - offset.y); - } - - private String[] getTooltip() { - String[] tipStrings = new String[3]; - StringBuffer buffer; - - buffer = new StringBuffer(); - buffer.append( entity.getChassis() ) - .append( " (" ) //$NON-NLS-1$ - .append( entity.getOwner().getName() ) - .append( "); " ) //$NON-NLS-1$ - .append( entity.getCrew().getGunnery() ) - .append( "/" ) //$NON-NLS-1$ - .append( entity.getCrew().getPiloting() ) - .append( Messages.getString("BoardView1.pilot") ); //$NON-NLS-1$ - int numAdv = entity.getCrew().countAdvantages(); - if (numAdv > 0) { - buffer.append( " <" ) //$NON-NLS-1$ - .append( numAdv ) - .append( Messages.getString("BoardView1.advs") ); //$NON-NLS-1$ - } - tipStrings[0] = buffer.toString(); - - buffer = new StringBuffer(); - buffer.append( Messages.getString("BoardView1.move") ) //$NON-NLS-1$ - .append( entity.getMovementAbbr(entity.moved) ) - .append( ":" ) //$NON-NLS-1$ - .append( entity.delta_distance ) - .append( " (+" ) //$NON-NLS-1$ - .append( Compute.getTargetMovementModifier - (game, entity.getId()).getValue() ) - .append( ");" ) //$NON-NLS-1$ - .append( Messages.getString("BoardView1.Heat") ) //$NON-NLS-1$ - .append( entity.heat ); - if (entity.isDone()) - buffer.append(" (").append(Messages.getString("BoardView1.done")).append(")"); - tipStrings[1] = buffer.toString(); - - buffer = new StringBuffer(); - buffer.append( Messages.getString("BoardView1.Armor") ) //$NON-NLS-1$ - .append( entity.getTotalArmor() ) - .append( Messages.getString("BoardView1.internal") ) //$NON-NLS-1$ - .append( entity.getTotalInternal() ); - tipStrings[2] = buffer.toString(); - - return tipStrings; - } - } - - /** - * Sprite for a step in a movement path. Only one sprite should exist for - * any hex in a path. Contains a colored number, and arrows indicating - * entering, exiting or turning. - */ - private class StepSprite extends Sprite - { - private MoveStep step; - - public StepSprite(MoveStep step) { - this.step = step; - - // step is the size of the hex that this step is in - bounds = new Rectangle(getHexLocation(step.getPosition()), hex_size); - this.image = null; - } - - public void prepare() { - // create image for buffer - Image tempImage = createImage(bounds.width, bounds.height); - Graphics graph = tempImage.getGraphics(); - - // fill with key color - graph.setColor(new Color(TRANSPARENT)); - graph.fillRect(0, 0, bounds.width, bounds.height); - - // setup some variables - final Point stepPos = getHexLocation(step.getPosition()); - stepPos.translate(-bounds.x, -bounds.y); - final Polygon facingPoly = facingPolys[step.getFacing()]; - final Polygon movePoly = movementPolys[step.getFacing()]; - Point offsetCostPos; - Polygon myPoly; - Color col; - // set color - switch (step.getMovementType()) { - case IEntityMovementType.MOVE_RUN: - case IEntityMovementType.MOVE_VTOL_RUN: - if (step.isUsingMASC()) { - col = GUIPreferences.getInstance().getColor("AdvancedMoveMASCColor"); - } else { - col = GUIPreferences.getInstance().getColor("AdvancedMoveRunColor"); - } - break; - case IEntityMovementType.MOVE_JUMP : - col = GUIPreferences.getInstance().getColor("AdvancedMoveJumpColor"); - break; - case IEntityMovementType.MOVE_ILLEGAL : - col = GUIPreferences.getInstance().getColor("AdvancedMoveIllegalColor"); - break; - default : - if (step.getType()==MovePath.STEP_BACKWARDS) { - col = GUIPreferences.getInstance().getColor("AdvancedMoveBackColor"); - } else { - col = GUIPreferences.getInstance().getColor("AdvancedMoveDefaultColor"); - } - break; - } - - // draw arrows and cost for the step - switch (step.getType()) { - case MovePath.STEP_FORWARDS : - case MovePath.STEP_BACKWARDS : - case MovePath.STEP_CHARGE : - case MovePath.STEP_DFA : - case MovePath.STEP_LATERAL_LEFT : - case MovePath.STEP_LATERAL_RIGHT : - case MovePath.STEP_LATERAL_LEFT_BACKWARDS : - case MovePath.STEP_LATERAL_RIGHT_BACKWARDS : - // draw arrows showing them entering the next - myPoly = new Polygon(movePoly.xpoints, movePoly.ypoints, - movePoly.npoints); - graph.setColor(Color.darkGray); - myPoly.translate(stepPos.x + 1, stepPos.y + 1); - graph.drawPolygon(myPoly); - graph.setColor(col); - myPoly.translate(-1, -1); - graph.drawPolygon(myPoly); - // draw movement cost - drawMovementCost(step, stepPos, graph, col, true); - break; - case MovePath.STEP_GO_PRONE: - // draw arrow indicating dropping prone - Polygon downPoly = movementPolys[7]; - myPoly = new Polygon(downPoly.xpoints, downPoly.ypoints, downPoly.npoints); - graph.setColor(Color.darkGray); - myPoly.translate(stepPos.x, stepPos.y); - graph.drawPolygon(myPoly); - graph.setColor(col); - myPoly.translate(-1, -1); - graph.drawPolygon(myPoly); - offsetCostPos = new Point(stepPos.x + 1, stepPos.y + 15); - drawMovementCost(step, offsetCostPos, graph, col, false); - break; - case MovePath.STEP_GET_UP: - // draw arrow indicating standing up - Polygon upPoly = movementPolys[6]; - myPoly = new Polygon(upPoly.xpoints, upPoly.ypoints, upPoly.npoints); - graph.setColor(Color.darkGray); - myPoly.translate(stepPos.x, stepPos.y); - graph.drawPolygon(myPoly); - graph.setColor(col); - myPoly.translate(-1, -1); - graph.drawPolygon(myPoly); - offsetCostPos = new Point(stepPos.x, stepPos.y + 15); - drawMovementCost(step, offsetCostPos, graph, col, false); - break; - case MovePath.STEP_TURN_LEFT: - case MovePath.STEP_TURN_RIGHT: - // draw arrows showing the facing - myPoly = new Polygon(facingPoly.xpoints, facingPoly.ypoints, - facingPoly.npoints); - graph.setColor(Color.darkGray); - myPoly.translate(stepPos.x + 1, stepPos.y + 1); - graph.drawPolygon(myPoly); - graph.setColor(col); - myPoly.translate(-1, -1); - graph.drawPolygon(myPoly); - break; - case MovePath.STEP_LOAD: - // Announce load. - String load = Messages.getString("BoardView1.Load"); //$NON-NLS-1$ - if (step.isPastDanger()) { - load = "(" + load + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - graph.setFont(new Font("SansSerif", Font.PLAIN, 12)); //$NON-NLS-1$ - int loadX = stepPos.x + 42 - (graph.getFontMetrics(graph.getFont()).stringWidth(load) / 2); - graph.setColor(Color.darkGray); - graph.drawString(load, loadX, stepPos.y + 39); - graph.setColor(col); - graph.drawString(load, loadX - 1, stepPos.y + 38); - break; - case MovePath.STEP_UNLOAD: - // Announce unload. - String unload = Messages.getString("BoardView1.Unload"); //$NON-NLS-1$ - if (step.isPastDanger()) { - unload = "(" + unload + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - graph.setFont(new Font("SansSerif", Font.PLAIN, 12)); //$NON-NLS-1$ - int unloadX = stepPos.x + 42 - (graph.getFontMetrics(graph.getFont()).stringWidth(unload) / 2); - int unloadY = stepPos.y + 38 + graph.getFontMetrics(graph.getFont()).getHeight(); - graph.setColor(Color.darkGray); - graph.drawString(unload, unloadX, unloadY + 1); - graph.setColor(col); - graph.drawString(unload, unloadX - 1, unloadY); - break; - - default : - break; - } - - // create final image - this.image = createImage(new FilteredImageSource(tempImage.getSource(), - new KeyAlphaFilter(TRANSPARENT))); - } - - public Rectangle getBounds(){ - bounds = new Rectangle(getHexLocation(step.getPosition()), hex_size); - return bounds; - } - - public MoveStep getStep() { - return step; - } - - private void drawMovementCost(MoveStep step, Point stepPos, Graphics graph, Color col, boolean shiftFlag) { - String costString = null; - StringBuffer costStringBuf = new StringBuffer(); - costStringBuf.append( step.getMpUsed() ); - - // If the step is using a road bonus, mark it. - if ( step.isPavementStep() && step.getParent().getEntity() instanceof Tank ) { - costStringBuf.append( "+" ); //$NON-NLS-1$ - } - - // If the step is dangerous, mark it. - if ( step.isDanger() ) { - costStringBuf.append( "*" ); //$NON-NLS-1$ - } - - // If the step is past danger, mark that. - if (step.isPastDanger()) { - costStringBuf.insert( 0, "(" ); //$NON-NLS-1$ - costStringBuf.append( ")" ); //$NON-NLS-1$ - } - - if (step.isUsingMASC()) { - costStringBuf.append("["); //$NON-NLS-1$ - costStringBuf.append(step.getTargetNumberMASC()); - costStringBuf.append("+]"); //$NON-NLS-1$ - } - - if (step.getMovementType() == IEntityMovementType.MOVE_VTOL_WALK || - step.getMovementType() == IEntityMovementType.MOVE_VTOL_RUN) { - costStringBuf.append("{").append(step.getElevation()).append("}"); - } - - // Convert the buffer to a String and draw it. - costString = costStringBuf.toString(); - graph.setFont(new Font("SansSerif", Font.PLAIN, 12)); //$NON-NLS-1$ - int costX = stepPos.x + 42; - if (shiftFlag) { - costX -= (graph.getFontMetrics(graph.getFont()).stringWidth(costString) / 2); - } - graph.setColor(Color.darkGray); - graph.drawString(costString, costX, stepPos.y + 39); - graph.setColor(col); - graph.drawString(costString, costX - 1, stepPos.y + 38); - } - - } - - /** - * Sprite and info for a C3 network. Does not actually use the image buffer - * as this can be horribly inefficient for long diagonal lines. - */ - private class C3Sprite extends Sprite - { - private Polygon C3Poly; - - protected int entityId; - protected int masterId; - protected Entity entityE; - protected Entity entityM; - - Color spriteColor; - - public C3Sprite(Entity e, Entity m) { - this.entityE = e; - this.entityM = m; - this.entityId = e.getId(); - this.masterId = m.getId(); - this.spriteColor = PlayerColors.getColor(e.getOwner().getColorIndex()); - - if(e.getPosition() == null || m.getPosition() == null) { - C3Poly = new Polygon(); - C3Poly.addPoint(0, 0); - C3Poly.addPoint(1,0); - C3Poly.addPoint(0,1); - this.bounds = new Rectangle(C3Poly.getBounds()); - bounds.setSize(bounds.getSize().width + 1, bounds.getSize().height + 1); - this.image = null; - return; - } - - makePoly(); - - // set bounds - this.bounds = new Rectangle(C3Poly.getBounds()); - bounds.setSize(bounds.getSize().width + 1, bounds.getSize().height + 1); - - // move poly to upper right of image - C3Poly.translate(-bounds.getLocation().x, -bounds.getLocation().y); - - // set names & stuff - - // nullify image - this.image = null; - } - - public void prepare() { - } - - private void makePoly( ){ - // make a polygon - final Point a = getHexLocation(entityE.getPosition()); - final Point t = getHexLocation(entityM.getPosition()); - - final double an = (entityE.getPosition().radian(entityM.getPosition()) + (Math.PI * 1.5)) % (Math.PI * 2); // angle - final double lw = scale*C3_LINE_WIDTH; // line width - - C3Poly = new Polygon(); - C3Poly.addPoint( - a.x + (int)(scale*(HEX_W/2) - (int)Math.round(Math.sin(an) * lw)), - a.y + (int)(scale*(HEX_H/2) + (int)Math.round(Math.cos(an) * lw))); - C3Poly.addPoint( - a.x + (int)(scale*(HEX_W/2) + (int)Math.round(Math.sin(an) * lw)), - a.y + (int)(scale*(HEX_H/2) - (int)Math.round(Math.cos(an) * lw))); - C3Poly.addPoint( - t.x + (int)(scale*(HEX_W/2) + (int)Math.round(Math.sin(an) * lw)), - t.y + (int)(scale*(HEX_H/2) - (int)Math.round(Math.cos(an) * lw))); - C3Poly.addPoint( - t.x + (int)(scale*(HEX_W/2) - (int)Math.round(Math.sin(an) * lw)), - t.y + (int)(scale*(HEX_H/2) + (int)Math.round(Math.cos(an) * lw))); - } - - public Rectangle getBounds(){ - makePoly(); - // set bounds - this.bounds = new Rectangle(C3Poly.getBounds()); - bounds.setSize(bounds.getSize().width + 1, bounds.getSize().height + 1); - - // move poly to upper right of image - C3Poly.translate(-bounds.getLocation().x, -bounds.getLocation().y); - this.image = null; - - return bounds; - } - - public boolean isReady() { - return true; - } - - public void drawOnto(Graphics g, int x, int y, ImageObserver observer) { - //makePoly(); - - Polygon drawPoly = new Polygon(C3Poly.xpoints, C3Poly.ypoints, C3Poly.npoints); - drawPoly.translate(x, y); - - g.setColor(spriteColor); - g.fillPolygon(drawPoly); - g.setColor(Color.black); - g.drawPolygon(drawPoly); - } - - /** - * Return true if the point is inside our polygon - */ - public boolean isInside(Point point) { - return C3Poly.contains(point.x + view.x - bounds.x - offset.x, - point.y + view.y - bounds.y - offset.y); - } - - } - - /** - * Sprite and info for an attack. Does not actually use the image buffer - * as this can be horribly inefficient for long diagonal lines. - * - * Appears as an arrow. Arrow becoming cut in half when two Meks attacking - * each other. - */ - private class AttackSprite extends Sprite - { - private java.util.Vector attacks = new java.util.Vector(); - private Point a; - private Point t; - private double an; - private StraightArrowPolygon attackPoly; - private Color attackColor; - private int entityId; - private int targetType; - private int targetId; - private String attackerDesc; - private String targetDesc; - private Vector weaponDescs = new Vector(); - private final Entity ae; - private final Targetable target; - - public AttackSprite(AttackAction attack) { - this.attacks.addElement(attack); - this.entityId = attack.getEntityId(); - this.targetType = attack.getTargetType(); - this.targetId = attack.getTargetId(); - this.ae = game.getEntity(attack.getEntityId()); - this.target = game.getTarget(targetType, targetId); - - // color? - attackColor = PlayerColors.getColor(ae.getOwner().getColorIndex()); - //angle of line connecting two hexes - this.an = (ae.getPosition().radian(target.getPosition()) + (Math.PI * 1.5)) % (Math.PI * 2); // angle - makePoly(); - - // set bounds - this.bounds = new Rectangle(attackPoly.getBounds()); - bounds.setSize(bounds.getSize().width + 1, bounds.getSize().height + 1); - // move poly to upper right of image - attackPoly.translate(-bounds.getLocation().x, -bounds.getLocation().y); - - // set names & stuff - attackerDesc = ae.getDisplayName(); - targetDesc = target.getDisplayName(); - if (attack instanceof WeaponAttackAction) { - addWeapon((WeaponAttackAction)attack); - } - if (attack instanceof KickAttackAction) { - addWeapon((KickAttackAction)attack); - } - if (attack instanceof PunchAttackAction) { - addWeapon((PunchAttackAction)attack); - } - if (attack instanceof PushAttackAction) { - addWeapon((PushAttackAction)attack); - } - if (attack instanceof ClubAttackAction) { - addWeapon((ClubAttackAction)attack); - } - if (attack instanceof ChargeAttackAction) { - addWeapon((ChargeAttackAction)attack); - } - if (attack instanceof DfaAttackAction) { - addWeapon((DfaAttackAction)attack); - } - if (attack instanceof ProtomechPhysicalAttackAction) { - addWeapon((ProtomechPhysicalAttackAction)attack); - } - - // nullify image - this.image = null; - } - - private void makePoly(){ - // make a polygon - this.a = getHexLocation(ae.getPosition()); - this.t = getHexLocation(target.getPosition()); - // OK, that is actually not good. I do not like hard coded figures. - // HEX_W/2 - x distance in pixels from origin of hex bounding box to the center of hex. - // HEX_H/2 - y distance in pixels from origin of hex bounding box to the center of hex. - // 18 - is actually 36/2 - we do not want arrows to start and end directly - // in the centes of hex and hiding mek under. - - a.x = a.x + (int)(HEX_W/2*scale) + (int)Math.round(Math.cos(an) * (int)(18*scale)); - t.x = t.x + (int)(HEX_W/2*scale) - (int)Math.round(Math.cos(an) * (int)(18*scale)); - a.y = a.y + (int)(HEX_H/2*scale) + (int)Math.round(Math.sin(an) * (int)(18*scale)); - t.y = t.y + (int)(HEX_H/2*scale) - (int)Math.round(Math.sin(an) * (int)(18*scale)); - - // Checking if given attack is mutual. In this case we building halved arrow - if (isMutualAttack()){ - attackPoly = new StraightArrowPolygon(a, t, (int)(8*scale), (int)(12*scale), true); - } else { - attackPoly = new StraightArrowPolygon(a, t, (int)(4*scale), (int)(8*scale), false); - } - } - - public Rectangle getBounds(){ - makePoly(); - // set bounds - this.bounds = new Rectangle(attackPoly.getBounds()); - bounds.setSize(bounds.getSize().width + 1, bounds.getSize().height + 1); - // move poly to upper right of image - attackPoly.translate(-bounds.getLocation().x, -bounds.getLocation().y); - - return bounds; - } - - /** If we have build full arrow already with single attack and have got - * counter attack from our target lately - lets change arrow to halved. - */ - public void rebuildToHalvedPolygon(){ - attackPoly = new StraightArrowPolygon(a, t, (int)(8*scale), (int)(12*scale), true); - // set bounds - this.bounds = new Rectangle(attackPoly.getBounds()); - bounds.setSize(bounds.getSize().width + 1, bounds.getSize().height + 1); - // move poly to upper right of image - attackPoly.translate(-bounds.getLocation().x, -bounds.getLocation().y); - } - /** Cheking if attack is mutual and changing target arrow to half-arrow - */ - private boolean isMutualAttack(){ - for (final Iterator i = attackSprites.iterator(); i.hasNext();) { - final AttackSprite sprite = (AttackSprite)i.next(); - if (sprite.getEntityId() == this.targetId && sprite.getTargetId() == this.entityId) { - sprite.rebuildToHalvedPolygon(); - return true; - } - } - return false; - } - - public void prepare() { - } - - public boolean isReady() { - return true; - } - - public void drawOnto(Graphics g, int x, int y, ImageObserver observer) { - Polygon drawPoly = new Polygon(attackPoly.xpoints, attackPoly.ypoints, attackPoly.npoints); - drawPoly.translate(x, y); - - g.setColor(attackColor); - g.fillPolygon(drawPoly); - g.setColor(Color.gray.darker()); - g.drawPolygon(drawPoly); - } - - /** - * Return true if the point is inside our polygon - */ - public boolean isInside(Point point) { - return attackPoly.contains(point.x + view.x - bounds.x - offset.x, - point.y + view.y - bounds.y - offset.y); - } - - public int getEntityId() { - return entityId; - } - - public int getTargetId() { - return targetId; - } - - /** - * Adds a weapon to this attack - */ - public void addWeapon(WeaponAttackAction attack) { - final Entity entity = game.getEntity(attack.getEntityId()); - final WeaponType wtype = (WeaponType)entity.getEquipment(attack.getWeaponId()).getType(); - final String roll = attack.toHit(game).getValueAsString(); - weaponDescs.addElement( wtype.getName() + Messages.getString("BoardView1.needs") + roll ); //$NON-NLS-1$ - } - - public void addWeapon(KickAttackAction attack) { - String bufer = ""; //$NON-NLS-1$ - String rollLeft = ""; //$NON-NLS-1$ - String rollRight = ""; //$NON-NLS-1$ - final int leg = attack.getLeg(); - switch (leg){ - case KickAttackAction.BOTH: - rollLeft = KickAttackAction.toHit( game, attack.getEntityId(), game.getTarget(attack.getTargetType(), attack.getTargetId()), KickAttackAction.LEFT).getValueAsString(); - rollRight = KickAttackAction.toHit( game, attack.getEntityId(), game.getTarget(attack.getTargetType(), attack.getTargetId()), KickAttackAction.RIGHT).getValueAsString(); - bufer = Messages.getString("BoardView1.kickBoth", new Object[]{rollLeft,rollRight}); //$NON-NLS-1$ - break; - case KickAttackAction.LEFT: - rollLeft = KickAttackAction.toHit( game, attack.getEntityId(), game.getTarget(attack.getTargetType(), attack.getTargetId()), KickAttackAction.LEFT).getValueAsString(); - bufer = Messages.getString("BoardView1.kickLeft", new Object[]{rollLeft}); //$NON-NLS-1$ - break; - case KickAttackAction.RIGHT: - rollRight = KickAttackAction.toHit( game, attack.getEntityId(), game.getTarget(attack.getTargetType(), attack.getTargetId()), KickAttackAction.RIGHT).getValueAsString(); - bufer = Messages.getString("BoardView1.kickRight", new Object[]{rollRight}); //$NON-NLS-1$ - break; - } - weaponDescs.addElement(bufer); - } - - public void addWeapon(PunchAttackAction attack) { - String bufer = ""; //$NON-NLS-1$ - String rollLeft = ""; //$NON-NLS-1$ - String rollRight = ""; //$NON-NLS-1$ - final int arm = attack.getArm(); - switch (arm){ - case PunchAttackAction.BOTH: - rollLeft = PunchAttackAction.toHit( game, attack.getEntityId(), game.getTarget(attack.getTargetType(), attack.getTargetId()), PunchAttackAction.LEFT).getValueAsString(); - rollRight = PunchAttackAction.toHit( game, attack.getEntityId(), game.getTarget(attack.getTargetType(), attack.getTargetId()), PunchAttackAction.RIGHT).getValueAsString(); - bufer = Messages.getString("BoardView1.punchBoth", new Object[]{rollLeft,rollRight}); //$NON-NLS-1$ - break; - case PunchAttackAction.LEFT: - rollLeft = PunchAttackAction.toHit( game, attack.getEntityId(), game.getTarget(attack.getTargetType(), attack.getTargetId()), PunchAttackAction.LEFT).getValueAsString(); - bufer = Messages.getString("BoardView1.punchLeft", new Object[]{rollLeft}); //$NON-NLS-1$ - break; - case PunchAttackAction.RIGHT: - rollRight = PunchAttackAction.toHit( game, attack.getEntityId(), game.getTarget(attack.getTargetType(), attack.getTargetId()), PunchAttackAction.RIGHT).getValueAsString(); - bufer = Messages.getString("BoardView1.punchRight", new Object[]{rollRight}); //$NON-NLS-1$ - break; - } - weaponDescs.addElement(bufer); - } - - public void addWeapon(PushAttackAction attack) { - final String roll = attack.toHit(game).getValueAsString(); - weaponDescs.addElement(Messages.getString("BoardView1.push", new Object[]{roll})); //$NON-NLS-1$ - } - - public void addWeapon(ClubAttackAction attack) { - final String roll = attack.toHit(game).getValueAsString(); - final String club = attack.getClub().getName(); - weaponDescs.addElement(Messages.getString("BoardView1.hit", new Object[]{club,roll})); //$NON-NLS-1$ - } - - public void addWeapon(ChargeAttackAction attack) { - final String roll = attack.toHit(game).getValueAsString(); - weaponDescs.addElement(Messages.getString("BoardView1.charge", new Object[]{roll})); //$NON-NLS-1$ - } - public void addWeapon(DfaAttackAction attack) { - final String roll = attack.toHit(game).getValueAsString(); - weaponDescs.addElement(Messages.getString("BoardView1.DFA", new Object[]{roll})); //$NON-NLS-1$ - } - public void addWeapon(ProtomechPhysicalAttackAction attack) { - final String roll = attack.toHit(game).getValueAsString(); - weaponDescs.addElement(Messages.getString("BoardView1.proto", new Object[]{roll})); //$NON-NLS-1$ - } - - private String[] getTooltip() { - String[] tipStrings = new String[1 + weaponDescs.size()]; - int tip = 1; - tipStrings[0] = attackerDesc + " "+Messages.getString("BoardView1.on")+" " + targetDesc; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - for (Iterator i = weaponDescs.iterator(); i.hasNext();) { - tipStrings[tip++] = (String)i.next(); - } - return tipStrings; - } - } - - /** - * Determine if the tile manager's images have been loaded. - * - * @return true if all images have been loaded. - * false if more need to be loaded. - */ - public boolean isTileImagesLoaded() { - return this.tileManager.isLoaded(); - } - - public void setUseLOSTool(boolean use) { - useLOSTool = use; - } - - public TilesetManager getTilesetManager() { - return tileManager; - } - - // added by kenn - public void drawRuler(Coords s, Coords e, Color sc, Color ec) { - rulerStart = s; - rulerEnd = e; - rulerStartColor = sc; - rulerEndColor = ec; - - repaint(); - } - // end kenn - - /** - * @param lastCursor The lastCursor to set. - */ - public void setLastCursor(Coords lastCursor) { - this.lastCursor = lastCursor; - } - - /** - * @return Returns the lastCursor. - */ - public Coords getLastCursor() { - return lastCursor; - } - - /** - * @param highlighted The highlighted to set. - */ - public void setHighlighted(Coords highlighted) { - this.highlighted = highlighted; - } - - /** - * @return Returns the highlighted. - */ - public Coords getHighlighted() { - return highlighted; - } - - /** - * @param selected The selected to set. - */ - public void setSelected(Coords selected) { - this.selected = selected; - } - - /** - * @return Returns the selected. - */ - public Coords getSelected() { - return selected; - } - - /** - * @param firstLOS The firstLOS to set. - */ - public void setFirstLOS(Coords firstLOS) { - this.firstLOS = firstLOS; - } - - /** - * @return Returns the firstLOS. - */ - public Coords getFirstLOS() { - return firstLOS; - } - - /** - * Determines if this Board contains the Coords, - * and if so, "selects" that Coords. - * - * @param coords the Coords. - */ - public void select(Coords coords) { - if(coords == null || game.getBoard().contains(coords)) { - setSelected(coords); - moveCursor(selectedSprite, coords); - moveCursor(firstLOSSprite, null); - moveCursor(secondLOSSprite, null); - processBoardViewEvent(new BoardViewEvent(this, coords, null, BoardViewEvent.BOARD_HEX_SELECTED,0)); - } - } - - /** - * "Selects" the specified Coords. - * - * @param x the x coordinate. - * @param y the y coordinate. - */ - public void select(int x, int y) { - select(new Coords(x, y)); - } - - /** - * Determines if this Board contains the Coords, - * and if so, highlights that Coords. - * - * @param coords the Coords. - */ - public void highlight(Coords coords) { - if(coords == null || game.getBoard().contains(coords)) { - setHighlighted(coords); - moveCursor(highlightSprite, coords); - moveCursor(firstLOSSprite, null); - moveCursor(secondLOSSprite, null); - processBoardViewEvent(new BoardViewEvent(this, coords, null, BoardViewEvent.BOARD_HEX_HIGHLIGHTED, 0)); - } - } - - /** - * Highlights the specified Coords. - * - * @param x the x coordinate. - * @param y the y coordinate. - */ - public void highlight(int x, int y) { - highlight(new Coords(x, y)); - } - - /** - * Determines if this Board contains the Coords, - * and if so, "cursors" that Coords. - * - * @param coords the Coords. - */ - public void cursor(Coords coords) { - if(coords == null || game.getBoard().contains(coords)) { - if(getLastCursor() == null || coords == null || !coords.equals(getLastCursor())) { - setLastCursor(coords); - moveCursor(cursorSprite, coords); - moveCursor(firstLOSSprite, null); - moveCursor(secondLOSSprite, null); - processBoardViewEvent(new BoardViewEvent(this, coords, null, BoardViewEvent.BOARD_HEX_CURSOR, 0)); - } else { - setLastCursor(coords); - } - } - } - - /** - * "Cursors" the specified Coords. - * - * @param x the x coordinate. - * @param y the y coordinate. - */ - public void cursor(int x, int y) { - cursor(new Coords(x, y)); - } - - public void checkLOS(Coords c) { - if(c == null || game.getBoard().contains(c)) { - if (getFirstLOS() == null) { - setFirstLOS(c); - firstLOSHex(c); - processBoardViewEvent(new BoardViewEvent(this, c, null, BoardViewEvent.BOARD_FIRST_LOS_HEX, 0)); - } else { - secondLOSHex(c,getFirstLOS()); - processBoardViewEvent(new BoardViewEvent(this, c, null, BoardViewEvent.BOARD_SECOND_LOS_HEX, 0)); - setFirstLOS(null); - } - } - } - - /** - * Determines if this Board contains the (x, y) Coords, - * and if so, notifies listeners about the specified mouse - * action. - */ - public void mouseAction(int x, int y, int mtype, int modifiers) { - if(game.getBoard().contains(x, y)) { - Coords c = new Coords(x, y); - switch(mtype) { - case BOARD_HEX_CLICK : - if ((modifiers & java.awt.event.InputEvent.CTRL_MASK) != 0) { - checkLOS(c); - } else { - processBoardViewEvent(new BoardViewEvent(this, c, null, BoardViewEvent.BOARD_HEX_CLICKED, modifiers)); - } - break; - case BOARD_HEX_DOUBLECLICK : - processBoardViewEvent(new BoardViewEvent(this, c, null, BoardViewEvent.BOARD_HEX_DOUBLECLICKED, modifiers)); - break; - case BOARD_HEX_DRAG : - processBoardViewEvent(new BoardViewEvent(this, c, null, BoardViewEvent.BOARD_HEX_DRAGGED, modifiers)); - break; - } - } - } - - /** - * Notifies listeners about the specified mouse action. - * - * @param coords the Coords. - */ - public void mouseAction(Coords coords, int mtype, int modifiers) { - mouseAction(coords.x, coords.y, mtype, modifiers); - } - - /** - * Return, whether a popup may be drawn, this currently means, whether no scrolling took place. - */ - public boolean mayDrawPopup() { - return !scrolled; - } - - /* (non-Javadoc) - * @see megamek.common.BoardListener#boardNewBoard(megamek.common.BoardEvent) - */ - public void boardNewBoard(BoardEvent b) { - updateBoard(); - } - - /* (non-Javadoc) - * @see megamek.common.BoardListener#boardChangedHex(megamek.common.BoardEvent) - */ - public void boardChangedHex(BoardEvent b) { - IHex hex = game.getBoard().getHex(b.getCoords()); - tileManager.clearHex(hex); - tileManager.waitForHex(hex); - if (boardGraph != null) { - redrawAround(b.getCoords()); - } - } - - //TODO Is there a better solution? - //This is required because the BoardView creates the redraw thread - //that must be stopped explicitly - public void die() { - redrawWorker.stop(); - } - - private GameListener gameListener = new GameListenerAdapter(){ - - public void gameEntityNew(GameEntityNewEvent e) { - redrawAllEntities(); - } - - public void gameEntityRemove(GameEntityRemoveEvent e) { - redrawAllEntities(); - } - - public void gameEntityChange(GameEntityChangeEvent e) { - java.util.Vector mp = e.getMovePath(); - if (mp != null && mp.size() > 0 && GUIPreferences.getInstance().getShowMoveStep()) { - addMovingUnit(e.getEntity(), mp); - }else { - redrawEntity(e.getEntity()); - } - } - - public void gameNewAction(GameNewActionEvent e) { - EntityAction ea = e.getAction(); - if (ea instanceof AttackAction) { - addAttack((AttackAction)ea); - } - } - - public void gameBoardNew(GameBoardNewEvent e) { - IBoard b = e.getOldBoard(); - if (b != null) { - b.removeBoardListener(BoardView1.this); - } - b = e.getNewBoard(); - if (b != null) { - b.addBoardListener(BoardView1.this); - } - updateBoard(); - } - - public void gameBoardChanged(GameBoardChangeEvent e) { - boardImage = null; - boardGraph = null; - redrawAllEntities(); - } - }; - - protected void updateBoard() { - updateBoardSize(); - backGraph = null; - backImage = null; - backSize = null; - boardImage = null; - boardGraph = null; - tileManager.reset(); - redrawAllEntities(); - } - - /* - * It's not quite polished solution, but on other hand it's better then nothing. - */ - protected class RedrawWorker implements Runnable { - - private boolean finished = false; - - public void start() { - Thread thread = new Thread(this, "BoardView RedrawWorker Thread"); //$NON-NLS-1$ - thread.start(); - - } - - public void stop() { - finished = true; - } - - public void run() { - long lastTime = System.currentTimeMillis(); - long currentTime = System.currentTimeMillis(); - while (!finished) { - try { - Thread.sleep(20); - } catch(InterruptedException ex) { - // duh? - } - if (finished) { - break; - } - if (!isShowing()) { - currentTime = System.currentTimeMillis(); - lastTime = currentTime; - continue; - } - currentTime = System.currentTimeMillis(); - boolean redraw = false; - for (int i = 0; i < displayables.size(); i++) { - Displayable disp = (Displayable) displayables.elementAt(i); - if (!disp.isSliding()) { - disp.setIdleTime(currentTime - lastTime, true); - } else { - redraw = redraw || disp.slide(); - } - } - if (backSize != null) { - redraw = redraw || doMoveUnits(currentTime - lastTime); - redraw = redraw || doScroll(); - checkTooltip(); - } else { - repaint(100); - } - if (redraw) { - repaint(); - } - lastTime = currentTime; - } - } - } -} diff --git a/java/cvsvintage/IRMILocalContext_1.1_1.2_v0.java b/java/cvsvintage/IRMILocalContext_1.1_1.2_v0.java deleted file mode 100644 index e67ee3b..0000000 --- a/java/cvsvintage/IRMILocalContext_1.1_1.2_v0.java +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Copyright (C) 2005 - Bull S.A. - * - * CAROL: Common Architecture for RMI ObjectWeb Layer - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - * - * -------------------------------------------------------------------------- - * $Id: IRMILocalContext.java,v 1.1 2005-09-15 13:04:16 benoitf Exp $ - * -------------------------------------------------------------------------- - */ -package org.objectweb.carol.jndi.spi; - -import javax.naming.Context; -import javax.naming.Name; -import javax.naming.NamingException; -import javax.naming.Reference; -import javax.naming.spi.ObjectFactory; - -import org.objectweb.carol.jndi.registry.IRMIRegistryWrapperContext; -import org.objectweb.carol.jndi.wrapping.JNDIRemoteResource; -import org.objectweb.carol.jndi.wrapping.RemoteReference; -import org.objectweb.carol.rmi.exception.NamingExceptionHelper; - - -/** - * Use the wrapper on registry object defined by RegistryWrapperContext class. - * This class has been refactored to split : - *
    - *
  • - wrapper on registry object
  • - *
  • - Single instance
  • - *
  • - Wrapping of Serializable/Referenceable/... objects
  • - *
- * @author Florent Benoit - */ -public class IRMILocalContext extends IRMIContext implements Context { - - /** - * Constructs an IRMI local Wrapper context - * @param irmiLocalContext the inital Local IRMI context - * @throws NamingException if the registry wrapper cannot be build - */ - public IRMILocalContext(Context irmiLocalContext) throws NamingException { - super(new IRMIRegistryWrapperContext(irmiLocalContext.getEnvironment())); - } - - /** - * If this object is a reference wrapper return the reference If this object - * is a resource wrapper return the resource - * @param o the object to resolve - * @param name name of the object to unwrap - * @return the unwrapped object - * @throws NamingException if the object cannot be unwraped - */ - protected Object unwrapObject(Object o, Name name) throws NamingException { - try { - if (o instanceof RemoteReference) { - // build of the Referenceable object with is Reference - Reference objRef = ((RemoteReference) o).getReference(); - ObjectFactory objFact = (ObjectFactory) (Class.forName(objRef.getFactoryClassName())).newInstance(); - return objFact.getObjectInstance(objRef, name, this, getEnvironment()); - } else if (o instanceof JNDIRemoteResource) { - return ((JNDIRemoteResource) o).getResource(); - } else { - return o; - } - } catch (Exception e) { - throw NamingExceptionHelper.create("Cannot unwrap object '" + o + "' with name '" + name + "'.", e); - } - } - -} diff --git a/java/cvsvintage/IRMILocalContext_1.1_1.2_v1.java b/java/cvsvintage/IRMILocalContext_1.1_1.2_v1.java deleted file mode 100644 index f2bf7bd..0000000 --- a/java/cvsvintage/IRMILocalContext_1.1_1.2_v1.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright (C) 2005 - Bull S.A. - * - * CAROL: Common Architecture for RMI ObjectWeb Layer - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - * - * -------------------------------------------------------------------------- - * $Id: IRMILocalContext.java,v 1.2 2005-10-21 07:17:44 ashah Exp $ - * -------------------------------------------------------------------------- - */ -package org.objectweb.carol.jndi.spi; - -import javax.naming.Context; -import javax.naming.Name; -import javax.naming.NamingException; -import javax.naming.Reference; -import javax.naming.spi.ObjectFactory; - -import org.objectweb.carol.jndi.registry.IRMIRegistryWrapperContext; -import org.objectweb.carol.jndi.wrapping.JNDIRemoteResource; -import org.objectweb.carol.jndi.wrapping.RemoteReference; -import org.objectweb.carol.rmi.exception.NamingExceptionHelper; - - -/** - * Use the wrapper on registry object defined by RegistryWrapperContext class. - * This class has been refactored to split : - *
    - *
  • - wrapper on registry object
  • - *
  • - Single instance
  • - *
  • - Wrapping of Serializable/Referenceable/... objects
  • - *
- * @author Florent Benoit - */ -public class IRMILocalContext extends IRMIContext implements Context { - - /** - * Constructs an IRMI local Wrapper context - * @param irmiLocalContext the inital Local IRMI context - * @throws NamingException if the registry wrapper cannot be build - */ - public IRMILocalContext(Context irmiLocalContext) throws NamingException { - super(new IRMIRegistryWrapperContext(irmiLocalContext.getEnvironment())); - } -} diff --git a/java/cvsvintage/IndexWriter_1.2_1.3_v0.java b/java/cvsvintage/IndexWriter_1.2_1.3_v0.java deleted file mode 100644 index fa1335c..0000000 --- a/java/cvsvintage/IndexWriter_1.2_1.3_v0.java +++ /dev/null @@ -1,401 +0,0 @@ -package org.apache.lucene.index; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache Lucene" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache Lucene", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.IOException; -import java.io.File; -import java.io.PrintStream; -import java.util.Vector; - -import org.apache.lucene.store.Directory; -import org.apache.lucene.store.RAMDirectory; -import org.apache.lucene.store.FSDirectory; -import org.apache.lucene.store.Lock; -import org.apache.lucene.store.InputStream; -import org.apache.lucene.store.OutputStream; -import org.apache.lucene.document.Document; -import org.apache.lucene.analysis.Analyzer; - -/** - An IndexWriter creates and maintains an index. - - The third argument to the constructor - determines whether a new index is created, or whether an existing index is - opened for the addition of new documents. - - In either case, documents are added with the addDocument method. When finished adding - documents, close should be called. - - If an index will not have more documents added for a while and optimal search - performance is desired, then the optimize - method should be called before the index is closed. - */ - -public final class IndexWriter { - private Directory directory; // where this index resides - private Analyzer analyzer; // how to analyze text - - private SegmentInfos segmentInfos = new SegmentInfos(); // the segments - private final Directory ramDirectory = new RAMDirectory(); // for temp segs - - /** Constructs an IndexWriter for the index in path. Text will - be analyzed with a. If create is true, then a - new, empty index will be created in d, replacing the index - already there, if any. */ - public IndexWriter(String path, Analyzer a, boolean create) - throws IOException { - this(FSDirectory.getDirectory(path, create), a, create); - } - - /** Constructs an IndexWriter for the index in path. Text will - be analyzed with a. If create is true, then a - new, empty index will be created in d, replacing the index - already there, if any. */ - public IndexWriter(File path, Analyzer a, boolean create) - throws IOException { - this(FSDirectory.getDirectory(path, create), a, create); - } - - /** Constructs an IndexWriter for the index in d. Text will be - analyzed with a. If create is true, then a new, - empty index will be created in d, replacing the index already - there, if any. */ - public IndexWriter(Directory d, Analyzer a, final boolean create) - throws IOException { - directory = d; - analyzer = a; - - Lock writeLock = directory.makeLock("write.lock"); - if (!writeLock.obtain()) // obtain write lock - throw new IOException("Index locked for write: " + writeLock); - - synchronized (directory) { // in- & inter-process sync - new Lock.With(directory.makeLock("commit.lock")) { - public Object doBody() throws IOException { - if (create) - segmentInfos.write(directory); - else - segmentInfos.read(directory); - return null; - } - }.run(); - } - } - - /** Flushes all changes to an index, closes all associated files, and closes - the directory that the index is stored in. */ - public final synchronized void close() throws IOException { - flushRamSegments(); - ramDirectory.close(); - directory.makeLock("write.lock").release(); // release write lock - directory.close(); - } - - /** Returns the number of documents currently in this index. */ - public final synchronized int docCount() { - int count = 0; - for (int i = 0; i < segmentInfos.size(); i++) { - SegmentInfo si = segmentInfos.info(i); - count += si.docCount; - } - return count; - } - - /** The maximum number of terms that will be indexed for a single field in a - document. This limits the amount of memory required for indexing, so that - collections with very large files will not crash the indexing process by - running out of memory. - -

By default, no more than 10,000 terms will be indexed for a field. */ - public int maxFieldLength = 10000; - - /** Adds a document to this index.*/ - public final void addDocument(Document doc) throws IOException { - DocumentWriter dw = - new DocumentWriter(ramDirectory, analyzer, maxFieldLength); - String segmentName = newSegmentName(); - dw.addDocument(segmentName, doc); - synchronized (this) { - segmentInfos.addElement(new SegmentInfo(segmentName, 1, ramDirectory)); - maybeMergeSegments(); - } - } - - private final synchronized String newSegmentName() { - return "_" + Integer.toString(segmentInfos.counter++, Character.MAX_RADIX); - } - - /** Determines how often segment indexes are merged by addDocument(). With - * smaller values, less RAM is used while indexing, and searches on - * unoptimized indexes are faster, but indexing speed is slower. With larger - * values more RAM is used while indexing and searches on unoptimized indexes - * are slower, but indexing is faster. Thus larger values (> 10) are best - * for batched index creation, and smaller values (< 10) for indexes that are - * interactively maintained. - * - *

This must never be less than 2. The default value is 10.*/ - public int mergeFactor = 10; - - /** Determines the largest number of documents ever merged by addDocument(). - * Small values (e.g., less than 10,000) are best for interactive indexing, - * as this limits the length of pauses while indexing to a few seconds. - * Larger values are best for batched indexing and speedier searches. - * - *

The default value is {@link Integer#MAX_VALUE}. */ - public int maxMergeDocs = Integer.MAX_VALUE; - - /** If non-null, information about merges will be printed to this. */ - public PrintStream infoStream = null; - - /** Merges all segments together into a single segment, optimizing an index - for search. */ - public final synchronized void optimize() throws IOException { - flushRamSegments(); - while (segmentInfos.size() > 1 || - (segmentInfos.size() == 1 && - SegmentReader.hasDeletions(segmentInfos.info(0)))){ - int minSegment = segmentInfos.size() - mergeFactor; - mergeSegments(minSegment < 0 ? 0 : minSegment); - } - } - - /** Merges all segments from an array of indexes into this index. - * - *

This may be used to parallelize batch indexing. A large document - * collection can be broken into sub-collections. Each sub-collection can be - * indexed in parallel, on a different thread, process or machine. The - * complete index can then be created by merging sub-collection indexes - * with this method. - * - *

After this completes, the index is optimized. */ - public final synchronized void addIndexes(Directory[] dirs) - throws IOException { - optimize(); // start with zero or 1 seg - int minSegment = segmentInfos.size(); - int segmentsAddedSinceMerge = 0; - for (int i = 0; i < dirs.length; i++) { - SegmentInfos sis = new SegmentInfos(); // read infos from dir - sis.read(dirs[i]); - for (int j = 0; j < sis.size(); j++) { - segmentInfos.addElement(sis.info(j)); // add each info - - // merge whenever mergeFactor segments have been added - if (++segmentsAddedSinceMerge == mergeFactor) { - mergeSegments(minSegment++, false); - segmentsAddedSinceMerge = 0; - } - } - } - optimize(); // final cleanup - } - - /** Merges all RAM-resident segments. */ - private final void flushRamSegments() throws IOException { - int minSegment = segmentInfos.size()-1; - int docCount = 0; - while (minSegment >= 0 && - (segmentInfos.info(minSegment)).dir == ramDirectory) { - docCount += segmentInfos.info(minSegment).docCount; - minSegment--; - } - if (minSegment < 0 || // add one FS segment? - (docCount + segmentInfos.info(minSegment).docCount) > mergeFactor || - !(segmentInfos.info(segmentInfos.size()-1).dir == ramDirectory)) - minSegment++; - if (minSegment >= segmentInfos.size()) - return; // none to merge - mergeSegments(minSegment); - } - - /** Incremental segment merger. */ - private final void maybeMergeSegments() throws IOException { - long targetMergeDocs = mergeFactor; - while (targetMergeDocs <= maxMergeDocs) { - // find segments smaller than current target size - int minSegment = segmentInfos.size(); - int mergeDocs = 0; - while (--minSegment >= 0) { - SegmentInfo si = segmentInfos.info(minSegment); - if (si.docCount >= targetMergeDocs) - break; - mergeDocs += si.docCount; - } - - if (mergeDocs >= targetMergeDocs) // found a merge to do - mergeSegments(minSegment+1); - else - break; - - targetMergeDocs *= mergeFactor; // increase target size - } - } - - /** Pops segments off of segmentInfos stack down to minSegment, merges them, - and pushes the merged index onto the top of the segmentInfos stack. */ - private final void mergeSegments(int minSegment) throws IOException { - mergeSegments(minSegment, true); - } - - /** Pops segments off of segmentInfos stack down to minSegment, merges them, - and pushes the merged index onto the top of the segmentInfos stack. */ - private final void mergeSegments(int minSegment, boolean delete) - throws IOException { - String mergedName = newSegmentName(); - int mergedDocCount = 0; - if (infoStream != null) infoStream.print("merging segments"); - SegmentMerger merger = new SegmentMerger(directory, mergedName); - final Vector segmentsToDelete = new Vector(); - for (int i = minSegment; i < segmentInfos.size(); i++) { - SegmentInfo si = segmentInfos.info(i); - if (infoStream != null) - infoStream.print(" " + si.name + " (" + si.docCount + " docs)"); - SegmentReader reader = new SegmentReader(si); - merger.add(reader); - if (delete) - segmentsToDelete.addElement(reader); // queue for deletion - mergedDocCount += si.docCount; - } - if (infoStream != null) { - infoStream.println(); - infoStream.println(" into "+mergedName+" ("+mergedDocCount+" docs)"); - } - merger.merge(); - - segmentInfos.setSize(minSegment); // pop old infos & add new - segmentInfos.addElement(new SegmentInfo(mergedName, mergedDocCount, - directory)); - - synchronized (directory) { // in- & inter-process sync - new Lock.With(directory.makeLock("commit.lock")) { - public Object doBody() throws IOException { - segmentInfos.write(directory); // commit before deleting - deleteSegments(segmentsToDelete); // delete now-unused segments - return null; - } - }.run(); - } - } - - /* Some operating systems (e.g. Windows) don't permit a file to be deleted - while it is opened for read (e.g. by another process or thread). So we - assume that when a delete fails it is because the file is open in another - process, and queue the file for subsequent deletion. */ - - private final void deleteSegments(Vector segments) throws IOException { - Vector deletable = new Vector(); - - deleteFiles(readDeleteableFiles(), deletable); // try to delete deleteable - - for (int i = 0; i < segments.size(); i++) { - SegmentReader reader = (SegmentReader)segments.elementAt(i); - if (reader.directory == this.directory) - deleteFiles(reader.files(), deletable); // try to delete our files - else - deleteFiles(reader.files(), reader.directory); // delete, eg, RAM files - } - - writeDeleteableFiles(deletable); // note files we can't delete - } - - private final void deleteFiles(Vector files, Directory directory) - throws IOException { - for (int i = 0; i < files.size(); i++) - directory.deleteFile((String)files.elementAt(i)); - } - - private final void deleteFiles(Vector files, Vector deletable) - throws IOException { - for (int i = 0; i < files.size(); i++) { - String file = (String)files.elementAt(i); - try { - directory.deleteFile(file); // try to delete each file - } catch (IOException e) { // if delete fails - if (directory.fileExists(file)) { - if (infoStream != null) - infoStream.println(e.getMessage() + "; Will re-try later."); - deletable.addElement(file); // add to deletable - } - } - } - } - - private final Vector readDeleteableFiles() throws IOException { - Vector result = new Vector(); - if (!directory.fileExists("deletable")) - return result; - - InputStream input = directory.openFile("deletable"); - try { - for (int i = input.readInt(); i > 0; i--) // read file names - result.addElement(input.readString()); - } finally { - input.close(); - } - return result; - } - - private final void writeDeleteableFiles(Vector files) throws IOException { - OutputStream output = directory.createFile("deleteable.new"); - try { - output.writeInt(files.size()); - for (int i = 0; i < files.size(); i++) - output.writeString((String)files.elementAt(i)); - } finally { - output.close(); - } - directory.renameFile("deleteable.new", "deletable"); - } -} diff --git a/java/cvsvintage/IndexWriter_1.2_1.3_v1.java b/java/cvsvintage/IndexWriter_1.2_1.3_v1.java deleted file mode 100644 index 41e2a6d..0000000 --- a/java/cvsvintage/IndexWriter_1.2_1.3_v1.java +++ /dev/null @@ -1,402 +0,0 @@ -package org.apache.lucene.index; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache Lucene" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache Lucene", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.IOException; -import java.io.File; -import java.io.PrintStream; -import java.util.Vector; - -import org.apache.lucene.store.Directory; -import org.apache.lucene.store.RAMDirectory; -import org.apache.lucene.store.FSDirectory; -import org.apache.lucene.store.Lock; -import org.apache.lucene.store.InputStream; -import org.apache.lucene.store.OutputStream; -import org.apache.lucene.document.Document; -import org.apache.lucene.analysis.Analyzer; - -/** - An IndexWriter creates and maintains an index. - - The third argument to the constructor - determines whether a new index is created, or whether an existing index is - opened for the addition of new documents. - - In either case, documents are added with the addDocument method. When finished adding - documents, close should be called. - - If an index will not have more documents added for a while and optimal search - performance is desired, then the optimize - method should be called before the index is closed. - */ - -public final class IndexWriter { - private Directory directory; // where this index resides - private Analyzer analyzer; // how to analyze text - - private SegmentInfos segmentInfos = new SegmentInfos(); // the segments - private final Directory ramDirectory = new RAMDirectory(); // for temp segs - - /** Constructs an IndexWriter for the index in path. Text will - be analyzed with a. If create is true, then a - new, empty index will be created in d, replacing the index - already there, if any. */ - public IndexWriter(String path, Analyzer a, boolean create) - throws IOException { - this(FSDirectory.getDirectory(path, create), a, create); - } - - /** Constructs an IndexWriter for the index in path. Text will - be analyzed with a. If create is true, then a - new, empty index will be created in d, replacing the index - already there, if any. */ - public IndexWriter(File path, Analyzer a, boolean create) - throws IOException { - this(FSDirectory.getDirectory(path, create), a, create); - } - - /** Constructs an IndexWriter for the index in d. Text will be - analyzed with a. If create is true, then a new, - empty index will be created in d, replacing the index already - there, if any. */ - public IndexWriter(Directory d, Analyzer a, final boolean create) - throws IOException { - directory = d; - analyzer = a; - - Lock writeLock = directory.makeLock("write.lock"); - if (!writeLock.obtain()) // obtain write lock - throw new IOException("Index locked for write: " + writeLock); - - synchronized (directory) { // in- & inter-process sync - new Lock.With(directory.makeLock("commit.lock")) { - public Object doBody() throws IOException { - if (create) - segmentInfos.write(directory); - else - segmentInfos.read(directory); - return null; - } - }.run(); - } - } - - /** Flushes all changes to an index, closes all associated files, and closes - the directory that the index is stored in. */ - public final synchronized void close() throws IOException { - flushRamSegments(); - ramDirectory.close(); - directory.makeLock("write.lock").release(); // release write lock - directory.close(); - } - - /** Returns the number of documents currently in this index. */ - public final synchronized int docCount() { - int count = 0; - for (int i = 0; i < segmentInfos.size(); i++) { - SegmentInfo si = segmentInfos.info(i); - count += si.docCount; - } - return count; - } - - /** The maximum number of terms that will be indexed for a single field in a - document. This limits the amount of memory required for indexing, so that - collections with very large files will not crash the indexing process by - running out of memory. - -

By default, no more than 10,000 terms will be indexed for a field. */ - public int maxFieldLength = 10000; - - /** Adds a document to this index.*/ - public final void addDocument(Document doc) throws IOException { - DocumentWriter dw = - new DocumentWriter(ramDirectory, analyzer, maxFieldLength); - String segmentName = newSegmentName(); - dw.addDocument(segmentName, doc); - synchronized (this) { - segmentInfos.addElement(new SegmentInfo(segmentName, 1, ramDirectory)); - maybeMergeSegments(); - } - } - - private final synchronized String newSegmentName() { - return "_" + Integer.toString(segmentInfos.counter++, Character.MAX_RADIX); - } - - /** Determines how often segment indexes are merged by addDocument(). With - * smaller values, less RAM is used while indexing, and searches on - * unoptimized indexes are faster, but indexing speed is slower. With larger - * values more RAM is used while indexing and searches on unoptimized indexes - * are slower, but indexing is faster. Thus larger values (> 10) are best - * for batched index creation, and smaller values (< 10) for indexes that are - * interactively maintained. - * - *

This must never be less than 2. The default value is 10.*/ - public int mergeFactor = 10; - - /** Determines the largest number of documents ever merged by addDocument(). - * Small values (e.g., less than 10,000) are best for interactive indexing, - * as this limits the length of pauses while indexing to a few seconds. - * Larger values are best for batched indexing and speedier searches. - * - *

The default value is {@link Integer#MAX_VALUE}. */ - public int maxMergeDocs = Integer.MAX_VALUE; - - /** If non-null, information about merges will be printed to this. */ - public PrintStream infoStream = null; - - /** Merges all segments together into a single segment, optimizing an index - for search. */ - public final synchronized void optimize() throws IOException { - flushRamSegments(); - while (segmentInfos.size() > 1 || - (segmentInfos.size() == 1 && - (SegmentReader.hasDeletions(segmentInfos.info(0)) || - segmentInfos.info(0).dir != directory))) { - int minSegment = segmentInfos.size() - mergeFactor; - mergeSegments(minSegment < 0 ? 0 : minSegment); - } - } - - /** Merges all segments from an array of indexes into this index. - * - *

This may be used to parallelize batch indexing. A large document - * collection can be broken into sub-collections. Each sub-collection can be - * indexed in parallel, on a different thread, process or machine. The - * complete index can then be created by merging sub-collection indexes - * with this method. - * - *

After this completes, the index is optimized. */ - public final synchronized void addIndexes(Directory[] dirs) - throws IOException { - optimize(); // start with zero or 1 seg - int minSegment = segmentInfos.size(); - int segmentsAddedSinceMerge = 0; - for (int i = 0; i < dirs.length; i++) { - SegmentInfos sis = new SegmentInfos(); // read infos from dir - sis.read(dirs[i]); - for (int j = 0; j < sis.size(); j++) { - segmentInfos.addElement(sis.info(j)); // add each info - - // merge whenever mergeFactor segments have been added - if (++segmentsAddedSinceMerge == mergeFactor) { - mergeSegments(minSegment++, false); - segmentsAddedSinceMerge = 0; - } - } - } - optimize(); // final cleanup - } - - /** Merges all RAM-resident segments. */ - private final void flushRamSegments() throws IOException { - int minSegment = segmentInfos.size()-1; - int docCount = 0; - while (minSegment >= 0 && - (segmentInfos.info(minSegment)).dir == ramDirectory) { - docCount += segmentInfos.info(minSegment).docCount; - minSegment--; - } - if (minSegment < 0 || // add one FS segment? - (docCount + segmentInfos.info(minSegment).docCount) > mergeFactor || - !(segmentInfos.info(segmentInfos.size()-1).dir == ramDirectory)) - minSegment++; - if (minSegment >= segmentInfos.size()) - return; // none to merge - mergeSegments(minSegment); - } - - /** Incremental segment merger. */ - private final void maybeMergeSegments() throws IOException { - long targetMergeDocs = mergeFactor; - while (targetMergeDocs <= maxMergeDocs) { - // find segments smaller than current target size - int minSegment = segmentInfos.size(); - int mergeDocs = 0; - while (--minSegment >= 0) { - SegmentInfo si = segmentInfos.info(minSegment); - if (si.docCount >= targetMergeDocs) - break; - mergeDocs += si.docCount; - } - - if (mergeDocs >= targetMergeDocs) // found a merge to do - mergeSegments(minSegment+1); - else - break; - - targetMergeDocs *= mergeFactor; // increase target size - } - } - - /** Pops segments off of segmentInfos stack down to minSegment, merges them, - and pushes the merged index onto the top of the segmentInfos stack. */ - private final void mergeSegments(int minSegment) throws IOException { - mergeSegments(minSegment, true); - } - - /** Pops segments off of segmentInfos stack down to minSegment, merges them, - and pushes the merged index onto the top of the segmentInfos stack. */ - private final void mergeSegments(int minSegment, boolean delete) - throws IOException { - String mergedName = newSegmentName(); - int mergedDocCount = 0; - if (infoStream != null) infoStream.print("merging segments"); - SegmentMerger merger = new SegmentMerger(directory, mergedName); - final Vector segmentsToDelete = new Vector(); - for (int i = minSegment; i < segmentInfos.size(); i++) { - SegmentInfo si = segmentInfos.info(i); - if (infoStream != null) - infoStream.print(" " + si.name + " (" + si.docCount + " docs)"); - SegmentReader reader = new SegmentReader(si); - merger.add(reader); - if (delete) - segmentsToDelete.addElement(reader); // queue for deletion - mergedDocCount += si.docCount; - } - if (infoStream != null) { - infoStream.println(); - infoStream.println(" into "+mergedName+" ("+mergedDocCount+" docs)"); - } - merger.merge(); - - segmentInfos.setSize(minSegment); // pop old infos & add new - segmentInfos.addElement(new SegmentInfo(mergedName, mergedDocCount, - directory)); - - synchronized (directory) { // in- & inter-process sync - new Lock.With(directory.makeLock("commit.lock")) { - public Object doBody() throws IOException { - segmentInfos.write(directory); // commit before deleting - deleteSegments(segmentsToDelete); // delete now-unused segments - return null; - } - }.run(); - } - } - - /* Some operating systems (e.g. Windows) don't permit a file to be deleted - while it is opened for read (e.g. by another process or thread). So we - assume that when a delete fails it is because the file is open in another - process, and queue the file for subsequent deletion. */ - - private final void deleteSegments(Vector segments) throws IOException { - Vector deletable = new Vector(); - - deleteFiles(readDeleteableFiles(), deletable); // try to delete deleteable - - for (int i = 0; i < segments.size(); i++) { - SegmentReader reader = (SegmentReader)segments.elementAt(i); - if (reader.directory == this.directory) - deleteFiles(reader.files(), deletable); // try to delete our files - else - deleteFiles(reader.files(), reader.directory); // delete, eg, RAM files - } - - writeDeleteableFiles(deletable); // note files we can't delete - } - - private final void deleteFiles(Vector files, Directory directory) - throws IOException { - for (int i = 0; i < files.size(); i++) - directory.deleteFile((String)files.elementAt(i)); - } - - private final void deleteFiles(Vector files, Vector deletable) - throws IOException { - for (int i = 0; i < files.size(); i++) { - String file = (String)files.elementAt(i); - try { - directory.deleteFile(file); // try to delete each file - } catch (IOException e) { // if delete fails - if (directory.fileExists(file)) { - if (infoStream != null) - infoStream.println(e.getMessage() + "; Will re-try later."); - deletable.addElement(file); // add to deletable - } - } - } - } - - private final Vector readDeleteableFiles() throws IOException { - Vector result = new Vector(); - if (!directory.fileExists("deletable")) - return result; - - InputStream input = directory.openFile("deletable"); - try { - for (int i = input.readInt(); i > 0; i--) // read file names - result.addElement(input.readString()); - } finally { - input.close(); - } - return result; - } - - private final void writeDeleteableFiles(Vector files) throws IOException { - OutputStream output = directory.createFile("deleteable.new"); - try { - output.writeInt(files.size()); - for (int i = 0; i < files.size(); i++) - output.writeString((String)files.elementAt(i)); - } finally { - output.close(); - } - directory.renameFile("deleteable.new", "deletable"); - } -} diff --git a/java/cvsvintage/Install_1.9_1.10_v0.java b/java/cvsvintage/Install_1.9_1.10_v0.java deleted file mode 100644 index 8637100..0000000 --- a/java/cvsvintage/Install_1.9_1.10_v0.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Install.java - Main class of the installer - * - * Originally written by Slava Pestov for the jEdit installer project. This work - * has been placed into the public domain. You may use this work in any way and - * for any purpose you wish. - * - * THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND, NOT EVEN THE - * IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, ASSUMES - * _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, - * OR REDISTRIBUTION OF THIS SOFTWARE. - */ - -package installer; - -import javax.swing.plaf.metal.MetalLookAndFeel; -import java.io.*; -import java.util.Properties; - -public class Install -{ - public static void main(String[] args) - { - String javaVersion = System.getProperty("java.version"); - if(javaVersion.compareTo("1.3") < 0) - { - System.err.println("You are running Java version " - + javaVersion + "."); - System.err.println("This installer requires Java 1.3 or later."); - System.exit(1); - } - - if(args.length == 0) - { - MetalLookAndFeel.setCurrentTheme(new JEditMetalTheme()); - new SwingInstall(); - } - else if(args.length == 1 && args[0].equals("text")) - new ConsoleInstall(); - else if(args.length >= 2 && args[0].equals("auto")) - { - new NonInteractiveInstall(args); - } - else - { - System.err.println("Usage:"); - System.err.println("java -jar "); - System.err.println("java -jar text"); - System.err.println("java -jar auto" - + " [unix-script=

] [unix-man=]"); - System.err.println("text parameter starts installer in text-only mode."); - System.err.println("auto parameter starts installer in non-interactive mode."); - } - } - - public Install() - { - props = new Properties(); - try - { - InputStream in = getClass().getResourceAsStream("install.props"); - props.load(in); - in.close(); - } - catch(IOException io) - { - System.err.println("Error loading 'install.props':"); - io.printStackTrace(); - } - - buf = new byte[32768]; - } - - public String getProperty(String name) - { - return props.getProperty(name); - } - - public int getIntegerProperty(String name) - { - try - { - return Integer.parseInt(props.getProperty(name)); - } - catch(Exception e) - { - return -1; - } - } - - public void copy(InputStream in, String outfile, Progress progress) - throws IOException - { - File outFile = new File(outfile); - - OperatingSystem.getOperatingSystem().mkdirs(outFile.getParent()); - - BufferedOutputStream out = new BufferedOutputStream( - new FileOutputStream(outFile)); - - int count; - - for(;;) - { - count = in.read(buf,0,Math.min(in.available(),buf.length)); - if(count == -1 || count == 0) - break; - - out.write(buf,0,count); - if(progress != null) - progress.advance(count); - } - - //in.close(); - out.close(); - } - - // private members - private Properties props; - private byte[] buf; -} diff --git a/java/cvsvintage/Install_1.9_1.10_v1.java b/java/cvsvintage/Install_1.9_1.10_v1.java deleted file mode 100644 index 740258f..0000000 --- a/java/cvsvintage/Install_1.9_1.10_v1.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Install.java - Main class of the installer - * - * Originally written by Slava Pestov for the jEdit installer project. This work - * has been placed into the public domain. You may use this work in any way and - * for any purpose you wish. - * - * THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND, NOT EVEN THE - * IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, ASSUMES - * _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, - * OR REDISTRIBUTION OF THIS SOFTWARE. - */ - -package installer; - -import javax.swing.plaf.metal.MetalLookAndFeel; -import java.io.*; -import java.util.Properties; - -public class Install -{ - public static void main(String[] args) - { - String javaVersion = System.getProperty("java.version"); - if(javaVersion.compareTo("1.3") < 0) - { - System.err.println("You are running Java version " - + javaVersion + "."); - System.err.println("This installer requires Java 1.3 or later."); - System.exit(1); - } - - if(args.length == 0) - { - MetalLookAndFeel.setCurrentTheme(new JEditMetalTheme()); - new SwingInstall(); - } - else if(args.length == 1 && args[0].equals("text")) - new ConsoleInstall(); - else if(args.length >= 2 && args[0].equals("auto")) - { - new NonInteractiveInstall(args); - } - else - { - System.err.println("Usage:"); - System.err.println("java -jar "); - System.err.println("java -jar text"); - System.err.println("java -jar auto" - + " [unix-script=] [unix-man=]"); - System.err.println("text parameter starts installer in text-only mode."); - System.err.println("auto parameter starts installer in non-interactive mode."); - } - } - - public Install() - { - props = new Properties(); - try - { - InputStream in = getClass().getResourceAsStream("/installer/install.props"); - props.load(in); - in.close(); - } - catch(IOException io) - { - System.err.println("Error loading 'install.props':"); - io.printStackTrace(); - } - - buf = new byte[32768]; - } - - public String getProperty(String name) - { - return props.getProperty(name); - } - - public int getIntegerProperty(String name) - { - try - { - return Integer.parseInt(props.getProperty(name)); - } - catch(Exception e) - { - return -1; - } - } - - public void copy(InputStream in, String outfile, Progress progress) - throws IOException - { - File outFile = new File(outfile); - - OperatingSystem.getOperatingSystem().mkdirs(outFile.getParent()); - - BufferedOutputStream out = new BufferedOutputStream( - new FileOutputStream(outFile)); - - int count; - - for(;;) - { - count = in.read(buf,0,Math.min(in.available(),buf.length)); - if(count == -1 || count == 0) - break; - - out.write(buf,0,count); - if(progress != null) - progress.advance(count); - } - - //in.close(); - out.close(); - } - - // private members - private Properties props; - private byte[] buf; -} diff --git a/java/cvsvintage/IntrospectionUtils_1.1_1.2_v0.java b/java/cvsvintage/IntrospectionUtils_1.1_1.2_v0.java deleted file mode 100644 index 3c04cfc..0000000 --- a/java/cvsvintage/IntrospectionUtils_1.1_1.2_v0.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * ==================================================================== - * - * The Apache Software License, Version 1.1 - * - * Copyright (c) 1999 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, if - * any, must include the following acknowlegement: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowlegement may appear in the software itself, - * if and wherever such third-party acknowlegements normally appear. - * - * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software - * Foundation" must not be used to endorse or promote products derived - * from this software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache" - * nor may "Apache" appear in their names without prior written - * permission of the Apache Group. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - * [Additional notices, if required by prior licensing conditions] - * - */ - - -package org.apache.tomcat.util; -import java.lang.reflect.*; - -/** - * Utils for introspection and reflection - */ -public final class IntrospectionUtils { - - /** Test if the interceptor implements a particular - * method - */ - public static boolean hasHook( Object obj, String methodN ) { - try { - Method myMethods[]=obj.getClass().getMethods(); - for( int i=0; i< myMethods.length; i++ ) { - if( methodN.equals ( myMethods[i].getName() )) { - // check if it's overriden - Class declaring=myMethods[i].getDeclaringClass(); - Class parentOfDeclaring=declaring.getSuperclass(); - // this works only if the base class doesn't extend - // another class. - - // if the method is declared in a top level class - // like BaseInterceptor parent is Object, otherwise - // parent is BaseInterceptor or an intermediate class - if( ! "java.jang.Object". - equals(parentOfDeclaring.getName() )) { - return true; - } - } - } - } catch ( Exception ex ) { - ex.printStackTrace(); - } - return false; - } - - -} diff --git a/java/cvsvintage/IntrospectionUtils_1.1_1.2_v1.java b/java/cvsvintage/IntrospectionUtils_1.1_1.2_v1.java deleted file mode 100644 index e8d30fd..0000000 --- a/java/cvsvintage/IntrospectionUtils_1.1_1.2_v1.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * ==================================================================== - * - * The Apache Software License, Version 1.1 - * - * Copyright (c) 1999 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, if - * any, must include the following acknowlegement: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowlegement may appear in the software itself, - * if and wherever such third-party acknowlegements normally appear. - * - * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software - * Foundation" must not be used to endorse or promote products derived - * from this software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache" - * nor may "Apache" appear in their names without prior written - * permission of the Apache Group. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - * [Additional notices, if required by prior licensing conditions] - * - */ - - -package org.apache.tomcat.util; -import java.lang.reflect.*; - -/** - * Utils for introspection and reflection - */ -public final class IntrospectionUtils { - - /** Test if the interceptor implements a particular - * method - */ - public static boolean hasHook( Object obj, String methodN ) { - try { - Method myMethods[]=obj.getClass().getMethods(); - for( int i=0; i< myMethods.length; i++ ) { - if( methodN.equals ( myMethods[i].getName() )) { - // check if it's overriden - Class declaring=myMethods[i].getDeclaringClass(); - Class parentOfDeclaring=declaring.getSuperclass(); - // this works only if the base class doesn't extend - // another class. - - // if the method is declared in a top level class - // like BaseInterceptor parent is Object, otherwise - // parent is BaseInterceptor or an intermediate class - if( ! "java.lang.Object". - equals(parentOfDeclaring.getName() )) { - return true; - } - } - } - } catch ( Exception ex ) { - ex.printStackTrace(); - } - return false; - } - - -} diff --git a/java/cvsvintage/JacORBPRODelegate_1.1_1.2_v0.java b/java/cvsvintage/JacORBPRODelegate_1.1_1.2_v0.java deleted file mode 100644 index a62a272..0000000 --- a/java/cvsvintage/JacORBPRODelegate_1.1_1.2_v0.java +++ /dev/null @@ -1,80 +0,0 @@ -/** - * JOnAS: Java(TM) Open Application Server - * Copyright (C) 2004 Bull S.A. - * Contact: jonas-team@objectweb.org - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - * - * -------------------------------------------------------------------------- - * $Id: JacORBPRODelegate.java,v 1.1 2004-12-13 16:24:13 benoitf Exp $ - * -------------------------------------------------------------------------- - */ -package org.objectweb.carol.rmi.multi; - -import java.rmi.Remote; -import java.rmi.RemoteException; - -import javax.rmi.CORBA.Tie; -import javax.rmi.CORBA.Util; - -import org.objectweb.carol.jndi.spi.JacORBIIOPContext; -import org.objectweb.carol.util.configuration.TraceCarol; - -import com.sun.corba.se.internal.javax.rmi.PortableRemoteObject; - -/** - * TODO : should extends non com.sun classes. - * For example an OpenOrb class or implements our own Class, or use Classpath project - * It seems to be javax.rmi.CORBA.PortableRemoteObjectDelegateImpl class - * @author Florent Benoit - */ -public class JacORBPRODelegate extends PortableRemoteObject { - - /** - * Makes a server object ready to receive remote calls. Note that subclasses - * of PortableRemoteObject do not need to call this method, as it is called - * by the constructor. - * @param obj the server object to export. - * @exception RemoteException if export fails. - */ - public void exportObject(Remote obj) throws RemoteException { - - // For JacORB, we need first to unexport object as it is not associated - // to an ORB - try { - unexportObject(obj); - } catch (Exception eee) { - TraceCarol.debugExportCarol("JacORBPRODelegate :exportObject() unexport = " + eee); - } - - /* Now export it */ - try { - super.exportObject(obj); - } catch (Exception ee) { - TraceCarol.debugExportCarol("JacORBPRODelegate: exportObject() export:" + ee); - } - - Tie theTie = Util.getTie(obj); - - // Then connect it to the ORB - if (theTie != null) { - theTie.orb(JacORBIIOPContext.getOrb()); - } - - - - } -} diff --git a/java/cvsvintage/JacORBPRODelegate_1.1_1.2_v1.java b/java/cvsvintage/JacORBPRODelegate_1.1_1.2_v1.java deleted file mode 100644 index 3e3d0de..0000000 --- a/java/cvsvintage/JacORBPRODelegate_1.1_1.2_v1.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * JOnAS: Java(TM) Open Application Server - * Copyright (C) 2004 Bull S.A. - * Contact: jonas-team@objectweb.org - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - * - * -------------------------------------------------------------------------- - * $Id: JacORBPRODelegate.java,v 1.2 2005-01-10 09:31:55 benoitf Exp $ - * -------------------------------------------------------------------------- - */ -package org.objectweb.carol.rmi.multi; - -import com.sun.corba.se.internal.javax.rmi.PortableRemoteObject; - -/** - * TODO : should extends non com.sun classes. - * For example an OpenOrb class or implements our own Class, or use Classpath project - * It seems to be javax.rmi.CORBA.PortableRemoteObjectDelegateImpl class - * @author Florent Benoit - */ -public class JacORBPRODelegate extends PortableRemoteObject { - - -} diff --git a/java/cvsvintage/MetricsInterceptor_1.18_1.19_v0.java b/java/cvsvintage/MetricsInterceptor_1.18_1.19_v0.java deleted file mode 100644 index 09a48a4..0000000 --- a/java/cvsvintage/MetricsInterceptor_1.18_1.19_v0.java +++ /dev/null @@ -1,333 +0,0 @@ -/* - * JBoss, the OpenSource J2EE webOS - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package org.jboss.ejb.plugins; - -import java.lang.reflect.Method; -import java.security.Principal; -import java.util.Map; -import java.util.List; -import java.util.ArrayList; - -import javax.transaction.Transaction; -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.jms.DeliveryMode; -import javax.jms.Topic; -import javax.jms.TopicPublisher; -import javax.jms.TopicSession; -import javax.jms.TopicConnection; -import javax.jms.TopicConnectionFactory; -import javax.jms.Message; -import javax.jms.Session; -import javax.jms.Connection; -import javax.jms.JMSException; - -import org.jboss.ejb.Container; -import org.jboss.invocation.Invocation; -import org.jboss.logging.Logger; -import org.jboss.monitor.MetricsConstants; - -/** - * MetricsInterceptor collects data from the bean invocation call and publishes - * them on a JMS topic (bound to topic/metrics in the name service). - *

- * - * @since jBoss 2.0 - * - * @author Juha Lindfors - */ -public class MetricsInterceptor extends AbstractInterceptor - implements MetricsConstants -{ - /** - * The name of the application to which this interceptor belongs. - */ - private String applicationName = ""; - - /** - * Bean name in the container. - */ - private String beanName = ""; - - /** - * Publisher thread. - */ - private Thread publisher; - - /** - * Message queue for the outgoing JMS messages. This list is accessed - * by the interceptor when adding new messages, and by the publisher - * thread when copying and clearing the contents of the queue. The list - * must be locked for access and locks should be kept down to minimum - * as they degrade the interceptor stack performance. - */ - private List msgQueue = new ArrayList(2000); - - /** - * Starts the JMS publisher thread. - */ - public void create() - { - applicationName = getContainer().getEjbModule().getName(); - beanName = getContainer().getBeanMetaData().getJndiName(); - publisher = new Thread(new Publisher()); - publisher.setName("Metrics Publisher Thread for " + beanName + "."); - publisher.setDaemon(true); - publisher.start(); - } - - /** - * Kills the publisher thread. - */ - public void destroy() - { - publisher.interrupt(); - } - - public Object invoke(Invocation invocation) throws Exception - { - long begin = System.currentTimeMillis(); - try - { - return getNext().invoke(invocation); - } - finally - { - if(invocation.getMethod() != null) - { - addEntry(invocation, begin, System.currentTimeMillis()); - } - } - } - - /** - * Store the required information from this invocation: principal, - * transaction, method, time. - * - * @param begin invocation begin time in ms - * @param end invocation end time in ms - */ - private final void addEntry(Invocation invocation, long begin, long end) - { - /* this gets called by the interceptor */ - Transaction tx = invocation.getTransaction(); - Principal princ = invocation.getPrincipal(); - Method method = invocation.getMethod(); - Entry start = new Entry(princ, method, tx, begin, "START"); - Entry stop = new Entry(princ, method, tx, end, "STOP"); - - // add both entries, order is guaranteed, synchronized to prevent - // publisher from touching the queue while working on it - synchronized(msgQueue) - { - // Two entries for now, one should suffice but requires changes in - // the client. - msgQueue.add(start); - msgQueue.add(stop); - } - } - - private Message createMessage( - Session session, - String principal, - int txID, - String method, - String checkpoint, - long time) - { - try - { - Message message = session.createMessage(); - - message.setJMSType(INVOCATION_METRICS); - message.setStringProperty(CHECKPOINT, checkpoint); - message.setStringProperty(BEAN, beanName); - message.setObjectProperty(METHOD, method); - message.setLongProperty(TIME, time); - - if (txID != -1) - { - message.setStringProperty("ID", String.valueOf(txID)); - } - - if (principal != null) - { - message.setStringProperty("PRINCIPAL", principal); - } - - return message; - } - catch (Exception e) - { - // catch JMSExceptions, tx.SystemExceptions, and NPE's - // don't want to bother the container even if the metrics fail. - return null; - } - } - - /** - * JMS Publisher thread implementation. - */ - private class Publisher implements Runnable { - - /** Thread keep-alive field. */ - private boolean running = true; - /** Thread sleep delay. */ - private int delay = 2000; - /** JMS Connection */ - private TopicConnection connection = null; - - /** - * Thread implementation.

- * - * When started, looks up a topic connection factory from the name - * service, and attempts to create a publisher to topic/metrics - * topic.

- * - * While alive, locks the msgQueue every two seconds to make a - * copy of the contents and then clear it.

- * - * Interrupting this thread will kill it. - * - * @see #msgQueue - * @see java.lang.Thread#interrupt() - */ - public void run() - { - try - { - final boolean IS_TRANSACTED = true; - final int ACKNOWLEDGE_MODE = Session.DUPS_OK_ACKNOWLEDGE; - - // lookup the connection factory and topic and create a JMS session - Context namingContext = new InitialContext(); - TopicConnectionFactory fact = (TopicConnectionFactory)namingContext.lookup("TopicConnectionFactory"); - - connection = fact.createTopicConnection(); - - Topic topic = (Topic)namingContext.lookup("topic/metrics"); - TopicSession session = connection.createTopicSession(IS_TRANSACTED, ACKNOWLEDGE_MODE); - TopicPublisher pub = session.createPublisher(topic); - - pub.setDeliveryMode(DeliveryMode.NON_PERSISTENT); - pub.setPriority(Message.DEFAULT_PRIORITY); - pub.setTimeToLive(Message.DEFAULT_TIME_TO_LIVE); - - // start the JMS connection - connection.start(); - - // copy the message queue every x seconds, and publish the messages - while (running) - { - Object[] array; - long sleepTime = delay; - - try - { - Thread.sleep(sleepTime); - - // measure message processing cost and try to deal - // with congestion - long begin = System.currentTimeMillis(); - - // synchronized during the copy... the interceptor will - // have to wait til done - synchronized(msgQueue) - { - array = msgQueue.toArray(); - msgQueue.clear(); - } - - // publish the messages - for (int i = 0; i < array.length; ++i) - { - Message msg = createMessage(session, - ((Entry)array[i]).principal, - ((Entry)array[i]).id, - ((Entry)array[i]).method, - ((Entry)array[i]).checkpoint, - ((Entry)array[i]).time - ); - - pub.publish(msg); - } - - // try to deal with congestion a little better, alot of - // small messages fast will kill JBossMQ performance, this is - // a temp fix to group many messages into one operation - try - { - session.commit(); - } catch(Exception e) {} - - // stop the clock and reduce the work time from our - // resting time - long end = System.currentTimeMillis(); - - sleepTime = delay - (end - begin); - } - catch (InterruptedException e) - { - // kill this thread - running = false; - } - } - - // thread cleanup - connection.close(); - - } - catch (NamingException e) - { - log.warn(e); - } - catch (JMSException e) - { - log.warn(e); - } - } - } - - /** - * Wrapper class for message queue entries. - * - * @see #msgQueue - */ - private final class Entry - { - int id = -1; - long time; - String principal; - String checkpoint; - String method; - - public Entry( - Principal principal, - Method method, - Transaction tx, - long time, - String checkpoint) - { - if(principal != null) - { - this.principal = principal.getName(); - } - - this.method = method.getName(); - - if(tx != null) - { - this.id = tx.hashCode(); - } - - this.time = time; - this.checkpoint = checkpoint; - } - } -} - diff --git a/java/cvsvintage/MetricsInterceptor_1.18_1.19_v1.java b/java/cvsvintage/MetricsInterceptor_1.18_1.19_v1.java deleted file mode 100644 index dfaba41..0000000 --- a/java/cvsvintage/MetricsInterceptor_1.18_1.19_v1.java +++ /dev/null @@ -1,333 +0,0 @@ -/* - * JBoss, the OpenSource J2EE webOS - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package org.jboss.ejb.plugins; - -import java.lang.reflect.Method; -import java.security.Principal; -import java.util.Map; -import java.util.List; -import java.util.ArrayList; - -import javax.transaction.Transaction; -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.jms.DeliveryMode; -import javax.jms.Topic; -import javax.jms.TopicPublisher; -import javax.jms.TopicSession; -import javax.jms.TopicConnection; -import javax.jms.TopicConnectionFactory; -import javax.jms.Message; -import javax.jms.Session; -import javax.jms.Connection; -import javax.jms.JMSException; - -import org.jboss.ejb.Container; -import org.jboss.invocation.Invocation; -import org.jboss.logging.Logger; -import org.jboss.monitor.MetricsConstants; - -/** - * MetricsInterceptor collects data from the bean invocation call and publishes - * them on a JMS topic (bound to topic/metrics in the name service). - *

- * - * @since jBoss 2.0 - * - * @author Juha Lindfors - */ -public class MetricsInterceptor extends AbstractInterceptor - implements MetricsConstants -{ - /** - * The name of the application to which this interceptor belongs. - */ - private String applicationName = ""; - - /** - * Bean name in the container. - */ - private String beanName = ""; - - /** - * Publisher thread. - */ - private Thread publisher; - - /** - * Message queue for the outgoing JMS messages. This list is accessed - * by the interceptor when adding new messages, and by the publisher - * thread when copying and clearing the contents of the queue. The list - * must be locked for access and locks should be kept down to minimum - * as they degrade the interceptor stack performance. - */ - private List msgQueue = new ArrayList(2000); - - /** - * Starts the JMS publisher thread. - */ - public void create() - { - applicationName = getContainer().getEjbModule().getName(); - beanName = getContainer().getBeanMetaData().getJndiName(); - publisher = new Thread(new Publisher()); - publisher.setName("Metrics Publisher Thread for " + beanName + "."); - publisher.setDaemon(true); - publisher.start(); - } - - /** - * Kills the publisher thread. - */ - public void destroy() - { - publisher.interrupt(); - } - - public Object invoke(Invocation invocation) throws Exception - { - long begin = System.currentTimeMillis(); - try - { - return getNext().invoke(invocation); - } - finally - { - if(invocation.getMethod() != null) - { - addEntry(invocation, begin, System.currentTimeMillis()); - } - } - } - - /** - * Store the required information from this invocation: principal, - * transaction, method, time. - * - * @param begin invocation begin time in ms - * @param end invocation end time in ms - */ - private final void addEntry(Invocation invocation, long begin, long end) - { - /* this gets called by the interceptor */ - Transaction tx = invocation.getTransaction(); - Principal princ = invocation.getPrincipal(); - Method method = invocation.getMethod(); - Entry start = new Entry(princ, method, tx, begin, "START"); - Entry stop = new Entry(princ, method, tx, end, "STOP"); - - // add both entries, order is guaranteed, synchronized to prevent - // publisher from touching the queue while working on it - synchronized(msgQueue) - { - // Two entries for now, one should suffice but requires changes in - // the client. - msgQueue.add(start); - msgQueue.add(stop); - } - } - - private Message createMessage( - Session session, - String principal, - int txID, - String method, - String checkpoint, - long time) - { - try - { - Message message = session.createMessage(); - - message.setJMSType(INVOCATION_METRICS); - message.setStringProperty(CHECKPOINT, checkpoint); - message.setStringProperty(BEAN, beanName); - message.setObjectProperty(METHOD, method); - message.setLongProperty(TIME, time); - - if (txID != -1) - { - message.setStringProperty("ID", String.valueOf(txID)); - } - - if (principal != null) - { - message.setStringProperty("PRINCIPAL", principal); - } - - return message; - } - catch (Exception e) - { - // catch JMSExceptions, tx.SystemExceptions, and NPE's - // don't want to bother the container even if the metrics fail. - return null; - } - } - - /** - * JMS Publisher thread implementation. - */ - private class Publisher implements Runnable { - - /** Thread keep-alive field. */ - private boolean running = true; - /** Thread sleep delay. */ - private int delay = 2000; - /** JMS Connection */ - private TopicConnection connection = null; - - /** - * Thread implementation.

- * - * When started, looks up a topic connection factory from the name - * service, and attempts to create a publisher to topic/metrics - * topic.

- * - * While alive, locks the msgQueue every two seconds to make a - * copy of the contents and then clear it.

- * - * Interrupting this thread will kill it. - * - * @see #msgQueue - * @see java.lang.Thread#interrupt() - */ - public void run() - { - try - { - final boolean IS_TRANSACTED = true; - final int ACKNOWLEDGE_MODE = Session.DUPS_OK_ACKNOWLEDGE; - - // lookup the connection factory and topic and create a JMS session - Context namingContext = new InitialContext(); - TopicConnectionFactory fact = (TopicConnectionFactory)namingContext.lookup("ConnectionFactory"); - - connection = fact.createTopicConnection(); - - Topic topic = (Topic)namingContext.lookup("topic/metrics"); - TopicSession session = connection.createTopicSession(IS_TRANSACTED, ACKNOWLEDGE_MODE); - TopicPublisher pub = session.createPublisher(topic); - - pub.setDeliveryMode(DeliveryMode.NON_PERSISTENT); - pub.setPriority(Message.DEFAULT_PRIORITY); - pub.setTimeToLive(Message.DEFAULT_TIME_TO_LIVE); - - // start the JMS connection - connection.start(); - - // copy the message queue every x seconds, and publish the messages - while (running) - { - Object[] array; - long sleepTime = delay; - - try - { - Thread.sleep(sleepTime); - - // measure message processing cost and try to deal - // with congestion - long begin = System.currentTimeMillis(); - - // synchronized during the copy... the interceptor will - // have to wait til done - synchronized(msgQueue) - { - array = msgQueue.toArray(); - msgQueue.clear(); - } - - // publish the messages - for (int i = 0; i < array.length; ++i) - { - Message msg = createMessage(session, - ((Entry)array[i]).principal, - ((Entry)array[i]).id, - ((Entry)array[i]).method, - ((Entry)array[i]).checkpoint, - ((Entry)array[i]).time - ); - - pub.publish(msg); - } - - // try to deal with congestion a little better, alot of - // small messages fast will kill JBossMQ performance, this is - // a temp fix to group many messages into one operation - try - { - session.commit(); - } catch(Exception e) {} - - // stop the clock and reduce the work time from our - // resting time - long end = System.currentTimeMillis(); - - sleepTime = delay - (end - begin); - } - catch (InterruptedException e) - { - // kill this thread - running = false; - } - } - - // thread cleanup - connection.close(); - - } - catch (NamingException e) - { - log.warn(e); - } - catch (JMSException e) - { - log.warn(e); - } - } - } - - /** - * Wrapper class for message queue entries. - * - * @see #msgQueue - */ - private final class Entry - { - int id = -1; - long time; - String principal; - String checkpoint; - String method; - - public Entry( - Principal principal, - Method method, - Transaction tx, - long time, - String checkpoint) - { - if(principal != null) - { - this.principal = principal.getName(); - } - - this.method = method.getName(); - - if(tx != null) - { - this.id = tx.hashCode(); - } - - this.time = time; - this.checkpoint = checkpoint; - } - } -} - diff --git a/java/cvsvintage/MirrorListHandler_1.2_1.3_v0.java b/java/cvsvintage/MirrorListHandler_1.2_1.3_v0.java deleted file mode 100644 index 7af3b66..0000000 --- a/java/cvsvintage/MirrorListHandler_1.2_1.3_v0.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * MirrorListHandler.java - XML handler for the mirrors list - * :tabSize=8:indentSize=8:noTabs=false: - * :folding=explicit:collapseFolds=1: - * - * Copyright (C) 2002 Kris Kopicki (parts copied from Slava Pestov :) ) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -package org.gjt.sp.jedit.pluginmgr; - -import java.io.*; -import java.util.*; - -import org.xml.sax.Attributes; -import org.xml.sax.InputSource; -import org.xml.sax.helpers.DefaultHandler; - -import org.gjt.sp.jedit.MiscUtilities; -import org.gjt.sp.util.Log; - -class MirrorListHandler extends DefaultHandler -{ - //{{{ Constructor - MirrorListHandler(MirrorList mirrors, String path) - { - this.mirrors = mirrors; - this.path = path; - stateStack = new Stack(); - - description = new StringBuffer(); - location = new StringBuffer(); - country = new StringBuffer(); - continent = new StringBuffer(); - } //}}} - - //{{{ resolveEntity() method - public InputSource resolveEntity(String publicId, String systemId) - { - return MiscUtilities.findEntity(systemId, "mirrors.dtd", - org.gjt.sp.jedit.options.PluginOptions.class); - } //}}} - - //{{{ characters() method - public void characters(char[] c, int off, int len) - { - String tag = peekElement(); - String text = new String(c, off, len); - - if(tag == "DESCRIPTION") - description.append(c, off, len); - else if(tag == "LOCATION") - location.append(c, off, len); - else if(tag == "COUNTRY") - country.append(c, off, len); - else if(tag == "CONTINENT") - continent.append(c, off, len); - } //}}} - - //{{{ startElement() method - public void startElement(String uri, String localName, - String tag, Attributes attrs) - { - tag = pushElement(tag); - - if(tag.equals("MIRROR")) - mirror = new MirrorList.Mirror(); - id = attrs.getValue("ID"); - } //}}} - - //{{{ endElement() method - public void endElement(String uri, String localName, String tag) - { - popElement(); - - if(tag.equals("MIRROR")) - { - mirror.id = id; - mirror.description = description.toString(); - mirror.location = location.toString(); - mirror.country = country.toString(); - mirror.continent = continent.toString(); - mirrors.add(mirror); - description.setLength(0); - location.setLength(0); - country.setLength(0); - continent.setLength(0); - } - } //}}} - - //{{{ startDocument() method - public void startDocument() - { - try - { - pushElement(null); - } - catch (Exception e) - { - e.printStackTrace(); - } - } //}}} - - //{{{ endDocument() method - public void endDocument() - { - mirrors.finished(); - } //}}} - - //{{{ Private members - - //{{{ Variables - private String id; - private StringBuffer description; - private StringBuffer location; - private StringBuffer country; - private StringBuffer continent; - - private MirrorList mirrors; - private MirrorList.Mirror mirror; - - private Stack stateStack; - private String path; - //}}} - - private String pushElement(String name) - { - name = (name == null) ? null : name.intern(); - - stateStack.push(name); - - return name; - } - - private String peekElement() - { - return (String) stateStack.peek(); - } - - private String popElement() - { - return (String) stateStack.pop(); - } - - //}}} -} diff --git a/java/cvsvintage/MirrorListHandler_1.2_1.3_v1.java b/java/cvsvintage/MirrorListHandler_1.2_1.3_v1.java deleted file mode 100644 index 38a038b..0000000 --- a/java/cvsvintage/MirrorListHandler_1.2_1.3_v1.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * MirrorListHandler.java - XML handler for the mirrors list - * :tabSize=8:indentSize=8:noTabs=false: - * :folding=explicit:collapseFolds=1: - * - * Copyright (C) 2002 Kris Kopicki (parts copied from Slava Pestov :) ) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -package org.gjt.sp.jedit.pluginmgr; - -import java.io.*; -import java.util.*; - -import org.xml.sax.Attributes; -import org.xml.sax.InputSource; -import org.xml.sax.helpers.DefaultHandler; - -import org.gjt.sp.jedit.MiscUtilities; -import org.gjt.sp.util.Log; - -class MirrorListHandler extends DefaultHandler -{ - //{{{ Constructor - MirrorListHandler(MirrorList mirrors, String path) - { - this.mirrors = mirrors; - this.path = path; - stateStack = new Stack(); - - description = new StringBuffer(); - location = new StringBuffer(); - country = new StringBuffer(); - continent = new StringBuffer(); - } //}}} - - //{{{ resolveEntity() method - public InputSource resolveEntity(String publicId, String systemId) - { - return MiscUtilities.findEntity(systemId, "mirrors.dtd", - org.gjt.sp.jedit.options.PluginOptions.class); - } //}}} - - //{{{ characters() method - public void characters(char[] c, int off, int len) - { - String tag = peekElement(); - String text = new String(c, off, len); - - if(tag == "DESCRIPTION") - description.append(c, off, len); - else if(tag == "LOCATION") - location.append(c, off, len); - else if(tag == "COUNTRY") - country.append(c, off, len); - else if(tag == "CONTINENT") - continent.append(c, off, len); - } //}}} - - //{{{ startElement() method - public void startElement(String uri, String localName, - String tag, Attributes attrs) - { - tag = pushElement(tag); - - if (tag.equals("MIRROR")) - { - mirror = new MirrorList.Mirror(); - id = attrs.getValue("ID"); - } - } //}}} - - //{{{ endElement() method - public void endElement(String uri, String localName, String tag) - { - popElement(); - - if(tag.equals("MIRROR")) - { - mirror.id = id; - mirror.description = description.toString(); - mirror.location = location.toString(); - mirror.country = country.toString(); - mirror.continent = continent.toString(); - mirrors.add(mirror); - description.setLength(0); - location.setLength(0); - country.setLength(0); - continent.setLength(0); - } - } //}}} - - //{{{ startDocument() method - public void startDocument() - { - try - { - pushElement(null); - } - catch (Exception e) - { - e.printStackTrace(); - } - } //}}} - - //{{{ endDocument() method - public void endDocument() - { - mirrors.finished(); - } //}}} - - //{{{ Private members - - //{{{ Variables - private String id; - private StringBuffer description; - private StringBuffer location; - private StringBuffer country; - private StringBuffer continent; - - private MirrorList mirrors; - private MirrorList.Mirror mirror; - - private Stack stateStack; - private String path; - //}}} - - private String pushElement(String name) - { - name = (name == null) ? null : name.intern(); - - stateStack.push(name); - - return name; - } - - private String peekElement() - { - return (String) stateStack.peek(); - } - - private String popElement() - { - return (String) stateStack.pop(); - } - - //}}} -} diff --git a/java/cvsvintage/RQueryUser_1.1_1.2_v0.java b/java/cvsvintage/RQueryUser_1.1_1.2_v0.java deleted file mode 100644 index 85d56fe..0000000 --- a/java/cvsvintage/RQueryUser_1.1_1.2_v0.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.tigris.scarab.om; - - -import org.apache.torque.om.UnsecurePersistent; - -/** - * You should add additional methods to this class to meet the - * application requirements. This class will only be generated as - * long as it does not already exist in the output directory. - */ -public class RQueryUser - extends org.tigris.scarab.om.BaseRQueryUser - implements UnsecurePersistent -{ -} diff --git a/java/cvsvintage/RQueryUser_1.1_1.2_v1.java b/java/cvsvintage/RQueryUser_1.1_1.2_v1.java deleted file mode 100644 index 25f8bef..0000000 --- a/java/cvsvintage/RQueryUser_1.1_1.2_v1.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.tigris.scarab.om; - - -import org.apache.torque.om.UnsecurePersistent; -import org.apache.torque.util.Criteria; - -import org.tigris.scarab.util.ScarabException; -import org.tigris.scarab.util.ScarabConstants; -import org.tigris.scarab.security.ScarabSecurity; -import org.tigris.scarab.security.SecurityFactory; - -/** - * You should add additional methods to this class to meet the - * application requirements. This class will only be generated as - * long as it does not already exist in the output directory. - */ -public class RQueryUser - extends org.tigris.scarab.om.BaseRQueryUser - implements UnsecurePersistent -{ - - /** - * Delete the subscription. - */ - public void delete(ScarabUser user, ScarabModule module) throws Exception - - { - ScarabSecurity security = SecurityFactory.getInstance(); - if (user.getUserId().equals(getUserId()) - || security.hasPermission(ScarabSecurity.ITEM__APPROVE, user, - module)) - { - Criteria c = new Criteria() - .add(RQueryUserPeer.USER_ID, getUserId()) - .add(RQueryUserPeer.QUERY_ID, getQueryId()); - RQueryUserPeer.doDelete(c); - } - else - { - throw new ScarabException(ScarabConstants.NO_PERMISSION_MESSAGE); - } - } - -} diff --git a/java/cvsvintage/SegmentTermDocs_1.6_1.7_v0.java b/java/cvsvintage/SegmentTermDocs_1.6_1.7_v0.java deleted file mode 100644 index 6c2d633..0000000 --- a/java/cvsvintage/SegmentTermDocs_1.6_1.7_v0.java +++ /dev/null @@ -1,231 +0,0 @@ -package org.apache.lucene.index; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache Lucene" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache Lucene", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.IOException; -import org.apache.lucene.util.BitVector; -import org.apache.lucene.store.InputStream; - -class SegmentTermDocs implements TermDocs { - protected SegmentReader parent; - private InputStream freqStream; - private int count; - private int df; - private BitVector deletedDocs; - int doc = 0; - int freq; - - private int skipInterval; - private int skipCount; - private InputStream skipStream; - private int skipDoc; - private long freqPointer; - private long proxPointer; - private long skipPointer; - private boolean haveSkipped; - - SegmentTermDocs(SegmentReader parent) - throws IOException { - this.parent = parent; - this.freqStream = (InputStream) parent.freqStream.clone(); - this.deletedDocs = parent.deletedDocs; - this.skipInterval = parent.tis.getSkipInterval(); - } - - public void seek(Term term) throws IOException { - TermInfo ti = parent.tis.get(term); - seek(ti); - } - - public void seek(TermEnum enum) throws IOException { - TermInfo ti; - if (enum instanceof SegmentTermEnum) // optimized case - ti = ((SegmentTermEnum) enum).termInfo(); - else // punt case - ti = parent.tis.get(enum.term()); - seek(ti); - } - - void seek(TermInfo ti) throws IOException { - count = 0; - if (ti == null) { - df = 0; - } else { - df = ti.docFreq; - doc = 0; - skipDoc = 0; - skipCount = 0; - freqPointer = ti.freqPointer; - proxPointer = ti.proxPointer; - skipPointer = freqPointer + ti.skipOffset; - freqStream.seek(freqPointer); - haveSkipped = false; - } - } - - public void close() throws IOException { - freqStream.close(); - } - - public final int doc() { return doc; } - public final int freq() { return freq; } - - protected void skippingDoc() throws IOException { - } - - public boolean next() throws IOException { - while (true) { - if (count == df) - return false; - - int docCode = freqStream.readVInt(); - doc += docCode >>> 1; // shift off low bit - if ((docCode & 1) != 0) // if low bit is set - freq = 1; // freq is one - else - freq = freqStream.readVInt(); // else read freq - - count++; - - if (deletedDocs == null || !deletedDocs.get(doc)) - break; - skippingDoc(); - } - return true; - } - - /** Optimized implementation. */ - public int read(final int[] docs, final int[] freqs) - throws IOException { - final int length = docs.length; - int i = 0; - while (i < length && count < df) { - - // manually inlined call to next() for speed - final int docCode = freqStream.readVInt(); - doc += docCode >>> 1; // shift off low bit - if ((docCode & 1) != 0) // if low bit is set - freq = 1; // freq is one - else - freq = freqStream.readVInt(); // else read freq - count++; - - if (deletedDocs == null || !deletedDocs.get(doc)) { - docs[i] = doc; - freqs[i] = freq; - ++i; - } - } - return i; - } - - /** Overridden by SegmentTermPositions to skip in prox stream. */ - protected void skipProx(long proxPointer) throws IOException {} - - /** Optimized implementation. */ - public boolean skipTo(int target) throws IOException { - if (df > skipInterval) { // optimized case - - if (skipStream == null) - skipStream = (InputStream) freqStream.clone(); // lazily clone - - if (!haveSkipped) { // lazily seek skip stream - skipStream.seek(skipPointer); - haveSkipped = true; - } - - // scan skip data - int lastSkipDoc = skipDoc; - long lastFreqPointer = freqStream.getFilePointer(); - long lastProxPointer = -1; - int numSkipped = -1 - (count % skipInterval); - - while (target > skipDoc) { - lastSkipDoc = skipDoc; - lastFreqPointer = freqPointer; - lastProxPointer = proxPointer; - if (skipDoc != 0 && skipDoc >= doc) - numSkipped += skipInterval; - - if ((count + numSkipped + skipInterval) > df) - break; // no more skips - - skipDoc += skipStream.readVInt(); - freqPointer += skipStream.readVInt(); - proxPointer += skipStream.readVInt(); - - skipCount++; - } - - // if we found something to skip, then skip it - if (lastFreqPointer > freqStream.getFilePointer()) { - freqStream.seek(lastFreqPointer); - skipProx(lastProxPointer); - - doc = lastSkipDoc; - count += numSkipped; - } - - } - - // done skipping, now just scan - do { - if (!next()) - return false; - } while (target > doc); - return true; - } - -} diff --git a/java/cvsvintage/SegmentTermDocs_1.6_1.7_v1.java b/java/cvsvintage/SegmentTermDocs_1.6_1.7_v1.java deleted file mode 100644 index edff5ca..0000000 --- a/java/cvsvintage/SegmentTermDocs_1.6_1.7_v1.java +++ /dev/null @@ -1,231 +0,0 @@ -package org.apache.lucene.index; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache Lucene" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache Lucene", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.IOException; -import org.apache.lucene.util.BitVector; -import org.apache.lucene.store.InputStream; - -class SegmentTermDocs implements TermDocs { - protected SegmentReader parent; - private InputStream freqStream; - private int count; - private int df; - private BitVector deletedDocs; - int doc = 0; - int freq; - - private int skipInterval; - private int skipCount; - private InputStream skipStream; - private int skipDoc; - private long freqPointer; - private long proxPointer; - private long skipPointer; - private boolean haveSkipped; - - SegmentTermDocs(SegmentReader parent) - throws IOException { - this.parent = parent; - this.freqStream = (InputStream) parent.freqStream.clone(); - this.deletedDocs = parent.deletedDocs; - this.skipInterval = parent.tis.getSkipInterval(); - } - - public void seek(Term term) throws IOException { - TermInfo ti = parent.tis.get(term); - seek(ti); - } - - public void seek(TermEnum enum) throws IOException { - TermInfo ti; - if (enum instanceof SegmentTermEnum) // optimized case - ti = ((SegmentTermEnum) enum).termInfo(); - else // punt case - ti = parent.tis.get(enum.term()); - seek(ti); - } - - void seek(TermInfo ti) throws IOException { - count = 0; - if (ti == null) { - df = 0; - } else { - df = ti.docFreq; - doc = 0; - skipDoc = 0; - skipCount = 0; - freqPointer = ti.freqPointer; - proxPointer = ti.proxPointer; - skipPointer = freqPointer + ti.skipOffset; - freqStream.seek(freqPointer); - haveSkipped = false; - } - } - - public void close() throws IOException { - freqStream.close(); - } - - public final int doc() { return doc; } - public final int freq() { return freq; } - - protected void skippingDoc() throws IOException { - } - - public boolean next() throws IOException { - while (true) { - if (count == df) - return false; - - int docCode = freqStream.readVInt(); - doc += docCode >>> 1; // shift off low bit - if ((docCode & 1) != 0) // if low bit is set - freq = 1; // freq is one - else - freq = freqStream.readVInt(); // else read freq - - count++; - - if (deletedDocs == null || !deletedDocs.get(doc)) - break; - skippingDoc(); - } - return true; - } - - /** Optimized implementation. */ - public int read(final int[] docs, final int[] freqs) - throws IOException { - final int length = docs.length; - int i = 0; - while (i < length && count < df) { - - // manually inlined call to next() for speed - final int docCode = freqStream.readVInt(); - doc += docCode >>> 1; // shift off low bit - if ((docCode & 1) != 0) // if low bit is set - freq = 1; // freq is one - else - freq = freqStream.readVInt(); // else read freq - count++; - - if (deletedDocs == null || !deletedDocs.get(doc)) { - docs[i] = doc; - freqs[i] = freq; - ++i; - } - } - return i; - } - - /** Overridden by SegmentTermPositions to skip in prox stream. */ - protected void skipProx(long proxPointer) throws IOException {} - - /** Optimized implementation. */ - public boolean skipTo(int target) throws IOException { - if (df > skipInterval) { // optimized case - - if (skipStream == null) - skipStream = (InputStream) freqStream.clone(); // lazily clone - - if (!haveSkipped) { // lazily seek skip stream - skipStream.seek(skipPointer); - haveSkipped = true; - } - - // scan skip data - int lastSkipDoc = skipDoc; - long lastFreqPointer = freqStream.getFilePointer(); - long lastProxPointer = -1; - int numSkipped = -1 - (count % skipInterval); - - while (target > skipDoc) { - lastSkipDoc = skipDoc; - lastFreqPointer = freqPointer; - lastProxPointer = proxPointer; - if (skipDoc != 0 && skipDoc >= doc) - numSkipped += skipInterval; - - if ((count + numSkipped + skipInterval) >= df) - break; // no more skips - - skipDoc += skipStream.readVInt(); - freqPointer += skipStream.readVInt(); - proxPointer += skipStream.readVInt(); - - skipCount++; - } - - // if we found something to skip, then skip it - if (lastFreqPointer > freqStream.getFilePointer()) { - freqStream.seek(lastFreqPointer); - skipProx(lastProxPointer); - - doc = lastSkipDoc; - count += numSkipped; - } - - } - - // done skipping, now just scan - do { - if (!next()) - return false; - } while (target > doc); - return true; - } - -} diff --git a/java/cvsvintage/Server_1.925_1.926_v0.java b/java/cvsvintage/Server_1.925_1.926_v0.java deleted file mode 100644 index 0916634..0000000 --- a/java/cvsvintage/Server_1.925_1.926_v0.java +++ /dev/null @@ -1,18150 +0,0 @@ -/* - * MegaMek - - * Copyright (C) 2000,2001,2002,2003,2004,2005 Ben Mazur (bmazur@sev.org) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -package megamek.server; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.UnknownHostException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.StringTokenizer; -import java.util.Vector; - -import megamek.*; -import megamek.common.*; -import megamek.common.actions.*; -import megamek.server.commands.*; -import megamek.common.net.*; -import megamek.common.options.*; -import megamek.common.util.BoardUtilities; -import megamek.common.util.StringUtil; -import megamek.common.verifier.EntityVerifier; -import megamek.common.verifier.TestEntity; -import megamek.common.verifier.TestMech; -import megamek.common.verifier.TestTank; -import megamek.common.TagInfo; -import megamek.common.preference.PreferenceManager; - -/** - * @author Ben Mazur - */ -public class Server implements Runnable { - // public final static String LEGAL_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.-"; - public final static String DEFAULT_BOARD = MapSettings.BOARD_SURPRISE; - private final static String VERIFIER_CONFIG_FILENAME = - "data/mechfiles/UnitVerifierOptions.xml"; - - // server setup - private String password; - private ServerSocket serverSocket; - private String motd; - - // game info - private Vector connections = new Vector(4); - private Vector connectionsPending = new Vector(4); - private Hashtable connectionIds = new Hashtable(); - - private int connectionCounter = 0; - private int entityCounter = 0; - - private IGame game = new Game(); - - private Vector vPhaseReport = new Vector(); - - private MapSettings mapSettings = new MapSettings(); - - // commands - private Hashtable commandsHash = new Hashtable(); - - // listens for and connects players - private Thread connector; - - // Track buildings that are affected by an entity's movement. - private Hashtable affectedBldgs = new Hashtable(); - - // Track Physical Action results, HACK to deal with opposing pushes - // canceling each other - private Vector physicalResults = new Vector(); - - private Vector terrainProcessors = new Vector(); - - /* Tracks entities which have been destroyed recently. Allows refactoring of the - * damage and kill logic from Server, where it is now, to the Entity subclasses eventually. - * This has not been implemented yet -- I am just starting to build the groundwork into Server. - * It isn't in the execution path and shouldn't cause any bugs */ - //Note from another coder - I have commented out your groundwork - //for now because it is using HashSet, which isn't available in - //Java 1.1 unless you import the collections classes. Since the - //Server class isn't using any other collecitons classes, there - //might be a reason we're avoiding them here...if not, feel free - //to add the import. - //private HashSet knownDeadEntities = new HashSet(); - - private static EntityVerifier entityVerifier = null; - - private ConnectionListenerAdapter connectionListener = new ConnectionListenerAdapter() { - - /** - * Called when it is sensed that a connection has terminated. - */ - public void disconnected(DisconnectedEvent e) { - Connection conn = e.getConnection(); - - // write something in the log - System.out.println("s: connection " + conn.getId()+ " disconnected"); - - connections.removeElement(conn); - connectionsPending.removeElement(conn); - connectionIds.remove(new Integer(conn.getId())); - - // if there's a player for this connection, remove it too - Player player = getPlayer(conn.getId()); - if (null != player) { - Server.this.disconnected( player ); - } - - } - - public void packetReceived(PacketReceivedEvent e) { - Server.this.handle(e.getConnection().getId(),e.getPacket()); - } - - }; - - /** - * Construct a new GameHost and begin listening for - * incoming clients. - * @param password the String that is set as a password - * @param port the int value that specifies the port that - * is used - */ - public Server(String password, int port) { - this.password = password.length() > 0 ? password : null; - // initialize server socket - try { - serverSocket = new ServerSocket(port); - } catch(IOException ex) { - System.err.println("could not create server socket on port "+port); - } - - motd = createMotd(); - - game.getOptions().initialize(); - - changePhase(IGame.PHASE_LOUNGE); - - // display server start text - System.out.println("s: starting a new server..."); - - try { - String host = InetAddress.getLocalHost().getHostName(); - System.out.print("s: hostname = '" ); - System.out.print( host ); - System.out.print( "' port = " ); - System.out.println( serverSocket.getLocalPort() ); - InetAddress[] addresses = InetAddress.getAllByName(host); - for (int i = 0; i < addresses.length; i++) { - System.out.println("s: hosting on address = " - + addresses[i].getHostAddress()); - } - } catch (UnknownHostException e) { - // oh well. - } - - System.out.println("s: password = " + this.password); - - connector = new Thread(this, "Connection Listener"); - connector.start(); - - // register commands - registerCommand(new DefeatCommand(this)); - registerCommand(new HelpCommand(this)); - registerCommand(new KickCommand(this)); - registerCommand(new ResetCommand(this)); - registerCommand(new RollCommand(this)); - registerCommand(new SaveGameCommand(this)); - registerCommand(new SkipCommand(this)); - registerCommand(new VictoryCommand(this)); - registerCommand(new WhoCommand(this)); - registerCommand(new SeeAllCommand(this)); - registerCommand(new LocalSaveGameCommand(this)); - registerCommand(new FixElevationCommand(this)); - - //register terrain processors - terrainProcessors.add(new FireProcessor(this)); - terrainProcessors.add(new GeyserProcessor(this)); - terrainProcessors.add(new ElevatorProcessor(this)); - } - - /** - * Sets the game for this server. Restores any transient fields, and sets - * all players as ghosts. - * This should only be called during server initialization before any - * players have connected. - */ - public void setGame(IGame g) { - this.game = g; - - // reattach the transient fields and ghost the players - for (Enumeration e = game.getEntities(); e.hasMoreElements(); ) { - Entity ent = (Entity)e.nextElement(); - ent.setGame(game); - } - game.setOutOfGameEntitiesVector(game.getOutOfGameEntitiesVector()); - for (Enumeration e = game.getPlayers(); e.hasMoreElements(); ) { - Player p = (Player)e.nextElement(); - p.setGame(game); - p.setGhost(true); - } - - } - - /** Returns the current game object */ - public IGame getGame() { - return game; - } - - /** - * Make a default message o' the day containing the version string, and - * if it was found, the build timestamp - */ - private String createMotd() { - StringBuffer buf = new StringBuffer(); - buf.append("Welcome to MegaMek. Server is running version "); - buf.append(MegaMek.VERSION); - buf.append(", build date "); - if (MegaMek.TIMESTAMP > 0L) { - buf.append(new Date(MegaMek.TIMESTAMP).toString()); - } else { - buf.append("unknown"); - } - buf.append("."); - - return buf.toString(); - } - - /** - * @return true if the server has a password - */ - public boolean isPassworded() { - return password != null; - } - - /** - * @return true if the password matches - */ - public boolean isPassword(Object guess) { - return password.equals(guess); - } - - /** - * Registers a new command in the server command table - */ - private void registerCommand(ServerCommand command) { - commandsHash.put(command.getName(), command); - } - - /** - * Returns the command associated with the specified name - */ - public ServerCommand getCommand(String name) { - return (ServerCommand)commandsHash.get(name); - } - - /** - * Shuts down the server. - */ - public void die() { - // kill thread accepting new connections - connector = null; - - // close socket - try { - serverSocket.close(); - } catch(IOException ex) {} - - // kill pending connnections - for (Enumeration i=connectionsPending.elements();i.hasMoreElements();){ - final Connection conn = (Connection)i.nextElement(); - conn.close(); - } - connectionsPending.removeAllElements(); - - // Send "kill" commands to all connections - // N.B. I may be starting a race here. - for (Enumeration i = connections.elements(); i.hasMoreElements();) { - final Connection conn = (Connection)i.nextElement(); - send(conn.getId(), new Packet(Packet.COMMAND_CLOSE_CONNECTION)); - } - - // kill active connnections - for (Enumeration i = connections.elements(); i.hasMoreElements();) { - final Connection conn = (Connection)i.nextElement(); - conn.close(); - } - connections.removeAllElements(); - connectionIds.clear(); - } - - /** - * Returns an enumeration of all the command names - */ - public Enumeration getAllCommandNames() { - return commandsHash.keys(); - } - - /** - * Sent when a client attempts to connect. - */ - private void greeting(int cn) { - // send server greeting -- client should reply with client info. - sendToPending(cn, new Packet(Packet.COMMAND_SERVER_GREETING)); - } - - /** - * Returns a free connection id. - */ - public int getFreeConnectionId() { - while (getPendingConnection(connectionCounter) != null - || getConnection(connectionCounter) != null - || getPlayer(connectionCounter) != null) { - connectionCounter++; - } - return connectionCounter; - } - - /** - * Returns a free entity id. Perhaps this should be in Game instead. - */ - public int getFreeEntityId() { - return game.getNextEntityId(); - } - - /** - * Allow the player to set whatever parameters he is able to - */ - private void receivePlayerInfo(Packet packet, int connId) { - Player player = (Player)packet.getObject(0); - Player connPlayer = game.getPlayer( connId ); - if ( null != connPlayer ) { - connPlayer.setColorIndex(player.getColorIndex()); - connPlayer.setStartingPos(player.getStartingPos()); - connPlayer.setTeam(player.getTeam()); - connPlayer.setCamoCategory(player.getCamoCategory()); - connPlayer.setCamoFileName(player.getCamoFileName()); - connPlayer.setNbrMFConventional(player.getNbrMFConventional()); - connPlayer.setNbrMFCommand(player.getNbrMFCommand()); - connPlayer.setNbrMFVibra(player.getNbrMFVibra()); - } - } - - private String correctDupeName(String oldName) { - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - Player player = (Player)i.nextElement(); - if (player.getName().equals(oldName)) { - // We need to correct it. - String newName = oldName; - int dupNum = 2; - try { - dupNum = Integer.parseInt(oldName.substring(oldName.lastIndexOf(".")+1)); - dupNum++; - newName = oldName.substring(0,oldName.lastIndexOf(".")); - } catch (Exception e) { - // If this fails, we don't care much. - // Just assume it's the first time for this name. - dupNum = 2; - } - newName = newName.concat(".").concat(Integer.toString(dupNum)); - return correctDupeName(newName); - } - } - return oldName; - } - - /** - * Recieves a player name, sent from a pending connection, and connects - * that connection. - */ - private void receivePlayerName(Packet packet, int connId) { - final Connection conn = getPendingConnection(connId); - String name = (String)packet.getObject(0); - boolean returning = false; - - // this had better be from a pending connection - if (conn == null) { - System.out.println("server: got a client name from a non-pending" + - " connection"); - return; - } - - // check if they're connecting with the same name as a ghost player - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - Player player = (Player)i.nextElement(); - if (player.getName().equals(name)) { - if (player.isGhost()) { - returning = true; - player.setGhost(false); - // switch id - connId = player.getId(); - conn.setId(connId); - } - } - } - - if (!returning) { - // Check to avoid duplicate names... - name = correctDupeName(name); - send(connId, new Packet(Packet.COMMAND_SERVER_CORRECT_NAME, name)); - } - - // right, switch the connection into the "active" bin - connectionsPending.removeElement(conn); - connections.addElement(conn); - connectionIds.put(new Integer(conn.getId()), conn); - - // add and validate the player info - if (!returning) { - game.addPlayer(connId, new Player(connId, name)); - validatePlayerInfo(connId); - } - - // if it is not the lounge phase, this player becomes an observer - Player player = getPlayer( connId ); - if ( game.getPhase() != IGame.PHASE_LOUNGE - && null != player - && game.getEntitiesOwnedBy(player) < 1) { - player.setObserver(true); - } - - // send the player the motd - sendServerChat(connId, motd); - - // send info that the player has connected - send(createPlayerConnectPacket(connId)); - - // tell them their local playerId - send(connId, new Packet(Packet.COMMAND_LOCAL_PN, new Integer(connId))); - - // send current game info - sendCurrentInfo(connId); - - try { - InetAddress[] addresses = InetAddress.getAllByName(InetAddress - .getLocalHost() - .getHostName()); - for (int i = 0; i < addresses.length; i++) { - sendServerChat(connId, "Machine IP is " + - addresses[i].getHostAddress()); - } - } catch (UnknownHostException e) { - // oh well. - } - - // Send the port we're listening on. Only useful for the player - // on the server machine to check. - sendServerChat(connId, "Listening on port " + serverSocket - .getLocalPort()); - - // Get the player *again*, because they may have disconnected. - player = getPlayer( connId ); - if ( null != player ) { - StringBuffer buff = new StringBuffer(); - buff.append( player.getName() ) - .append( " connected from " ) - .append( getClient(connId).getInetAddress() ); - String who = buff.toString(); - System.out.print( "s: player #" ); - System.out.print( connId ); - System.out.print( ", " ); - System.out.println( who ); - - sendServerChat( who ); - - } // Found the player - } - - /** - * Sends a player the info they need to look at the current phase. - * This is triggered when a player first connects to the server. - */ - private void sendCurrentInfo(int connId) { - //why are these two outside the player != null check below? - transmitAllPlayerConnects(connId); - send(connId, createGameSettingsPacket()); - - Player player = game.getPlayer(connId); - if ( null != player ) { - send(connId, new Packet(Packet.COMMAND_SENDING_MINEFIELDS, - player.getMinefields())); - - switch (game.getPhase()) { - case IGame.PHASE_LOUNGE : - send(connId, createMapSettingsPacket()); - // Send Entities *after* the Lounge Phase Change - send(connId, new Packet(Packet.COMMAND_PHASE_CHANGE, - new Integer(game.getPhase()))); - if (doBlind()) { - send(connId, createFilteredFullEntitiesPacket(player)); - } - else { - send(connId, createFullEntitiesPacket()); - } - break; - default : - send(connId, new Packet(Packet.COMMAND_ROUND_UPDATE, new Integer(game.getRoundCount()))); - //send(connId, createReportPacket(player)); - send(connId, createAllReportsPacket(player)); - - // Send Entites *before* other phase changes. - if (doBlind()) { - send(connId, createFilteredFullEntitiesPacket(player)); - } - else { - send(connId, createFullEntitiesPacket()); - } - player.setDone( game.getEntitiesOwnedBy(player) <= 0 ); - send(connId, createBoardPacket()); - send(connId, new Packet(Packet.COMMAND_PHASE_CHANGE, - new Integer(game.getPhase()))); - break; - } - if (game.getPhase() == IGame.PHASE_FIRING || - game.getPhase() == IGame.PHASE_TARGETING || - game.getPhase() == IGame.PHASE_OFFBOARD || - game.getPhase() == IGame.PHASE_PHYSICAL) { - // can't go above, need board to have been sent - send(connId,createAttackPacket(game.getActionsVector(),0)); - send(connId,createAttackPacket(game.getChargesVector(),1)); - send(connId,createAttackPacket(game.getLayMinefieldActionsVector(),2)); - } - if (game.phaseHasTurns(game.getPhase())) { - send(connId, createTurnVectorPacket()); - send(connId, createTurnIndexPacket()); - } - - send(connId, createArtilleryPacket(player)); - send(connId, createFlarePacket()); - - } // Found the player. - - } - - /** - * Validates the player info. - */ - public void validatePlayerInfo(int playerId) { - final Player player = getPlayer(playerId); - - // maybe this isn't actually useful - // // replace characters we don't like with "X" - // StringBuffer nameBuff = new StringBuffer(player.getName()); - // for (int i = 0; i < nameBuff.length(); i++) { - // int chr = nameBuff.charAt(i); - // if (LEGAL_CHARS.indexOf(chr) == -1) { - // nameBuff.setCharAt(i, 'X'); - // } - // } - // player.setName(nameBuff.toString()); - - //TODO: check for duplicate or reserved names - - // make sure colorIndex is unique - boolean[] colorUsed = new boolean[Player.colorNames.length]; - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - final Player otherPlayer = (Player)i.nextElement(); - if (otherPlayer.getId() != playerId) { - colorUsed[otherPlayer.getColorIndex()] = true; - } - } - if (null != player && colorUsed[player.getColorIndex()]) { - // find a replacement color; - for (int i = 0; i < colorUsed.length; i++) { - if (!colorUsed[i]) { - player.setColorIndex(i); - break; - } - } - } - - } - - /** - * Called when it's been determined that an actual player - * disconnected. Notifies the other players and does the appropriate - * housekeeping. - */ - void disconnected(Player player) { - int phase = game.getPhase(); - - // in the lounge, just remove all entities for that player - if (phase == IGame.PHASE_LOUNGE) { - removeAllEntitesOwnedBy(player); - } - - // if a player has active entities, he becomes a ghost - // except the VICTORY_PHASE when the dosconnected - // player is most likely the Bot disconnected after receiving - // the COMMAND_END_OF_GAME command - // see the Bug 1225949. - // TODO Perhaps there is a better solution to handle the Bot disconnect - if (game.getEntitiesOwnedBy(player) > 0 && phase != IGame.PHASE_VICTORY) { - player.setGhost(true); - player.setDone(true); - send(createPlayerUpdatePacket(player.getId())); - } else { - game.removePlayer(player.getId()); - send(new Packet(Packet.COMMAND_PLAYER_REMOVE, - new Integer(player.getId()))); - } - - // make sure the game advances - if ( game.phaseHasTurns(game.getPhase()) && null != game.getTurn() ) { - if ( game.getTurn().isValid( player.getId(), game ) ) { - sendGhostSkipMessage( player ); - } - } else { - checkReady(); - } - - // notify other players - sendServerChat(player.getName() + " disconnected."); - - // log it - System.out.println("s: removed player " + player.getName()); - - // Reset the game after Elvis has left the building. - if ( 0 == game.getNoOfPlayers() ) { - resetGame(); - } - } - - /** - * Checks each player to see if he has no entities, and if true, sets the - * observer flag for that player. An exception is that there are no - * observers during the lounge phase. - */ - public void checkForObservers() { - for (Enumeration e = game.getPlayers(); e.hasMoreElements(); ) { - Player p = (Player)e.nextElement(); - p.setObserver(game.getEntitiesOwnedBy(p) < 1 && - game.getPhase() != IGame.PHASE_LOUNGE); - } - } - - /** - * Reset the game back to the lounge. - * - * TODO: couldn't this be a hazard if there are other things executing at - * the same time? - */ - public void resetGame() { - // remove all entities - game.reset(); - send(createEntitiesPacket()); - send(new Packet(Packet.COMMAND_SENDING_MINEFIELDS, new Vector())); - - //TODO: remove ghosts - - // reset all players - resetPlayersDone(); - transmitAllPlayerDones(); - - // Write end of game to stdout so controlling scripts can rotate logs. - SimpleDateFormat format = new SimpleDateFormat - ( "yyyy-MM-dd HH:mm:ss z" ); - System.out.print( format.format(new Date()) ); - System.out.println( " END OF GAME" ); - - changePhase(IGame.PHASE_LOUNGE); - } - - - /** - * automatically save the game - */ - public void autoSave() { - String fileName = "autosave"; - if (PreferenceManager.getClientPreferences().stampFilenames()) { - fileName = StringUtil.addDateTimeStamp(fileName); - } - saveGame(fileName,game.getOptions().booleanOption("autosave_msg")); - } - - /** - * save the game and send it to the sepecified connection - * @param connId The int connection id to send to - * @param sFile The String filename to use - */ - public void sendSaveGame (int connId, String sFile) { - saveGame(sFile, false); - String sFinalFile = sFile; - if (!sFinalFile.endsWith(".sav")) { - sFinalFile = sFile + ".sav"; - } - sFinalFile = "savegames" + File.separator + sFinalFile; - File f = new File(sFinalFile); - try { - ObjectInputStream ois = new ObjectInputStream( - new FileInputStream(f)); - send(connId,new Packet(Packet.COMMAND_SEND_SAVEGAME, new Object[] {sFinalFile, ois.readObject()})); - sendChat(connId,"***Server","Savegame has been sent to you."); - ois.close(); - } catch (Exception e) { - System.err.println("Unable to load file: " + f); - e.printStackTrace(); - } - } - - /** - * save the game - * @param sFile The String filename to use - * @param sendChat A boolean value wether or not to announce - * the saving to the server chat. - */ - public void saveGame(String sFile, boolean sendChat) { - String sFinalFile = sFile; - if (!sFinalFile.endsWith(".sav")) { - sFinalFile = sFile + ".sav"; - } - try { - File sDir = new File("savegames"); - if (!sDir.exists()) { - sDir.mkdir(); - } - sFinalFile = sDir + File.separator + sFinalFile; - ObjectOutputStream oos = new ObjectOutputStream( - new FileOutputStream(sFinalFile)); - oos.writeObject(game); - oos.flush(); - oos.close(); - } catch (Exception e) { - System.err.println("Unable to save file: " + sFinalFile); - e.printStackTrace(); - } - - if (sendChat) sendChat("MegaMek", "Game saved to " + sFinalFile); - } - - /** - * save the game - * @param sFile The String filename to use - */ - public void saveGame(String sFile) { - saveGame(sFile,true); - } - - /** - * load the game - * @param f The File to load - * @return A boolean value wether or not the loading was successfull - */ - public boolean loadGame(File f) { - System.out.println("s: loading saved game file '"+f+"'"); - try { - ObjectInputStream ois = new ObjectInputStream( - new FileInputStream(f)); - game = (IGame)ois.readObject(); - ois.close(); - } catch (Exception e) { - System.err.println("Unable to load file: " + f); - e.printStackTrace(); - return false; - } - - // a bit redundant, but there's some initialization code there - setGame(game); - - return true; - } - - /** - * Shortcut to game.getPlayer(id) - */ - public Player getPlayer(int id) { - return game.getPlayer(id); - } - - /** - * Removes all entities owned by a player. Should only be called when it - * won't cause trouble (the lounge, for instance, or between phases.) - * @param the Player whose entites are to be removed - */ - private void removeAllEntitesOwnedBy(Player player) { - Vector toRemove = new Vector(); - - for (Enumeration e = game.getEntities(); e.hasMoreElements();) { - final Entity entity = (Entity)e.nextElement(); - - if (entity.getOwner().equals(player)) { - toRemove.addElement(entity); - } - } - - for (Enumeration e = toRemove.elements(); e.hasMoreElements();) { - final Entity entity = (Entity)e.nextElement(); - int id = entity.getId(); - game.removeEntity(id, IEntityRemovalConditions.REMOVE_NEVER_JOINED); - send(createRemoveEntityPacket(id, IEntityRemovalConditions.REMOVE_NEVER_JOINED)); - } - } - - /** - * a shorter name for getConnection() - */ - private Connection getClient(int connId) { - return getConnection(connId); - } - - /** - * Returns a connection, indexed by id - */ - public Enumeration getConnections() { - return connections.elements(); - } - - /** - * Returns a connection, indexed by id - */ - public Connection getConnection(int connId) { - return (Connection)connectionIds.get(new Integer(connId)); - } - - /** - * Returns a pending connection - */ - private Connection getPendingConnection(int connId) { - for (Enumeration i=connectionsPending.elements();i.hasMoreElements();){ - final Connection conn = (Connection)i.nextElement(); - - if (conn.getId() == connId) { - return conn; - } - } - return null; - } - - /** - * Called at the beginning of each game round to reset values on this - * entity that are reset every round - */ - private void resetEntityRound() { - for (Enumeration e = game.getEntities(); e.hasMoreElements();) { - Entity entity = (Entity)e.nextElement(); - - entity.newRound(game.getRoundCount()); - } - } - - /** - * Called at the beginning of each phase. Sets and resets - * any entity parameters that need to be reset. - */ - private void resetEntityPhase(int phase) { - // first, mark doomed entities as destroyed and flag them - Vector toRemove = new Vector(0, 10); - for (Enumeration e = game.getEntities(); e.hasMoreElements();) { - final Entity entity = (Entity)e.nextElement(); - - if (entity.crew.isDoomed()) { - entity.crew.setDead(true); - entity.setDestroyed(true); - } - - if (entity.isDoomed()) { - entity.setDestroyed(true); - - // Is this unit swarming somebody? Better let go before - // it's too late. - final int swarmedId = entity.getSwarmTargetId(); - if ( Entity.NONE != swarmedId ) { - final Entity swarmed = game.getEntity( swarmedId ); - swarmed.setSwarmAttackerId( Entity.NONE ); - entity.setSwarmTargetId( Entity.NONE ); - Report r = new Report(5165); - r.subject = swarmedId; - r.addDesc(swarmed); - addReport(r); - this.entityUpdate( swarmedId ); - } - } - - if (entity.isDestroyed() || entity.getCrew().isDead()) { - toRemove.addElement(entity); - } - } - - // actually remove all flagged entities - for (Enumeration e = toRemove.elements(); e.hasMoreElements();) { - final Entity entity = (Entity)e.nextElement(); - int condition = IEntityRemovalConditions.REMOVE_SALVAGEABLE; - if ( !entity.isSalvage() ) { - condition = IEntityRemovalConditions.REMOVE_DEVASTATED; - } - - this.entityUpdate(entity.getId()); - game.removeEntity(entity.getId(), condition); - send( createRemoveEntityPacket(entity.getId(), condition) ); - } - - // do some housekeeping on all the remaining - for (Enumeration e = game.getEntities(); e.hasMoreElements();) { - final Entity entity = (Entity)e.nextElement(); - - entity.applyDamage(); - - entity.reloadEmptyWeapons(); - - // reset damage this phase - entity.damageThisPhase = 0; - entity.engineHitsThisRound = 0; - entity.rolledForEngineExplosion = false; - entity.dodging = false; - - // reset done to false - - if ( phase == IGame.PHASE_DEPLOYMENT ) { - entity.setDone(!entity.shouldDeploy(game.getRoundCount())); - } else { - entity.setDone(false); - } - - // reset spotlights - entity.setIlluminated(false); - entity.setUsedSearchlight(false); - } - } - - /** - * Called at the beginning of certain phases to make - * every player not ready. - */ - private void resetPlayersDone() { - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - final Player player = (Player)i.nextElement(); - player.setDone(false); - } - } - - /** - * Called at the beginning of certain phases to make - * every active player not ready. - */ - private void resetActivePlayersDone() { - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - final Player player = (Player)i.nextElement(); - - player.setDone(game.getEntitiesOwnedBy(player) <= 0); - - } - transmitAllPlayerDones(); - } - - /** - * Writes the victory report - */ - private void prepareVictoryReport() { - Report r; - - addReport(new Report(7000, Report.PUBLIC)); - - //Declare the victor - r = new Report(1210); - r.type = Report.PUBLIC; - if (game.getVictoryTeam() == Player.TEAM_NONE) { - Player player = getPlayer( game.getVictoryPlayerId() ); - if ( null == player ) { - r.messageId = 7005; - } else { - r.messageId = 7010; - r.add(player.getName()); - } - } else { - //Team victory - r.messageId = 7015; - r.add(game.getVictoryTeam()); - } - addReport(r); - - //List the survivors - Enumeration survivors = game.getEntities(); - if ( survivors.hasMoreElements() ) { - addReport(new Report(7020, Report.PUBLIC)); - while ( survivors.hasMoreElements() ) { - Entity entity = (Entity) survivors.nextElement(); - - if ( !entity.isDeployed() ) - continue; - - addReport( entity.victoryReport()); - } - } - //List units that never deployed - Enumeration undeployed = game.getEntities(); - if ( undeployed.hasMoreElements() ) { - boolean wroteHeader = false; - - while ( undeployed.hasMoreElements() ) { - Entity entity = (Entity) undeployed.nextElement(); - - if ( entity.isDeployed() ) - continue; - - if ( !wroteHeader ) { - addReport(new Report(7075, Report.PUBLIC)); - wroteHeader = true; - } - - addReport( entity.victoryReport()); - } - } - //List units that retreated - Enumeration retreat = game.getRetreatedEntities(); - if ( retreat.hasMoreElements() ) { - addReport(new Report(7080, Report.PUBLIC)); - while ( retreat.hasMoreElements() ) { - Entity entity = (Entity) retreat.nextElement(); - addReport( entity.victoryReport()); - } - } - //List destroyed units - Enumeration graveyard = game.getGraveyardEntities(); - if ( graveyard.hasMoreElements() ) { - addReport(new Report(7085, Report.PUBLIC)); - while ( graveyard.hasMoreElements() ) { - Entity entity = (Entity) graveyard.nextElement(); - addReport( entity.victoryReport()); - } - } - //List devastated units (not salvagable) - Enumeration devastated = game.getDevastatedEntities(); - if ( devastated.hasMoreElements() ) { - addReport(new Report(7090, Report.PUBLIC)); - - while ( devastated.hasMoreElements() ) { - Entity entity = (Entity) devastated.nextElement(); - addReport( entity.victoryReport()); - } - } - //Let player know about entitystatus.txt file - addReport(new Report(7095, Report.PUBLIC)); - } - - /** - * Generates a detailed report for campaign use - */ - private String getDetailedVictoryReport() { - StringBuffer sb = new StringBuffer(); - - Vector vAllUnits = new Vector(); - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - vAllUnits.addElement(i.nextElement()); - } - - for ( Enumeration i = game.getRetreatedEntities(); - i.hasMoreElements(); ) { - vAllUnits.addElement(i.nextElement()); - } - - for ( Enumeration i = game.getGraveyardEntities(); - i.hasMoreElements(); ) { - vAllUnits.addElement(i.nextElement()); - } - - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - - // Record the player. - Player p = (Player)i.nextElement(); - sb.append("++++++++++ " ) - .append( p.getName() ) - .append( " ++++++++++"); - sb.append( CommonConstants.NL ); - - // Record the player's alive, retreated, or salvageable units. - for (int x = 0; x < vAllUnits.size(); x++) { - Entity e = (Entity)vAllUnits.elementAt(x); - if (e.getOwner() == p) { - sb.append(UnitStatusFormatter.format(e)); - } - } - - // Record the player's devastated units. - Enumeration devastated = game.getDevastatedEntities(); - if ( devastated.hasMoreElements() ) { - sb.append("============================================================="); - sb.append( CommonConstants.NL ); - sb.append("The following utterly destroyed units are not available for salvage:"); - sb.append( CommonConstants.NL ); - while ( devastated.hasMoreElements() ) { - Entity e = (Entity) devastated.nextElement(); - if (e.getOwner() == p) { - sb.append( e.getShortName() ) - .append( ", Pilot: " ) - .append( e.getCrew().getName() ) - .append( " (" ) - .append( e.getCrew().getGunnery() ) - .append( "/" ) - .append( e.getCrew().getPiloting() ) - .append( ")" ); - sb.append( CommonConstants.NL ); - } - } // Handle the next unsalvageable unit for the player - sb.append("============================================================="); - sb.append( CommonConstants.NL ); - } - - } // Handle the next player - - return sb.toString(); - } - - /** - * Forces victory for the specified player, or his/her team at the end of - * the round. - */ - public void forceVictory(Player victor) { - game.setForceVictory(true); - if (victor.getTeam() == Player.TEAM_NONE) { - game.setVictoryPlayerId(victor.getId()); - game.setVictoryTeam(Player.TEAM_NONE); - } else { - game.setVictoryPlayerId(Player.PLAYER_NONE); - game.setVictoryTeam(victor.getTeam()); - } - - Vector players = game.getPlayersVector(); - for (int i = 0; i < players.size(); i++) { - Player player = (Player) players.elementAt(i); - player.setAdmitsDefeat(false); - } - } - - /** Cancels the force victory */ - public void cancelVictory() { - game.setForceVictory(false); - game.setVictoryPlayerId(Player.PLAYER_NONE); - game.setVictoryTeam(Player.TEAM_NONE); - } - - /** - * Called when a player declares that he is "done." Checks to see if all - * players are done, and if so, moves on to the next phase. - */ - private void checkReady() { - // check if all active players are done - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - final Player player = (Player)i.nextElement(); - if (!player.isGhost() && !player.isObserver() && !player.isDone()) { - return; - } - } - - // Tactical Genius pilot special ability (lvl 3) - if (game.getNoOfInitiativeRerollRequests() > 0) { - resetActivePlayersDone(); - game.rollInitAndResolveTies(); - - determineTurnOrder(IGame.PHASE_INITIATIVE); - clearReports(); - writeInitiativeReport(true); - sendReport(true); - return; // don't end the phase yet, players need to see new report - } - - // need at least one entity in the game for the lounge phase to end - if (!game.phaseHasTurns(game.getPhase()) && - (game.getPhase() != IGame.PHASE_LOUNGE || game.getNoOfEntities() > 0)) { - endCurrentPhase(); - } - } - - /** - * Called when the current player has done his current turn and the turn - * counter needs to be advanced. - * Also enforces the "protos_move_multi" and the "protos_move_multi" - * option. If the player has just moved infantry/protos with a "normal" - * turn, adds up to Game.INF_AND_PROTOS_MOVE_MULTI - 1 more - * infantry/proto-specific turns after the current turn. - */ - private void endCurrentTurn(Entity entityUsed) { - - // Enforce "inf_move_multi" and "protos_move_multi" options. - // The "isNormalTurn" flag is checking to see if any non-Infantry - // or non-Protomech units can move during the current turn. - boolean turnsChanged = false; - GameTurn turn = game.getTurn(); - final int playerId = (null == entityUsed) ? - Player.PLAYER_NONE : entityUsed.getOwnerId(); - boolean infMoved = entityUsed instanceof Infantry; - boolean infMoveMulti = - game.getOptions().booleanOption("inf_move_multi") - && (game.getPhase() == IGame.PHASE_MOVEMENT - || game.getPhase() == IGame.PHASE_INITIATIVE); - boolean protosMoved = entityUsed instanceof Protomech; - boolean protosMoveMulti = - game.getOptions().booleanOption("protos_move_multi"); - - // If infantry or protos move multi see if any - // other unit types can move in the current turn. - int multiMask = 0; - if ( infMoveMulti ) { - multiMask += GameTurn.CLASS_INFANTRY; - } - if ( protosMoveMulti ) { - multiMask += GameTurn.CLASS_PROTOMECH; - } - - // If a proto declared fire and protos don't move - // multi, ignore whether infantry move or not. - else if ( protosMoved && game.getPhase() == IGame.PHASE_FIRING ) { - multiMask = 0; - } - - // Is this a general move turn? - boolean isGeneralMoveTurn = - ( !(turn instanceof GameTurn.SpecificEntityTurn) && - !(turn instanceof GameTurn.UnitNumberTurn) && - !(turn instanceof GameTurn.UnloadStrandedTurn) && - ( !(turn instanceof GameTurn.EntityClassTurn) || - ( (turn instanceof GameTurn.EntityClassTurn) && - ( (GameTurn.EntityClassTurn) turn ).isValidClass(~multiMask) - ) - ) - ); - - // Unless overridden by the "protos_move_multi" option, all Protomechs - // in a unit declare fire, and they don't mix with infantry. - if ( protosMoved && !protosMoveMulti && isGeneralMoveTurn && - game.getPhase() == IGame.PHASE_FIRING ) { - - // What's the unit number and ID of the entity used? - final char movingUnit = entityUsed.getUnitNumber(); - final int movingId = entityUsed.getId(); - - // How many other Protomechs are in the unit that can fire? - int protoTurns = game.getSelectedEntityCount - ( new EntitySelector() { - private final int ownerId = playerId; - private final int entityId = movingId; - private final char unitNum = movingUnit; - public boolean accept( Entity entity ) { - if ( entity instanceof Protomech && - entity.isSelectableThisTurn() && - ownerId == entity.getOwnerId() && - entityId != entity.getId() && - unitNum == entity.getUnitNumber() ) - return true; - return false; - } - } ); - - // Add the correct number of turns for the Protomech unit number. - for (int i = 0; i < protoTurns; i++) { - GameTurn newTurn = new GameTurn.UnitNumberTurn - ( playerId, movingUnit ); - game.insertNextTurn(newTurn); - turnsChanged = true; - } - } - - // Otherwise, we may need to add turns for the "*_move_multi" options. - else if ( ( (infMoved && infMoveMulti) || - (protosMoved && protosMoveMulti) ) && - isGeneralMoveTurn ) { - int remaining = 0; - - // Calculate the number of EntityClassTurns need to be added. - if ( infMoveMulti ) { - remaining += game.getInfantryLeft(playerId); - } - if ( protosMoveMulti ) { - remaining += game.getProtomechsLeft(playerId); - } - int moreInfAndProtoTurns = - Math.min(game.getOptions().intOption("inf_proto_move_multi") - 1, remaining); - - // Add the correct number of turns for the right unit classes. - for (int i = 0; i < moreInfAndProtoTurns; i++) { - GameTurn newTurn = - new GameTurn.EntityClassTurn( playerId, multiMask ); - game.insertNextTurn(newTurn); - turnsChanged = true; - } - } - // brief everybody on the turn update, if they changed - if (turnsChanged) { - send(createTurnVectorPacket()); - } - - // move along - changeToNextTurn(); - } - - /** - * Changes the current phase, does some bookkeeping and - * then tells the players. - * @param phase the int id of the phase to change to - */ - private void changePhase(int phase) { - game.setLastPhase(game.getPhase()); - game.setPhase(phase); - - // prepare for the phase - prepareForPhase(phase); - - if (isPhasePlayable(phase)) { - // tell the players about the new phase - send(new Packet(Packet.COMMAND_PHASE_CHANGE, new Integer(phase))); - - // post phase change stuff - executePhase(phase); - } else { - endCurrentPhase(); - } - } - - /** - * Prepares for, presumably, the next phase. This typically involves - * resetting the states of entities in the game and making sure the client - * has the information it needs for the new phase. - * @param phase the int id of the phase to prepare for - */ - private void prepareForPhase(int phase) { - switch (phase) { - case IGame.PHASE_LOUNGE : - clearReports(); - mapSettings.setBoardsAvailableVector - ( scanForBoards(mapSettings.getBoardWidth(), - mapSettings.getBoardHeight()) ); - mapSettings.setNullBoards(DEFAULT_BOARD); - send(createMapSettingsPacket()); - break; - case IGame.PHASE_INITIATIVE : - // remove the last traces of last round - game.resetActions(); - game.resetTagInfo(); - clearReports(); - resetEntityRound(); - resetEntityPhase(phase); - checkForObservers(); - // roll 'em - resetActivePlayersDone(); - rollInitiative(); - - if ( !game.shouldDeployThisRound() ) - incrementAndSendGameRound(); - - //setIneligible(phase); - determineTurnOrder(phase); - writeInitiativeReport(false); - System.out.println("Round " + game.getRoundCount() + " memory usage: " + MegaMek.getMemoryUsed()); - break; - case IGame.PHASE_DEPLOY_MINEFIELDS : - checkForObservers(); - resetActivePlayersDone(); - setIneligible(phase); - - Enumeration e = game.getPlayers(); - Vector turns = new Vector(); - while (e.hasMoreElements()) { - Player p = (Player) e.nextElement(); - if (p.hasMinefields()) { - GameTurn gt = new GameTurn(p.getId()); - turns.addElement(gt); - } - } - game.setTurnVector(turns); - game.resetTurnIndex(); - - // send turns to all players - send(createTurnVectorPacket()); - break; - case IGame.PHASE_SET_ARTYAUTOHITHEXES : - // place off board entities actually off-board - Enumeration i = game.getEntities(); - while (i.hasMoreElements()) { - Entity en = (Entity) i.nextElement(); - en.deployOffBoard(); - } - checkForObservers(); - resetActivePlayersDone(); - setIneligible(phase); - - i = game.getPlayers(); - Vector turn = new Vector(); - - // Walk through the players of the game, and add - // a turn for all players with artillery weapons. - while (i.hasMoreElements()) { - - // Get the next player. - final Player p = (Player) i.nextElement(); - - // Does the player have any artillery-equipped units? - EntitySelector playerArtySelector = new EntitySelector() { - private Player owner = p; - public boolean accept (Entity entity) { - if ( owner.equals( entity.getOwner() ) && - entity.isEligibleForTargetingPhase() ) - return true; - return false; - } - }; - if ( game.getSelectedEntities( playerArtySelector ) - .hasMoreElements() ) { - - // Yes, the player has arty-equipped units. - GameTurn gt = new GameTurn(p.getId()); - turn.addElement(gt); - } - } - game.setTurnVector(turn); - game.resetTurnIndex(); - - // send turns to all players - send(createTurnVectorPacket()); - break; - case IGame.PHASE_MOVEMENT : - case IGame.PHASE_DEPLOYMENT : - case IGame.PHASE_FIRING : - case IGame.PHASE_PHYSICAL : - case IGame.PHASE_TARGETING: - case IGame.PHASE_OFFBOARD: - resetEntityPhase(phase); - checkForObservers(); - setIneligible(phase); - determineTurnOrder(phase); - resetActivePlayersDone(); - //send(createEntitiesPacket()); - entityAllUpdate(); - clearReports(); - doTryUnstuck(); - break; - case IGame.PHASE_END : - resetEntityPhase(phase); - clearReports(); - resolveHeat(); - //write End Phase header - addReport(new Report(5005, Report.PUBLIC)); - checkForSuffocation(); - if (game.getOptions().booleanOption("vacuum")) { - checkForVacuumDeath(); - } - for(Enumeration tps=terrainProcessors.elements();tps.hasMoreElements();) { - DynamicTerrainProcessor tp = tps.nextElement(); - tp.DoEndPhaseChanges(vPhaseReport); - } - addReport( game.ageFlares()); - send(createFlarePacket()); - resolveExtremeTempInfantryDeath(); - resolveAmmoDumps(); - resolveCrewDamage(); - resolveCrewWakeUp(); - resolveMechWarriorPickUp(); - resolveVeeINarcPodRemoval(); - checkForObservers(); - entityAllUpdate(); - break; - case IGame.PHASE_INITIATIVE_REPORT : - autoSave(); - case IGame.PHASE_MOVEMENT_REPORT : - case IGame.PHASE_OFFBOARD_REPORT : - case IGame.PHASE_FIRING_REPORT : - case IGame.PHASE_PHYSICAL_REPORT : - case IGame.PHASE_END_REPORT : - resetActivePlayersDone(); - sendReport(); - if (game.getOptions().booleanOption("paranoid_autosave")) autoSave(); - break; - case IGame.PHASE_VICTORY : - resetPlayersDone(); - clearReports(); - prepareVictoryReport(); - game.addReports(vPhaseReport); - send(createFullEntitiesPacket()); - send(createReportPacket(null)); - send(createEndOfGamePacket()); - break; - } - } - - /** - * Should we play this phase or skip it? - */ - private boolean isPhasePlayable(int phase) { - switch (phase) { - case IGame.PHASE_INITIATIVE : - case IGame.PHASE_END : - return false; - case IGame.PHASE_SET_ARTYAUTOHITHEXES : - case IGame.PHASE_DEPLOY_MINEFIELDS : - case IGame.PHASE_DEPLOYMENT : - case IGame.PHASE_MOVEMENT : - case IGame.PHASE_FIRING : - case IGame.PHASE_PHYSICAL : - case IGame.PHASE_TARGETING: - case IGame.PHASE_OFFBOARD : - return game.hasMoreTurns(); - default : - return true; - } - } - - /** - * Do anything we seed to start the new phase, such as give a turn to - * the first player to play. - */ - private void executePhase(int phase) { - switch (phase) { - case IGame.PHASE_EXCHANGE : - resetPlayersDone(); - // Build teams vector - game.setupTeams(); - applyBoardSettings(); - game.setupRoundDeployment(); - game.determineWind(); - // If we add transporters for any Magnetic Clamp - // equiped squads, then update the clients' entities. - if ( game.checkForMagneticClamp() ) { - entityAllUpdate(); - } - // transmit the board to everybody - send(createBoardPacket()); - break; - case IGame.PHASE_MOVEMENT : - //write Movement Phase header to report - addReport(new Report(2000, Report.PUBLIC)); - case IGame.PHASE_SET_ARTYAUTOHITHEXES : - case IGame.PHASE_DEPLOY_MINEFIELDS : - case IGame.PHASE_DEPLOYMENT : - case IGame.PHASE_FIRING : - case IGame.PHASE_PHYSICAL : - case IGame.PHASE_TARGETING : - case IGame.PHASE_OFFBOARD : - changeToNextTurn(); - if (game.getOptions().booleanOption("paranoid_autosave")) autoSave(); - break; - } - } - - /** - * Ends this phase and moves on to the next. - */ - private void endCurrentPhase() { - switch (game.getPhase()) { - case IGame.PHASE_LOUNGE : - changePhase(IGame.PHASE_EXCHANGE); - break; - case IGame.PHASE_EXCHANGE : - changePhase(IGame.PHASE_SET_ARTYAUTOHITHEXES); - break; - case IGame.PHASE_STARTING_SCENARIO : - changePhase(IGame.PHASE_SET_ARTYAUTOHITHEXES); - break; - case IGame.PHASE_SET_ARTYAUTOHITHEXES : - Enumeration e = game.getPlayers(); - boolean mines = false; - while (e.hasMoreElements()) { - Player p = (Player) e.nextElement(); - if (p.hasMinefields()) { - mines = true; - } - } - if (mines) { - changePhase(IGame.PHASE_DEPLOY_MINEFIELDS); - } else { - changePhase(IGame.PHASE_INITIATIVE); - } - break; - case IGame.PHASE_DEPLOY_MINEFIELDS : - changePhase(IGame.PHASE_INITIATIVE); - break; - case IGame.PHASE_DEPLOYMENT : - game.clearDeploymentThisRound(); - game.checkForCompleteDeployment(); - Enumeration pls = game.getPlayers(); - while (pls.hasMoreElements()) { - Player p = (Player) pls.nextElement(); - p.adjustStartingPosForReinforcements(); - } - - changePhase(IGame.PHASE_INITIATIVE); - break; - case IGame.PHASE_INITIATIVE : - game.addReports(vPhaseReport); - changePhase(IGame.PHASE_INITIATIVE_REPORT); - break; - case IGame.PHASE_INITIATIVE_REPORT : - //boolean doDeploy = game.shouldDeployThisRound() && (game.getLastPhase() != IGame.PHASE_DEPLOYMENT); - if ( game.shouldDeployThisRound() ) { - changePhase(IGame.PHASE_DEPLOYMENT); - } else { - changePhase(IGame.PHASE_TARGETING); - } - break; - case IGame.PHASE_MOVEMENT : - doAllAssaultDrops(); - addMovementHeat(); - applyBuildingDamage(); - checkFor20Damage(); - resolveCrewDamage(); - resolvePilotingRolls(); // Skids cause damage in movement phase - resolveCrewDamage(); // again, I guess - checkForFlamingDeath(); - // check phase report - if (vPhaseReport.size() > 1) { - game.addReports(vPhaseReport); - changePhase(IGame.PHASE_MOVEMENT_REPORT); - } else { - //just the header, so we'll add the label - addReport(new Report(1205, Report.PUBLIC)); - game.addReports(vPhaseReport); - sendReport(); - changePhase(IGame.PHASE_OFFBOARD); - } - break; - case IGame.PHASE_MOVEMENT_REPORT : - changePhase(IGame.PHASE_OFFBOARD); - break; - case IGame.PHASE_FIRING : - resolveAllButWeaponAttacks(); - assignAMS(); - resolveOnlyWeaponAttacks(); - applyBuildingDamage(); - checkFor20Damage(); - resolveCrewDamage(); - resolvePilotingRolls(); - resolveCrewDamage(); // again, I guess - // check phase report - if (vPhaseReport.size() > 1) { - game.addReports(vPhaseReport); - changePhase(IGame.PHASE_FIRING_REPORT); - } else { - //just the header, so we'll add the label - addReport(new Report(1205, Report.PUBLIC)); - sendReport(); - game.addReports(vPhaseReport); - changePhase(IGame.PHASE_PHYSICAL); - } - break; - case IGame.PHASE_FIRING_REPORT : - changePhase(IGame.PHASE_PHYSICAL); - break; - case IGame.PHASE_PHYSICAL : - resolvePhysicalAttacks(); - applyBuildingDamage(); - checkFor20Damage(); - resolveCrewDamage(); - resolvePilotingRolls(); - resolveCrewDamage(); // again, I guess - resolveSinkVees(); - // check phase report - if (vPhaseReport.size() > 1) { - game.addReports(vPhaseReport); - changePhase(IGame.PHASE_PHYSICAL_REPORT); - } else { - //just the header, so we'll add the label - addReport(new Report(1205, Report.PUBLIC)); - game.addReports(vPhaseReport); - sendReport(); - changePhase(IGame.PHASE_END); - } - break; - case IGame.PHASE_PHYSICAL_REPORT : - changePhase(IGame.PHASE_END); - break; - case IGame.PHASE_TARGETING : - enqueueIndirectArtilleryAttacks(); - changePhase(IGame.PHASE_MOVEMENT); - break; - case IGame.PHASE_OFFBOARD : - //write Offboard Attack Phase header - addReport(new Report(1100, Report.PUBLIC)); - resolveAllButWeaponAttacks(); //torso twist or flip arms possible - resolveOnlyWeaponAttacks(); //should only be TAG at this point - resolveIndirectArtilleryAttacks(); - applyBuildingDamage(); - checkFor20Damage(); - resolveCrewDamage(); - resolvePilotingRolls(); - resolveCrewDamage(); // again, I guess - //check reports - if (vPhaseReport.size() > 1) { - game.addReports(vPhaseReport); - changePhase(IGame.PHASE_OFFBOARD_REPORT); - } else { - //just the header, so we'll add the label - addReport(new Report(1205, Report.PUBLIC)); - game.addReports(vPhaseReport); - sendReport(); - changePhase(IGame.PHASE_FIRING); - } - break; - case IGame.PHASE_OFFBOARD_REPORT: - changePhase(IGame.PHASE_FIRING); - break; - case IGame.PHASE_END : - // check phase report - //HACK: hardcoded message ID check - if (vPhaseReport.size() > 3 - || ((Report)vPhaseReport.elementAt(1)).messageId != 1205) { - game.addReports(vPhaseReport); - changePhase(IGame.PHASE_END_REPORT); - } else { - //just the heat and end headers, so we'll add - // the label - addReport(new Report(1205, Report.PUBLIC)); - game.addReports(vPhaseReport); - sendReport(); - if (victory()) { - changePhase(IGame.PHASE_VICTORY); - } else { - changePhase(IGame.PHASE_INITIATIVE); - } - } - break; - case IGame.PHASE_END_REPORT : - if (victory()) { - changePhase(IGame.PHASE_VICTORY); - } else { - changePhase(IGame.PHASE_INITIATIVE); - } - break; - case IGame.PHASE_VICTORY : - resetGame(); - break; - } - } - - /** - * Increment's the server's game round and send it to all the clients - */ - private void incrementAndSendGameRound() { - game.incrementRoundCount(); - send(new Packet(Packet.COMMAND_ROUND_UPDATE, new Integer(game.getRoundCount()))); - } - - /** - * Tries to change to the next turn. If there are no more turns, ends the - * current phase. If the player whose turn it is next is not connected, - * we allow the other players to skip that player. - */ - private void changeToNextTurn() { - // if there aren't any more turns, end the phase - if (!game.hasMoreTurns()) { - endCurrentPhase(); - return; - } - - // okay, well next turn then! - GameTurn nextTurn = game.changeToNextTurn(); - send(createTurnIndexPacket()); - - Player player = getPlayer( nextTurn.getPlayerNum() ); - if ( null != player && player.isGhost() ) { - sendGhostSkipMessage( player ); - } - else if ( null == game.getFirstEntity() - && null != player - && ((game.getPhase() != IGame.PHASE_DEPLOY_MINEFIELDS) && (game.getPhase() != IGame.PHASE_SET_ARTYAUTOHITHEXES))) { - sendTurnErrorSkipMessage( player ); - } - } - - /** - * Sends out a notification message indicating that a ghost player may - * be skipped. - * - * @param ghost - the Player who is ghosted. - * This value must not be null. - */ - private void sendGhostSkipMessage( Player ghost ) { - StringBuffer message = new StringBuffer(); - message.append( "Player '" ) - .append( ghost.getName() ) - .append( "' is disconnected. You may skip his/her current turn with the /skip command." ); - sendServerChat( message.toString() ); - } - - /** - * Sends out a notification message indicating that the current turn is an - * error and should be skipped. - * - * @param skip - the Player who is to be skipped. - * This value must not be null. - */ - private void sendTurnErrorSkipMessage( Player skip ) { - StringBuffer message = new StringBuffer(); - message.append( "Player '" ) - .append( skip.getName() ) - .append( "' has no units to move. You should skip his/her/your current turn with the /skip command. You may want to report this error. See the MegaMek homepage (http://megamek.sf.net/) for details." ); - sendServerChat( message.toString() ); - } - - /** - * Skips the current turn. This only makes sense in phases that have turns. - * Operates by finding an entity to move and then doing nothing with it. - */ - public void skipCurrentTurn() { - // find an entity to skip... - Entity toSkip = game.getFirstEntity(); - - switch (game.getPhase()) { - case IGame.PHASE_DEPLOYMENT : - sendServerChat("Turns cannot be skipped in the deployment phase."); - break; - case IGame.PHASE_MOVEMENT : - if ( toSkip != null ) { - processMovement(toSkip, new MovePath(game, toSkip)); - } - endCurrentTurn(toSkip); - break; - case IGame.PHASE_FIRING : - case IGame.PHASE_PHYSICAL : - case IGame.PHASE_TARGETING : - case IGame.PHASE_OFFBOARD : - if ( toSkip != null ) { - processAttack(toSkip, new Vector(0)); - } - endCurrentTurn(toSkip); - break; - default : - - } - } - - /** - * Returns true if the current turn may be skipped. Ghost players' turns - * are skippable, and a turn should be skipped if there's nothing to move. - */ - public boolean isTurnSkippable() { - GameTurn turn = game.getTurn(); - if (null == turn) return false; - Player player = getPlayer( turn.getPlayerNum() ); - return ( null == player || player.isGhost() - || game.getFirstEntity() == null ); - } - - /** - * Returns true if victory conditions have been met. Victory conditions - * are when there is only one player left with mechs or only one team. - */ - public boolean victory() { - if (game.isForceVictory()) { - int victoryPlayerId = game.getVictoryPlayerId(); - int victoryTeam = game.getVictoryTeam(); - Vector players = game.getPlayersVector(); - boolean forceVictory = true; - - // Individual victory. - if (victoryPlayerId != Player.PLAYER_NONE) { - for (int i = 0; i < players.size(); i++) { - Player player = (Player) players.elementAt(i); - - if (player.getId() != victoryPlayerId && !player.isObserver()) { - if (!player.admitsDefeat()) { - forceVictory = false; - break; - } - } - } - } - // Team victory. - if (victoryTeam != Player.TEAM_NONE) { - for (int i = 0; i < players.size(); i++) { - Player player = (Player) players.elementAt(i); - - if (player.getTeam() != victoryTeam && !player.isObserver()) { - if (!player.admitsDefeat()) { - forceVictory = false; - break; - } - } - } - } - - for (int i = 0; i < players.size(); i++) { - Player player = (Player) players.elementAt(i); - player.setAdmitsDefeat(false); - } - - if (forceVictory) { - return true; - } - cancelVictory(); - } - - if (!game.getOptions().booleanOption("check_victory")) { - return false; - } - - // check all players/teams for aliveness - int playersAlive = 0; - Player lastPlayer = null; - boolean oneTeamAlive = false; - int lastTeam = Player.TEAM_NONE; - boolean unteamedAlive = false; - for (Enumeration e = game.getPlayers(); e.hasMoreElements();) { - Player player = (Player)e.nextElement(); - int team = player.getTeam(); - if (game.getLiveDeployedEntitiesOwnedBy(player) <= 0) { - continue; - } - // we found a live one! - playersAlive++; - lastPlayer = player; - // check team - if (team == Player.TEAM_NONE) { - unteamedAlive = true; - } else if (lastTeam == Player.TEAM_NONE) { - // possibly only one team alive - oneTeamAlive = true; - lastTeam = team; - } else if (team != lastTeam) { - // more than one team alive - oneTeamAlive = false; - lastTeam = team; - } - } - - // check if there's one player alive - if (playersAlive < 1) { - game.setVictoryPlayerId( Player.PLAYER_NONE ); - game.setVictoryTeam( Player.TEAM_NONE ); - return true; - } - else if ( playersAlive == 1 ) { - if (lastPlayer.getTeam() == Player.TEAM_NONE) { - // individual victory - game.setVictoryPlayerId(lastPlayer.getId()); - game.setVictoryTeam(Player.TEAM_NONE); - return true; - } - } - - // did we only find one live team? - if (oneTeamAlive && !unteamedAlive) { - // team victory - game.setVictoryPlayerId(Player.PLAYER_NONE); - game.setVictoryTeam(lastTeam); - return true; - } - - return false; - } - - /** - * Applies board settings. This loads and combines all the boards that - * were specified into one mega-board and sets that board as current. - */ - public void applyBoardSettings() { - mapSettings.replaceBoardWithRandom(MapSettings.BOARD_RANDOM); - mapSettings.replaceBoardWithRandom(MapSettings.BOARD_SURPRISE); - IBoard[] sheetBoards = new IBoard[mapSettings.getMapWidth() * mapSettings.getMapHeight()]; - for (int i = 0; i < mapSettings.getMapWidth() * mapSettings.getMapHeight(); i++) { - sheetBoards[i] = new Board(); - String name = (String)mapSettings.getBoardsSelectedVector().elementAt(i); - boolean isRotated = false; - if ( name.startsWith( Board.BOARD_REQUEST_ROTATION ) ) { - isRotated = true; - name = name.substring( Board.BOARD_REQUEST_ROTATION.length() ); - } - if (name.startsWith(MapSettings.BOARD_GENERATED)) { - sheetBoards[i] = BoardUtilities.generateRandom(mapSettings); - } else { - sheetBoards[i].load( name + ".board"); - BoardUtilities.flip(sheetBoards[i], isRotated, isRotated ); - } - } - IBoard newBoard = BoardUtilities.combine(mapSettings.getBoardWidth(), mapSettings.getBoardHeight(), - mapSettings.getMapWidth(), mapSettings.getMapHeight(), sheetBoards); - game.setBoard(newBoard); - } - - - /** - * Rolls initiative for all the players. - */ - private void rollInitiative() { - if(game.getOptions().booleanOption("individual_initiative")) { - TurnOrdered.rollInitiative(game.getEntitiesVector()); - } else { - // Roll for initative on the teams. - TurnOrdered.rollInitiative(game.getTeamsVector()); - } - - transmitAllPlayerUpdates(); - } - - /** - * Determines the turn oder for a given phase (with individual init) - * @param phase the int id of the phase - */ - private void determineTurnOrderIUI(int phase) { - for (Enumeration loop = game.getEntities(); loop.hasMoreElements();) { - final Entity entity = (Entity)loop.nextElement(); - entity.resetOtherTurns(); - if (entity.isSelectableThisTurn()) { - entity.incrementOtherTurns(); - } - } - // Now, generate the global order of all teams' turns. - TurnVectors team_order = TurnOrdered.generateTurnOrder - ( game.getEntitiesVector(), game ); - - // See if there are any loaded units stranded on immobile transports. - Enumeration strandedUnits = game.getSelectedEntities - ( new EntitySelector() { - public boolean accept( Entity entity ) { - if ( Server.this.game.isEntityStranded(entity) ) - return true; - return false; - } - } ); - - // Now, we collect everything into a single vector. - Vector turns; - - if ( strandedUnits.hasMoreElements() && - game.getPhase() == IGame.PHASE_MOVEMENT ) { - // Add a game turn to unload stranded units, if this - // is the movement phase. - turns = new Vector( team_order.getNormalTurns() + - team_order.getEvenTurns() + 1); - turns.addElement( new GameTurn.UnloadStrandedTurn(strandedUnits) ); - } else { - // No stranded units. - turns = new Vector( team_order.getNormalTurns() + - team_order.getEvenTurns() ); - } - - //add the turns (this is easy) - while(team_order.hasMoreElements()) { - Entity e = (Entity)team_order.nextElement(); - if(e.isSelectableThisTurn()) - turns.addElement(new GameTurn.SpecificEntityTurn(e.getOwnerId(), e.getId())); - } - - // set fields in game - game.setTurnVector(turns); - game.resetTurnIndex(); - - // send turns to all players - send(createTurnVectorPacket()); - } - /** - * Determines the turn oder for a given phase - * @param phase the int id of the phase - */ - private void determineTurnOrder(int phase) { - - if(game.getOptions().booleanOption("individual_initiative")) { - determineTurnOrderIUI(phase); - return; - } - // and/or deploy even according to game options. - boolean infMoveEven = - ( game.getOptions().booleanOption("inf_move_even") && - (game.getPhase() == IGame.PHASE_INITIATIVE || - game.getPhase() == IGame.PHASE_MOVEMENT) ) || - ( game.getOptions().booleanOption("inf_deploy_even") && - game.getPhase() == IGame.PHASE_DEPLOYMENT ); - boolean infMoveMulti = - ( game.getOptions().booleanOption("inf_move_multi") && - (game.getPhase() == IGame.PHASE_INITIATIVE || - game.getPhase() == IGame.PHASE_MOVEMENT) ); - boolean protosMoveEven = - ( game.getOptions().booleanOption("protos_move_even") && - (game.getPhase() == IGame.PHASE_INITIATIVE || - game.getPhase() == IGame.PHASE_MOVEMENT) ) || - ( game.getOptions().booleanOption("protos_deploy_even") && - game.getPhase() == IGame.PHASE_DEPLOYMENT ); - boolean protosMoveMulti = - game.getOptions().booleanOption("protos_move_multi"); - boolean protosFireMulti = !protosMoveMulti && - game.getPhase() == IGame.PHASE_FIRING; - int evenMask = 0; - if ( infMoveEven ) evenMask += GameTurn.CLASS_INFANTRY; - if ( protosMoveEven ) evenMask += GameTurn.CLASS_PROTOMECH; - - // Reset all of the Players' turn category counts - for (Enumeration loop = game.getPlayers(); loop.hasMoreElements();) { - final Player player = (Player) loop.nextElement(); - player.resetEvenTurns(); - player.resetMultiTurns(); - player.resetOtherTurns(); - - // Add turns for protomechs weapons declaration. - if ( protosFireMulti ) { - - // How many Protomechs does the player have? - int numPlayerProtos = game.getSelectedEntityCount - ( new EntitySelector() { - private final int ownerId = player.getId(); - public boolean accept( Entity entity ) { - if ( entity instanceof Protomech && - ownerId == entity.getOwnerId() ) - return true; - return false; - } - } ); - int numProtoUnits = - (int) Math.ceil( (numPlayerProtos) / 5.0 ); - for ( int unit = 0; unit < numProtoUnits; unit++ ) { - if ( protosMoveEven ) player.incrementEvenTurns(); - else player.incrementOtherTurns(); - } - - } // End handle-proto-firing-turns - - } // Handle the next player - - // Go through all entities, and update the turn categories of the - // entity's player. The teams get their totals from their players. - // N.B. protomechs declare weapons fire based on their point. - for (Enumeration loop = game.getEntities(); loop.hasMoreElements();) { - final Entity entity = (Entity)loop.nextElement(); - if (entity.isSelectableThisTurn()) { - final Player player = entity.getOwner(); - if ( entity instanceof Infantry ) { - if ( infMoveEven ) player.incrementEvenTurns(); - else if ( infMoveMulti ) player.incrementMultiTurns(); - else player.incrementOtherTurns(); - } - else if ( entity instanceof Protomech ) { - if ( !protosFireMulti ) { - if ( protosMoveEven ) player.incrementEvenTurns(); - else if ( protosMoveMulti ) player.incrementMultiTurns(); - else player.incrementOtherTurns(); - } - } - else - player.incrementOtherTurns(); - } - } - - // Generate the turn order for the Players *within* - // each Team. Map the teams to their turn orders. - // Count the number of teams moving this turn. - int nTeams = game.getNoOfTeams(); - Hashtable allTeamTurns = new Hashtable( nTeams ); - Hashtable evenTrackers = new Hashtable( nTeams ); - int numTeamsMoving = 0; - for (Enumeration loop = game.getTeams(); loop.hasMoreElements(); ) { - final Team team = (Team) loop.nextElement(); - allTeamTurns.put( team, team.determineTeamOrder(game) ); - - // Track both the number of times we've checked the team for - // "leftover" turns, and the number of "leftover" turns placed. - int[] evenTracker = new int[2]; - evenTracker[0] = 0; - evenTracker[1] = 0; - evenTrackers.put (team, evenTracker); - - // Count this team if it has any "normal" moves. - if (team.getNormalTurns(game) > 0) - numTeamsMoving++; - } - - // Now, generate the global order of all teams' turns. - TurnVectors team_order = TurnOrdered.generateTurnOrder - ( game.getTeamsVector(), game ); - - // See if there are any loaded units stranded on immobile transports. - Enumeration strandedUnits = game.getSelectedEntities - ( new EntitySelector() { - public boolean accept( Entity entity ) { - if ( Server.this.game.isEntityStranded(entity) ) - return true; - return false; - } - } ); - - // Now, we collect everything into a single vector. - Vector turns; - - if ( strandedUnits.hasMoreElements() && - game.getPhase() == IGame.PHASE_MOVEMENT ) { - // Add a game turn to unload stranded units, if this - // is the movement phase. - turns = new Vector( team_order.getNormalTurns() + - team_order.getEvenTurns() + 1); - turns.addElement( new GameTurn.UnloadStrandedTurn(strandedUnits) ); - } else { - // No stranded units. - turns = new Vector( team_order.getNormalTurns() + - team_order.getEvenTurns() ); - } - - // Walk through the global order, assigning turns - // for individual players to the single vector. - // Keep track of how many turns we've added to the vector. - Team prevTeam = null; - int min = team_order.getMin(); - for ( int numTurn = 0; team_order.hasMoreElements(); numTurn++ ) { - Team team = (Team) team_order.nextElement(); - TurnVectors withinTeamTurns = (TurnVectors) allTeamTurns.get(team); - - int[] evenTracker = (int[]) evenTrackers.get (team); - float teamEvenTurns = team.getEvenTurns(); - - // Calculate the number of "even" turns to add for this team. - int numEven = 0; - if (1 == numTeamsMoving) { - // The only team moving should move all "even" units. - numEven += teamEvenTurns; - } - else if (prevTeam == null) { - // Increment the number of times we've checked for "leftovers". - evenTracker[0]++; - - // The first team to move just adds the "baseline" turns. - numEven += teamEvenTurns / min; - } - else if (!team.equals(prevTeam)) { - // Increment the number of times we've checked for "leftovers". - evenTracker[0]++; - - // This wierd equation attempts to spread the "leftover" - // turns accross the turn's moves in a "fair" manner. - // It's based on the number of times we've checked for - // "leftovers" the number of "leftovers" we started with, - // the number of times we've added a turn for a "leftover", - // and the total number of times we're going to check. - numEven += Math.ceil (evenTracker[0] * (teamEvenTurns % min) - / min - 0.5) - evenTracker[1]; - - // Update the number of turns actually added for "leftovers". - evenTracker[1] += numEven; - - // Add the "baseline" number of turns. - numEven += teamEvenTurns / min; - } - - // Record this team for the next move. - prevTeam = team; - - // This may be a "placeholder" for a team without "normal" turns. - if (withinTeamTurns.hasMoreElements()) { - - // Not a placeholder... get the player who moves next. - Player player = (Player) withinTeamTurns.nextElement(); - - // If we've added all "normal" turns, allocate turns - // for the infantry and/or protomechs moving even. - GameTurn turn = null; - if ( numTurn >= team_order.getNormalTurns() ) { - turn = new GameTurn.EntityClassTurn - (player.getId(), evenMask); - } - - // If either Infantry or Protomechs move even, only allow - // the other classes to move during the "normal" turn. - else if ( infMoveEven || protosMoveEven ) { - turn = new GameTurn.EntityClassTurn - (player.getId(), ~evenMask); - } - - // Otherwise, let *anybody* move. - else { - turn = new GameTurn( player.getId() ); - } - turns.addElement(turn); - - } // End team-has-"normal"-turns - - // Add the calculated number of "even" turns. - // Allow the player at least one "normal" turn before the - // "even" turns to help with loading infantry in deployment. - while (numEven > 0 && withinTeamTurns.hasMoreEvenElements()) { - Player evenPlayer = (Player) withinTeamTurns.nextEvenElement(); - turns.addElement - (new GameTurn.EntityClassTurn (evenPlayer.getId(), - evenMask)); - numEven--; - } - } - - // set fields in game - game.setTurnVector(turns); - game.resetTurnIndex(); - - // send turns to all players - send(createTurnVectorPacket()); - - } - - /** - * Write the initiative results to the report - */ - private void writeInitiativeReport(boolean abbreviatedReport) { - // write to report - Report r; - boolean deployment = false; - if (!abbreviatedReport) { - r = new Report(1210); - r.type = Report.PUBLIC; - if ((game.getLastPhase() == IGame.PHASE_DEPLOYMENT) || game.isDeploymentComplete() || !game.shouldDeployThisRound()) { - r.messageId = 1000; - r.add(game.getRoundCount()); - } else { - deployment = true; - if ( game.getRoundCount() == 0 ) { - r.messageId = 1005; - } else { - r.messageId = 1010; - r.add(game.getRoundCount()); - } - } - addReport(r); - - //write seperator - addReport(new Report(1200, Report.PUBLIC)); - } else { - addReport(new Report(1210, Report.PUBLIC)); //newline - } - - if(game.getOptions().booleanOption("individual_initiative")) { - r = new Report(1040, Report.PUBLIC); - addReport(r); - for(Enumeration e = game.getTurns();e.hasMoreElements();) { - GameTurn t = e.nextElement(); - if(t instanceof GameTurn.SpecificEntityTurn) { - Entity entity = game.getEntity(((GameTurn.SpecificEntityTurn)t).getEntityNum()); - r = new Report(1045); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(entity.getInitiative().toString()); - addReport(r); - } else { - Player player = getPlayer( t.getPlayerNum() ); - if ( null != player ) { - r = new Report(1050, Report.PUBLIC); - r.add(player.getName()); - addReport(r); - } - } - } - } else { - for (Enumeration i = game.getTeams(); i.hasMoreElements();) { - final Team team = (Team)i.nextElement(); - - // If there is only one player, list them as the 'team', and - // use the team iniative - if (team.getSize() == 1) { - final Player player = (Player)team.getPlayers().nextElement(); - r = new Report(1015, Report.PUBLIC); - r.add(player.getName()); - r.add(team.getInitiative().toString()); - addReport(r); - } else { - // Multiple players. List the team, then break it down. - r = new Report(1015, Report.PUBLIC); - r.add(Player.teamNames[team.getId()]); - r.add(team.getInitiative().toString()); - addReport(r); - for( Enumeration j = team.getPlayers(); j.hasMoreElements();) { - final Player player = (Player)j.nextElement(); - r = new Report(1015, Report.PUBLIC); - r.indent(); - r.add(player.getName()); - r.add(player.getInitiative().toString()); - addReport(r); - } - } - } - - // The turn order is different in movement phase - // if a player has any "even" moving units. - r = new Report(1020, Report.PUBLIC); - - boolean firstTurn = true; - boolean hasEven = false; - for (Enumeration i = game.getTurns(); i.hasMoreElements();) { - GameTurn turn = (GameTurn)i.nextElement(); - Player player = getPlayer( turn.getPlayerNum() ); - if ( null != player ) { - r.add(player.getName()); - firstTurn = false; - if (player.getEvenTurns() > 0) - hasEven = true; - } - } - r.newlines = 2; - addReport(r); - if (hasEven) { - r = new Report(1021, Report.PUBLIC); - if ((game.getOptions().booleanOption("inf_deploy_even") - || game.getOptions().booleanOption("protos_deploy_even")) && - !(game.getLastPhase() == IGame.PHASE_END_REPORT)) - r.choose(true); - else r.choose(false); - r.indent(); - r.newlines = 2; - addReport(r); - } - } - if (!abbreviatedReport) { - //Wind direction and strength - r = new Report(1025, Report.PUBLIC); - r.add(game.getStringWindDirection()); - if (game.getWindStrength() != -1) { - Report r2 = new Report(1030, Report.PUBLIC); - r2.add(game.getStringWindStrength()); - r.newlines = 0; - addReport(r); - addReport(r2); - } else { - addReport(r); - } - - if (deployment) - addNewLines(); - } - } - - /** - * Marks ineligible entities as not ready for this phase - */ - private void setIneligible(int phase) { - Vector assistants = new Vector(); - boolean assistable = false; - Entity entity = null; - for (Enumeration e = game.getEntities(); e.hasMoreElements();) { - entity = (Entity)e.nextElement(); - if (!entity.isEligibleFor(phase)) { - assistants.addElement(entity); - } else { - assistable=true; - } - } - for (int i=0;iEntity that is loading the unit. - * @param unit - the Entity being loaded. - */ - private void loadUnit( Entity loader, Entity unit ) { - - // Remove the *last* friendly turn (removing the *first* penalizes - // the opponent too much, and re-calculating moves is too hard). - game.removeTurnFor(unit); - send(createTurnVectorPacket()); - - // Load the unit. - loader.load( unit ); - - // The loaded unit is being carried by the loader. - unit.setTransportId( loader.getId() ); - - // Remove the loaded unit from the screen. - unit.setPosition( null ); - - // Update the loaded unit. - this.entityUpdate( unit.getId() ); - } - - /** - * Have the unloader unload the indicated unit. - * The unit being unloaded does *not* gain a turn. - * - * @param unloader - the Entity that is unloading the unit. - * @param unloaded - the Targetable unit being unloaded. - * @param pos - the Coords for the unloaded unit. - * @param facing - the int facing for the unloaded unit. - * @param elevation - the int elevation at which to unload, - * if both loader and loaded units use VTOL movement. - * @return true if the unit was successfully unloaded, - * false if the unit isn't carried in unloader. - */ - private boolean unloadUnit( Entity unloader, Targetable unloaded, - Coords pos, int facing, int elevation ) { - - // We can only unload Entities. - Entity unit = null; - if ( unloaded instanceof Entity ) { - unit = (Entity) unloaded; - } else { - return false; - } - - // Unload the unit. - if ( !unloader.unload( unit ) ) { - return false; - } - - // The unloaded unit is no longer being carried. - unit.setTransportId( Entity.NONE ); - - // Place the unloaded unit onto the screen. - unit.setPosition( pos ); - - // Units unloaded onto the screen are deployed. - if ( pos != null ) { - unit.setDeployed( true ); - } - - // Point the unloaded unit in the given direction. - unit.setFacing( facing ); - unit.setSecondaryFacing( facing ); - - IHex hex = game.getBoard().getHex(pos); - boolean isBridge = hex.containsTerrain(Terrains.PAVEMENT); - - if (unloader.getMovementMode() == IEntityMovementMode.VTOL) { - if (unit.getMovementMode() == IEntityMovementMode.VTOL) { - // Flying units onload to the same elevation as the flying transport - unit.setElevation(elevation); - } else if (game.getBoard().getBuildingAt(pos) != null) { - // non-flying unit onloaded from a flying onto a building - // -> sit on the roff - unit.setElevation(hex.terrainLevel(Terrains.BLDG_ELEV)); - } - } else if (game.getBoard().getBuildingAt(pos) != null) { - // non flying unit unloading units into a building - // -> sit in the building at the same elevation - unit.setElevation(elevation); - } else if (hex.terrainLevel(Terrains.WATER)>0) { - if (unit.getMovementMode() == IEntityMovementMode.HOVER || - unit.getMovementMode() == IEntityMovementMode.HYDROFOIL || - unit.getMovementMode() == IEntityMovementMode.NAVAL || - unit.getMovementMode() == IEntityMovementMode.SUBMARINE || - hex.containsTerrain(Terrains.ICE) || - isBridge) { - // units that can float stay on the surface, or we go on the bridge - // this means elevation 0, because elevation is relative to the surface - unit.setElevation(0); - } - } else { - // default to the floor of the hex. - // unit elevation is relative to the surface - unit.setElevation(hex.floor() - hex.surface()); - } - doSetLocationsExposure(unit, hex, false, unit.getElevation()); - - // Update the unloaded unit. - this.entityUpdate( unit.getId() ); - - // Unloaded successfully. - return true; - } - - /** - * Record that the given building has been affected by the current - * entity's movement. At the end of the entity's movement, notify - * the clients about the updates. - * - * @param bldg - the Building that has been affected. - * @param collapse - a boolean value that specifies that - * the building collapsed (when true). - */ - private void addAffectedBldg( Building bldg, boolean collapse ) { - - // If the building collapsed, then the clients have already - // been notified, so remove it from the notification list. - if ( collapse ) { - System.err.print( "Removing building from a list of " + affectedBldgs.size() + "\n" );//killme - this.affectedBldgs.remove( bldg ); - System.err.print( "... now list of " + affectedBldgs.size() + "\n" );//killme - } - - // Otherwise, make sure that this building is tracked. - else { - this.affectedBldgs.put( bldg, Boolean.FALSE ); - } - } - - /** - * Walk through the building hexes that were affected by the recent - * entity's movement. Notify the clients about the updates to all - * affected entities and uncollapsed buildings. The affected hexes - * is then cleared for the next entity's movement. - */ - private void applyAffectedBldgs() { - - // Build a list of Building updates. - Vector bldgUpdates = new Vector(); - - // Only send a single turn update. - boolean bTurnsChanged = false; - - // Walk the set of buildings. - Enumeration bldgs = this.affectedBldgs.keys(); - while ( bldgs.hasMoreElements() ) { - final Building bldg = (Building) bldgs.nextElement(); - - // Walk through the building's coordinates. - Enumeration bldgCoords = bldg.getCoords(); - while ( bldgCoords.hasMoreElements() ) { - final Coords coords = (Coords) bldgCoords.nextElement(); - - // Walk through the entities at these coordinates. - Enumeration entities = game.getEntities( coords ); - while( entities.hasMoreElements() ) { - final Entity entity = (Entity) entities.nextElement(); - - // Is the entity infantry? - if ( entity instanceof Infantry ) { - - // Is the infantry dead? - if ( entity.isDoomed() || entity.isDestroyed() ) { - - // Has the entity taken a turn? - if ( !entity.isDone() ) { - - // Dead entities don't take turns. - game.removeTurnFor(entity); - bTurnsChanged = true; - - } // End entity-still-to-move - - // Clean out the dead entity. - entity.setDestroyed(true); - game.moveToGraveyard(entity.getId()); - send(createRemoveEntityPacket(entity.getId())); - } - - // Infantry that aren't dead are damaged. - else { - this.entityUpdate( entity.getId() ); - } - - } // End entity-is-infantry - - } // Check the next entity. - - } // Handle the next hex in this building. - - // Add this building to the report. - bldgUpdates.addElement( bldg ); - - } // Handle the next affected building. - - // Did we update the turns? - if ( bTurnsChanged ) { - send(createTurnVectorPacket()); - } - - // Are there any building updates? - if ( !bldgUpdates.isEmpty() ) { - - // Send the building updates to the clients. - sendChangedCFBuildings( bldgUpdates ); - - // Clear the list of affected buildings. - this.affectedBldgs.clear(); - } - - // And we're done. - return; - - } // End private void applyAffectedBldgs() - - /** - * Receives an entity movement packet, and if valid, executes it and ends - * the current turn. - * - */ - private void receiveMovement(Packet packet, int connId) { - Entity entity = game.getEntity(packet.getIntValue(0)); - MovePath md = (MovePath)packet.getObject(1); - - // is this the right phase? - if (game.getPhase() != IGame.PHASE_MOVEMENT) { - System.err.println("error: server got movement packet in wrong phase"); - return; - } - - // can this player/entity act right now? - if (!game.getTurn().isValid(connId, entity, game)) { - System.err.println("error: server got invalid movement packet"); - return; - } - - // looks like mostly everything's okay - processMovement(entity, md); - - // Notify the clients about any building updates. - applyAffectedBldgs(); - - // Update visibility indications if using double blind. - if (doBlind()) { - updateVisibilityIndicator(); - } - - // This entity's turn is over. - // N.B. if the entity fell, a *new* turn has already been added. - endCurrentTurn(entity); - } - - /** - * Steps through an entity movement packet, executing it. - */ - private void processMovement(Entity entity, MovePath md) { - Report r; - boolean sideslipped = false; // for VTOL sideslipping - - // check for fleeing - if (md.contains(MovePath.STEP_FLEE)) { - // Unit has fled the battlefield. - r = new Report(2005, Report.PUBLIC); - r.addDesc(entity); - addReport(r); - - // Is the unit carrying passengers? - final Vector passengers = entity.getLoadedUnits(); - if ( !passengers.isEmpty() ) { - final Enumeration iter = passengers.elements(); - while ( iter.hasMoreElements() ) { - final Entity passenger = (Entity) iter.nextElement(); - // Unit has fled the battlefield. - r = new Report(2010, Report.PUBLIC); - r.indent(); - r.addDesc(passenger); - addReport(r); - game.removeEntity( passenger.getId(), - IEntityRemovalConditions.REMOVE_IN_RETREAT ); - send( createRemoveEntityPacket(passenger.getId(), - IEntityRemovalConditions.REMOVE_IN_RETREAT) ); - } - } - - // Handle any picked up MechWarriors - Enumeration iter = entity.getPickedUpMechWarriors().elements(); - while (iter.hasMoreElements() ) { - Integer mechWarriorId = (Integer)iter.nextElement(); - Entity mw = game.getEntity(mechWarriorId.intValue()); - - // Is the MechWarrior an enemy? - int condition = IEntityRemovalConditions.REMOVE_IN_RETREAT; - r = new Report(2010); - if (mw.isCaptured()) { - r = new Report(2015); - condition = IEntityRemovalConditions.REMOVE_CAPTURED; - } - game.removeEntity( mw.getId(), condition ); - send( createRemoveEntityPacket(mw.getId(), condition) ); - r.addDesc(mw); - r.indent(); - addReport(r); - } - - // Is the unit being swarmed? - final int swarmerId = entity.getSwarmAttackerId(); - if ( Entity.NONE != swarmerId ) { - final Entity swarmer = game.getEntity( swarmerId ); - - // Has the swarmer taken a turn? - if ( !swarmer.isDone() ) { - - // Dead entities don't take turns. - game.removeTurnFor(swarmer); - send(createTurnVectorPacket()); - - } // End swarmer-still-to-move - - // Unit has fled the battlefield. - swarmer.setSwarmTargetId( Entity.NONE ); - entity.setSwarmAttackerId( Entity.NONE ); - r = new Report(2015, Report.PUBLIC); - r.indent(); - r.addDesc(swarmer); - addReport(r); - game.removeEntity( swarmerId, IEntityRemovalConditions.REMOVE_CAPTURED ); - send( createRemoveEntityPacket(swarmerId, - IEntityRemovalConditions.REMOVE_CAPTURED) ); - } - game.removeEntity( entity.getId(), IEntityRemovalConditions.REMOVE_IN_RETREAT ); - send( createRemoveEntityPacket(entity.getId(), - IEntityRemovalConditions.REMOVE_IN_RETREAT) ); - return; - } - - if (md.contains(MovePath.STEP_EJECT)) { - if (entity instanceof Mech) { - r = new Report(2020); - r.subject = entity.getId(); - r.add(entity.getCrew().getName()); - r.addDesc(entity); - addReport(r); - } else if (entity instanceof Tank) { - r = new Report(2025); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - } - addReport( ejectEntity(entity, false)); - - return; - } - - // okay, proceed with movement calculations - Coords lastPos = entity.getPosition(); - Coords curPos = entity.getPosition(); - int curFacing = entity.getFacing(); - int curVTOLElevation = entity.getElevation(); - int distance = 0; - int mpUsed = 0; - int moveType = IEntityMovementType.MOVE_NONE; - int overallMoveType = IEntityMovementType.MOVE_NONE; - // if the entity already used some MPs, - // it previously tried to get up and fell, - // and then got another turn. set moveType - // and overallMoveType accordingly - if (entity.mpUsed > 0) { - moveType = IEntityMovementType.MOVE_WALK; - overallMoveType = IEntityMovementType.MOVE_WALK; - if (entity.mpUsed > entity.getWalkMP()) { - moveType = IEntityMovementType.MOVE_RUN; - overallMoveType = IEntityMovementType.MOVE_RUN; - } - } - boolean firstStep; - boolean wasProne; - boolean fellDuringMovement; - int prevFacing = curFacing; - IHex prevHex = null; - final boolean isInfantry = (entity instanceof Infantry); - AttackAction charge = null; - PilotingRollData rollTarget; - // cache this here, otherwise changing MP in the turn causes - // errorneous gravity PSRs - int cachedGravityLimit = (IEntityMovementType.MOVE_JUMP == moveType)? - entity.getOriginalJumpMP() : entity.getRunMP(false); - - // Compile the move - md.compile(game, entity); - - if (md.contains(MovePath.STEP_CLEAR_MINEFIELD)) { - ClearMinefieldAction cma = new ClearMinefieldAction(entity.getId()); - entity.setClearingMinefield(true); - game.addAction(cma); - } - - // check for MASC failure - if (entity instanceof Mech) { - Vector crits = new Vector(); - Vector vReport = new Vector(); - if (((Mech)entity).checkForMASCFailure(md, vReport, crits)) { - addReport(vReport); - CriticalSlot cs = null; - int loc = Entity.LOC_NONE; - for(Enumeration e = crits.elements();e.hasMoreElements();) { - Object o = e.nextElement(); - if(o instanceof Integer) - loc = (Integer) o; - else if (o instanceof CriticalSlot) { - cs = (CriticalSlot) o; - applyCriticalHit(entity, loc, cs, true); - } - } - // no movement after that - md.clear(); - } - } - - overallMoveType = md.getLastStepMovementType(); - - //check for starting in liquid magma - if(game.getBoard().getHex(entity.getPosition()).terrainLevel(Terrains.MAGMA) == 2 - && entity.getElevation() == 0) { - doMagmaDamage(entity, false); - } - - // iterate through steps - firstStep = true; - fellDuringMovement = false; - /* Bug 754610: Revert fix for bug 702735. */ - MoveStep prevStep = null; - - Vector movePath = new Vector(); - - for (final Enumeration i = md.getSteps(); i.hasMoreElements();) { - final MoveStep step = (MoveStep)i.nextElement(); - wasProne = entity.isProne(); - boolean isPavementStep = step.isPavementStep(); - boolean entityFellWhileAttemptingToStand = false; - - // stop for illegal movement - if (step.getMovementType() == IEntityMovementType.MOVE_ILLEGAL) { - break; - } - - //stop if the entity already killed itself - if(entity.isDestroyed() || entity.isDoomed()) { - break; - } - - // check piloting skill for getting up - rollTarget = entity.checkGetUp(step); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - entity.heatBuildup += 1; - entity.setProne(false); - entity.setHullDown(false); - wasProne = false; - game.resetPSRs(entity); - entityFellWhileAttemptingToStand = !doSkillCheckInPlace(entity, rollTarget); - } - // did the entity just fall? - if (entityFellWhileAttemptingToStand) { - moveType = step.getMovementType(); - curFacing = entity.getFacing(); - curPos = entity.getPosition(); - mpUsed = step.getMpUsed(); - fellDuringMovement = true; - break; - } - - if (step.getType() == MovePath.STEP_UNJAM_RAC) { - entity.setUnjammingRAC(true); - game.addAction(new UnjamAction(entity.getId())); - - break; - } - - if (step.getType() == MovePath.STEP_LAY_MINE) { - LayMinefieldAction lma = new LayMinefieldAction(entity.getId(), step.getMineToLay()); - game.addLayMinefieldAction(lma); - entity.setLayingMines(true); - break; - } - - if (step.getType() == MovePath.STEP_SEARCHLIGHT && entity.hasSpotlight()) { - final boolean SearchOn = !entity.isUsingSpotlight(); - entity.setSpotlightState(SearchOn); - sendServerChat(entity.getDisplayName() + " switched searchlight "+(SearchOn?"on":"off")+"."); - } - - // set most step parameters - moveType = step.getMovementType(); - distance = step.getDistance(); - mpUsed = step.getMpUsed(); - - // check for charge - if (step.getType() == MovePath.STEP_CHARGE) { - if (entity.canCharge()) { - checkExtremeGravityMovement(entity, step, curPos, cachedGravityLimit); - Targetable target = step.getTarget( game ); - ChargeAttackAction caa = new ChargeAttackAction(entity.getId(), target.getTargetType(), target.getTargetId(), target.getPosition()); - entity.setDisplacementAttack(caa); - game.addCharge(caa); - charge = caa; - } else { - sendServerChat("Illegal charge!! I don't think "+entity.getDisplayName() +" should be allowed to charge,"+ - " but the client of "+entity.getOwner().getName()+" disagrees."); - sendServerChat("Please make sure "+entity.getOwner().getName()+" is running MegaMek "+MegaMek.VERSION+ - ", or if that is already the case, submit a bug report at http://megamek.sf.net/"); - return; - } - break; - } - - // check for dfa - if (step.getType() == MovePath.STEP_DFA) { - if (entity.canDFA()) { - checkExtremeGravityMovement(entity, step, curPos, cachedGravityLimit); - Targetable target = step.getTarget( game ); - DfaAttackAction daa = new DfaAttackAction(entity.getId(), target.getTargetType(), target.getTargetId(), target.getPosition()); - entity.setDisplacementAttack(daa); - game.addCharge(daa); - charge = daa; - } else { - sendServerChat("Illegal DFA!! I don't think "+entity.getDisplayName() +" should be allowed to DFA,"+ - " but the client of "+entity.getOwner().getName()+" disagrees."); - sendServerChat("Please make sure "+entity.getOwner().getName()+" is running MegaMek "+MegaMek.VERSION+ - ", or if that is already the case, submit a bug report at http://megamek.sf.net/"); - return; - } - break; - } - - // set last step parameters - curPos = step.getPosition(); - if(moveType != IEntityMovementType.MOVE_JUMP || entity.getJumpType() != Mech.JUMP_BOOSTER) - curFacing = step.getFacing(); - curVTOLElevation = step.getElevation(); - //set elevation in case of collapses - entity.setElevation(step.getElevation()); - - final IHex curHex = game.getBoard().getHex(curPos); - - // check for automatic unstick - if(entity.canUnstickByJumping() && entity.isStuck() && moveType == IEntityMovementType.MOVE_JUMP) { - entity.setStuck(false); - entity.setCanUnstickByJumping(false); - } - - // Check for skid. - rollTarget = entity.checkSkid(moveType, prevHex, overallMoveType, - prevStep, prevFacing, curFacing, - lastPos, curPos, isInfantry, - distance); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - // Have an entity-meaningful PSR message. - boolean psrPassed = true; - if ( entity instanceof Mech ) { - psrPassed = doSkillCheckWhileMoving( entity, lastPos, - lastPos, rollTarget, - true ); - } else { - psrPassed = doSkillCheckWhileMoving( entity, lastPos, - lastPos, rollTarget, - false ); - } - // Does the entity skid? - if ( !psrPassed ){ - - curPos = lastPos; - Coords nextPos = curPos; - IHex nextHex = null; - int skidDistance = 0; - Enumeration targets = null; - Entity target = null; - int curElevation; - int nextElevation; - int skidDirection = prevFacing; - - // All charge damage is based upon - // the pre-skid move distance. - entity.delta_distance = distance-1; - - // Attacks against a skidding target have additional +2. - moveType = IEntityMovementType.MOVE_SKID; - - // What is the first hex in the skid? - if(step.isThisStepBackwards()) { - skidDirection = (skidDirection + 3) % 6; - } - nextPos = curPos.translated( skidDirection ); - nextHex = game.getBoard().getHex( nextPos ); - - // Move the entity a number hexes from curPos in the - // skidDirection direction equal to half the distance moved - // this turn (rounded up), unless something intervenes. - for ( skidDistance = 0; - skidDistance < (int) Math.ceil(entity.delta_distance / 2.0); - skidDistance++ ) { - - // Is the next hex off the board? - if ( !game.getBoard().contains(nextPos) ) { - - // Can the entity skid off the map? - if (game.getOptions().booleanOption("push_off_board")) { - // Yup. One dead entity. - game.removeEntity(entity.getId(), - IEntityRemovalConditions.REMOVE_PUSHED); - send(createRemoveEntityPacket(entity.getId(), - IEntityRemovalConditions.REMOVE_PUSHED)); - r = new Report(2030, Report.PUBLIC); - r.addDesc(entity); - addReport(r); - - // TODO: remove passengers and swarmers. - - // The entity's movement is completed. - return; - - } else { - // Nope. Update the report. - r = new Report(2035); - r.subject = entity.getId(); - r.indent(); - addReport(r); - } - // Stay in the current hex and stop skidding. - break; - } - - // Can the skiding entity enter the next hex from this? - // N.B. can skid along roads. - if ( ( entity.isHexProhibited(curHex) || - entity.isHexProhibited(nextHex) ) && - !Compute.canMoveOnPavement(game, curPos, nextPos) - ) { - // Update report. - r = new Report(2040); - r.subject = entity.getId(); - r.indent(); - r.add(nextPos.getBoardNum(), true); - addReport(r); - - // N.B. the BMRr pg. 22 says that the unit - // "crashes" into the terrain but it doesn't - // mention any damage. - - // Stay in the current hex and stop skidding. - break; - } - - // Hovercraft can "skid" over water. - // all units can skid over ice. - // TODO: allow entities to occupy different levels of - // buildings. - curElevation = curHex.floor(); - nextElevation = nextHex.floor(); - if ( entity instanceof Tank && - entity.getMovementMode() == - IEntityMovementMode.HOVER ) { - if ( curHex.containsTerrain(Terrains.WATER) ) { - curElevation = curHex.surface(); - } - if ( nextHex.containsTerrain(Terrains.WATER) ) { - nextElevation += nextHex.surface(); - } - } else { - if(curHex.containsTerrain(Terrains.ICE)) { - curElevation = curHex.surface(); - } - if(nextHex.containsTerrain(Terrains.ICE)) { - nextElevation = nextHex.surface(); - } - } - - // BMRr pg. 22 - Can't skid uphill, - // but can skid downhill. - if ( curElevation < nextElevation ) { - r = new Report(2045); - r.subject = entity.getId(); - r.indent(); - r.add(nextPos.getBoardNum(), true); - addReport(r); - - // Stay in the current hex and stop skidding. - break; - } - - // Have skidding units suffer falls. - else if ( curElevation > nextElevation + 1 ) { - doEntityFallsInto( entity, curPos, nextPos, - entity.getBasePilotingRoll() ); - doEntityDisplacementMinefieldCheck(entity, curPos, nextPos); - // Stay in the current hex and stop skidding. - break; - } - - // Get any building in the hex. - Building bldg = game.getBoard().getBuildingAt(nextPos); - boolean bldgSuffered = false; - boolean stopTheSkid = false; - // Does the next hex contain an entities? - // ASSUMPTION: hurt EVERYONE in the hex. - // TODO: allow entities to occupy different levels of - // buildings, and only skid into a single level. - targets = game.getEntities( nextPos ); - if ( targets.hasMoreElements()) { - boolean skidChargeHit = false; - while ( targets.hasMoreElements() ) { - target = (Entity) targets.nextElement(); - - // TODO : allow ready targets to move out of way - - // Mechs and vehicles get charged, - // but need to make a to-hit roll - if ( target instanceof Mech || - target instanceof Tank ) { - ChargeAttackAction caa = new ChargeAttackAction(entity.getId(), target.getTargetType(), target.getTargetId(), target.getPosition()); - ToHitData toHit = caa.toHit(game, true); - - // Calculate hit location. - if ( entity instanceof Tank - && ((entity.getMovementMode() == IEntityMovementMode.HOVER) - || (entity.getMovementMode() == IEntityMovementMode.NAVAL) - || (entity.getMovementMode() == IEntityMovementMode.HYDROFOIL)) - && 0 < nextHex.terrainLevel(Terrains.WATER) - && target.getElevation() < 0) { - if ( 2 <= nextHex.terrainLevel(Terrains.WATER) || - target.isProne() ) { - // Hovercraft/Naval Craft can't hit the Mek. - continue; - } - else { - toHit.setHitTable(ToHitData.HIT_PUNCH); - } - } else if ( entity.getHeight() < - target.getHeight() ) { - toHit.setHitTable(ToHitData.HIT_KICK); - } else { - toHit.setHitTable(ToHitData.HIT_NORMAL); - } - toHit.setSideTable - (Compute.targetSideTable(entity, target)); - - // roll - int roll = Compute.d6(2); - // Update report. - r = new Report(2050); - r.subject = entity.getId(); - r.indent(); - r.add(target.getShortName(), true); - r.add(nextPos.getBoardNum(), true); - r.newlines = 0; - addReport(r); - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - roll = -12; - r = new Report(2055); - r.subject = entity.getId(); - r.add(toHit.getDesc()); - r.newlines = 0; - addReport(r); - } else if (toHit.getValue() == ToHitData.AUTOMATIC_SUCCESS) { - r = new Report(2060); - r.subject = entity.getId(); - r.add(toHit.getDesc()); - r.newlines = 0; - addReport(r); - roll = Integer.MAX_VALUE; - } else { - // report the roll - r = new Report(2065); - r.subject = entity.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - } - - // Resolve a charge against the target. - // ASSUMPTION: buildings block damage for - // *EACH* entity charged. - if (roll < toHit.getValue()) { - r = new Report(2070); - r.subject = entity.getId(); - addReport(r); - } else { - // Resolve the charge. - resolveChargeDamage - (entity, target, toHit, skidDirection); - // HACK: set the entity's location - // to the original hex again, for the other targets - if (targets.hasMoreElements()) { - entity.setPosition(curPos); - } - bldgSuffered = true; - skidChargeHit = true; - } - // The skid ends here if the target lives. - if ( !target.isDoomed() && - !target.isDestroyed() && - !game.isOutOfGame(target) ) { - stopTheSkid = true; - } - - // if we don't do this here, - // we can have a mech without a leg - // standing on the field and moving - // as if it still had his leg after - // getting skid-charged. - if (!target.isDone()) { - resolvePilotingRolls(target); - game.resetPSRs(target); - target.applyDamage(); - addNewLines(); - } - - } - - // Resolve "move-through" damage on infantry. - // Infantry inside of a building don't get a - // move-through, but suffer "bleed through" - // from the building. - else if ( target instanceof Infantry && - bldg != null ) { - // Update report. - r = new Report(2075); - r.subject = entity.getId(); - r.indent(); - r.add(target.getShortName(), true); - r.add(nextPos.getBoardNum(), true); - r.newlines = 0; - addReport(r); - - // Infantry don't have different - // tables for punches and kicks - HitData hit = target.rollHitLocation( ToHitData.HIT_NORMAL, Compute.targetSideTable(entity, target) ); - - // Damage equals tonnage, divided by 5. - // ASSUMPTION: damage is applied in one hit. - addReport( - damageEntity(target, hit, - Math.round(entity.getWeight()/5))); - addNewLines(); - } - - // Has the target been destroyed? - if ( target.isDoomed() ) { - - // Has the target taken a turn? - if ( !target.isDone() ) { - - // Dead entities don't take turns. - game.removeTurnFor(target); - send(createTurnVectorPacket()); - - } // End target-still-to-move - - // Clean out the entity. - target.setDestroyed(true); - game.moveToGraveyard(target.getId()); - send(createRemoveEntityPacket(target.getId())); - } - - // Update the target's position, - // unless it is off the game map. - if ( !game.isOutOfGame(target) ) { - entityUpdate( target.getId() ); - } - - } // Check the next entity in the hex. - - // if we missed all the entities in the hex, - // move attacker to side hex - if (!skidChargeHit) { - Coords src = entity.getPosition(); - Coords dest = Compute.getMissedChargeDisplacement - (game, entity.getId(), src, skidDirection); - doEntityDisplacement(entity, src, dest, null); - } else { - // HACK: otherwise, set the entities position to that - // hex's coords, because we had to move the entity - // back earlier for the other targets - entity.setPosition(nextPos); - } - } - - // Handle the building in the hex. - // TODO : BMRr pg. 22, only count buildings that are - // higher than our starting terrain height. - // TODO: allow units to skid on top of buildings. - if ( bldg != null ) { - - // Report that the entity has entered the bldg. - r = new Report(2080); - r.subject = entity.getId(); - r.indent(); - r.add(bldg.getName()); - r.add(nextPos.getBoardNum(), true); - addReport(r); - - // If the building hasn't already suffered - // damage, then apply charge damage to the - // building and displace the entity inside. - // ASSUMPTION: you don't charge the building - // if Tanks or Mechs were charged. - int chargeDamage = ChargeAttackAction.getDamageFor - ( entity ); - if ( !bldgSuffered ) { - Report buildingReport = damageBuilding( bldg, chargeDamage ); - buildingReport.indent(2); - buildingReport.subject = entity.getId(); - addReport(buildingReport); - - // Apply damage to the attacker. - int toAttacker = ChargeAttackAction.getDamageTakenBy - ( entity, bldg ); - HitData hit = entity.rollHitLocation( ToHitData.HIT_NORMAL, - entity.sideTable(nextPos) - ); - addReport( - damageEntity( entity, hit, toAttacker )); - addNewLines(); - - entity.setPosition( nextPos ); - doEntityDisplacementMinefieldCheck(entity, curPos, nextPos); - curPos = nextPos; - } // End buildings-suffer-too - - // Any infantry in the building take damage - // equal to the building being charged. - // ASSUMPTION: infantry take no damage from the - // building absorbing damage from - // Tanks and Mechs being charged. - damageInfantryIn( bldg, chargeDamage ); - - // If a building still stands, then end the skid, - // and add it to the list of affected buildings. - if ( bldg.getCurrentCF() > 0 ) { - stopTheSkid = true; - this.addAffectedBldg( bldg, false ); - } - - } // End handle-building. - - // Do we stay in the current hex and stop skidding? - if ( stopTheSkid ) { - break; - } - // is the next hex a rubble hex? - rollTarget = entity.checkRubbleMove(step, nextHex, - curPos, nextPos); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - doSkillCheckWhileMoving(entity, curPos, nextPos, - rollTarget, true); - if (entity.isProne()) { - // if we fell, stop the skid (see bug 1115608) - break; - } - } - - //check for breaking magma crust - if(curHex.terrainLevel(Terrains.MAGMA) == 1) { - int roll = Compute.d6(1); - r = new Report(2395); - r.addDesc(entity); - r.add(roll); - r.subject = entity.getId(); - addReport(r); - if(roll == 6) { - curHex.removeTerrain(Terrains.MAGMA); - curHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.MAGMA, 2)); - sendChangedHex(curPos); - for(Enumeration e=game.getEntities(curPos);e.hasMoreElements();) { - Entity en = (Entity)e.nextElement(); - if(en != entity) - doMagmaDamage(en, false); - } - } - } - - //check for entering liquid magma - if(curHex.terrainLevel(Terrains.MAGMA) == 2) { - doMagmaDamage(entity, false); - } - - // is the next hex a swamp? - rollTarget = entity.checkSwampMove(step, nextHex, - curPos, nextPos); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - if (!doSkillCheckWhileMoving(entity, curPos, - nextPos, rollTarget, false)){ - entity.setStuck(true); - r = new Report(2081); - r.subject = entity.getId(); - r.add(entity.getDisplayName(), true); - // stay here and stop skidding, see bug 1115608 - break; - } - } - - // Update the position and keep skidding. - entity.setPosition( nextPos ); - doEntityDisplacementMinefieldCheck(entity, curPos, nextPos); - curPos = nextPos; - r = new Report(2085); - r.subject = entity.getId(); - r.indent(); - r.add(curPos.getBoardNum(), true); - addReport(r); - - // Get the next hex in the skid? - nextPos = nextPos.translated( skidDirection ); - nextHex = game.getBoard().getHex( nextPos ); - - } // Handle the next skid hex. - - // If the skidding entity violates stacking, - // displace targets until it doesn't. - curPos = entity.getPosition(); - target = Compute.stackingViolation - (game, entity.getId(), curPos); - while (target != null) { - nextPos = Compute.getValidDisplacement - (game, target.getId(), - target.getPosition(), skidDirection); - // ASSUMPTION - // There should always be *somewhere* that - // the target can go... last skid hex if - // nothing else is available. - if ( null == nextPos ) { - // But I don't trust the assumption fully. - // Report the error and try to continue. - System.err.println( "The skid of " + - entity.getShortName() + - " should displace " + - target.getShortName() + - " in hex " + - curPos.getBoardNum() + - " but there is nowhere to go." - ); - break; - } - // indent displacement - r = new Report(1210, Report.PUBLIC); - r.indent(); - r.newlines = 0; - addReport(r); - doEntityDisplacement(target, curPos, nextPos, null); - doEntityDisplacementMinefieldCheck(entity, curPos, nextPos); - target = Compute.stackingViolation( game, - entity.getId(), - curPos ); - } - - // Mechs suffer damage for every hex skidded. - if ( entity instanceof Mech ) { - // Calculate one half falling damage times skid length. - int damage = skidDistance * (int) Math.ceil(Math.round(entity.getWeight() / 10.0) / 2.0); - - // report skid damage - r = new Report(2090); - r.subject = entity.getId(); - r.indent(); - r.addDesc(entity); - r.add(damage); - addReport(r); - - // standard damage loop - // All skid damage is to the front. - while (damage > 0) { - int cluster = Math.min(5, damage); - HitData hit = entity.rollHitLocation(ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT); - addReport( - damageEntity(entity, hit, cluster)); - damage -= cluster; - } - addNewLines(); - } - - // Clean up the entity if it has been destroyed. - if ( entity.isDoomed() ) { - entity.setDestroyed(true); - game.moveToGraveyard(entity.getId()); - send(createRemoveEntityPacket(entity.getId())); - - // The entity's movement is completed. - return; - } - - // Let the player know the ordeal is over. - r = new Report(2095); - r.subject = entity.getId(); - r.indent(); - addReport(r); - - // set entity parameters - curFacing = entity.getFacing(); - curPos = entity.getPosition(); - entity.setSecondaryFacing( curFacing ); - - // skid consumes all movement - if (md.hasActiveMASC()) { - mpUsed = entity.getRunMP(); - } else { - mpUsed = entity.getRunMPwithoutMASC(); - } - - entity.moved = moveType; - fellDuringMovement = true; - distance = entity.delta_distance; - break; - - } // End failed-skid-psr - - } // End need-skid-psr - if(entity instanceof VTOL) { - rollTarget = ((VTOL)entity).checkSideSlip(moveType, prevHex, overallMoveType, - prevStep, prevFacing, curFacing, - lastPos, curPos, - distance); - if(rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - if(!doSkillCheckWhileMoving(entity,lastPos,curPos,rollTarget, false)) { - //report sideslip - sideslipped = true; - r = new Report(2100); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - Coords newPos = lastPos.translated((prevFacing));//does this work for opposing hex? - // Is the next hex off the board? - if ( !game.getBoard().contains(newPos) ) { - // Can the entity skid off the map? - if (game.getOptions().booleanOption("push_off_board")) { - // Yup. One dead entity. - game.removeEntity(entity.getId(), - IEntityRemovalConditions.REMOVE_PUSHED); - send(createRemoveEntityPacket(entity.getId(), - IEntityRemovalConditions.REMOVE_PUSHED)); - r = new Report(2030); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - - // TODO: remove passengers and swarmers. - // The entity's movement is completed. - return; - } else { - // Nope. Update the report. - r = new Report(2035); - r.subject = entity.getId(); - addReport(r); - } - // Stay in the current hex and stop skidding. - break; - } - IHex hex = game.getBoard().getHex(newPos); - int terrainLevel = hex.ceiling() - hex.surface(); - int newElevation=(entity.calcElevation(game.getBoard().getHex(curPos),game.getBoard().getHex(newPos),curVTOLElevation,step.climbMode())); - if(newElevation<=terrainLevel) { - r = new Report(2105); - r.subject = entity.getId(); - r.add(newPos.getBoardNum(), true); - addReport(r); - - int hitSide=curFacing-prevFacing+6; - hitSide=hitSide % 6; - int table=0; - switch(hitSide) {//quite hackish...I think it ought to work, though. - case 0://can this happen? - table=ToHitData.SIDE_FRONT; - break; - case 1: - case 2: - table=ToHitData.SIDE_LEFT; - break; - case 3: - table=ToHitData.SIDE_REAR; - break; - case 4: - case 5: - table=ToHitData.SIDE_RIGHT; - break; - } - curPos=newPos; - curVTOLElevation=newElevation; - addReport(crashVTOL(((VTOL)entity),true,distance,curPos,curVTOLElevation,table)); - - if((hex.containsTerrain(Terrains.WATER) && !hex.containsTerrain(Terrains.ICE)) - || hex.containsTerrain(Terrains.WOODS) - || hex.containsTerrain(Terrains.JUNGLE)) { - addReport(destroyEntity(entity,"could not land in crash site")); - } else if(newElevation < hex.terrainLevel(Terrains.BLDG_ELEV)){ - addReport(destroyEntity(entity, "crashed into building")); - } - } else { - r = new Report(2110); - r.subject = entity.getId(); - r.add(newPos.getBoardNum(), true); - addReport(r); - entity.setElevation(entity.calcElevation(game.getBoard().getHex(curPos),game.getBoard().getHex(newPos),curVTOLElevation,step.climbMode())); - curPos=newPos; - } - - if(!entity.isDestroyed() && !entity.isDoomed()) { - fellDuringMovement= true; //No, but it should work... - } - break; - } - } - } - - // check if we've moved into rubble - rollTarget = entity.checkRubbleMove(step, curHex, lastPos, curPos); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - doSkillCheckWhileMoving(entity, lastPos, curPos, rollTarget, - true); - } - - //check for breaking magma crust - if(curHex.terrainLevel(Terrains.MAGMA) == 1 - && step.getElevation() == 0 - && step.getMovementType() != IEntityMovementType.MOVE_JUMP) { - int roll = Compute.d6(1); - r = new Report(2395); - r.addDesc(entity); - r.add(roll); - r.subject = entity.getId(); - addReport(r); - if(roll == 6) { - curHex.removeTerrain(Terrains.MAGMA); - curHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.MAGMA, 2)); - sendChangedHex(curPos); - for(Enumeration e=game.getEntities(curPos);e.hasMoreElements();) { - Entity en = (Entity)e.nextElement(); - if(en != entity) - doMagmaDamage(en, false); - } - } - } - - //check for entering liquid magma - if(curHex.terrainLevel(Terrains.MAGMA) == 2 - && step.getElevation() == 0 - && step.getMovementType() != IEntityMovementType.MOVE_JUMP) { - doMagmaDamage(entity, false); - } - - // check if we've moved into a swamp - rollTarget = entity.checkSwampMove(step, curHex, lastPos, curPos); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - if (!doSkillCheckWhileMoving(entity, lastPos, curPos, rollTarget, - false)){ - entity.setStuck(true); - entity.setCanUnstickByJumping(true); - r = new Report(2081); - r.add(entity.getDisplayName()); - r.subject = entity.getId(); - addReport(r); - break; - } - } - - // check to see if we are a mech and we've moved OUT of fire - IHex lastHex = game.getBoard().getHex(lastPos); - if (entity instanceof Mech) { - if ( !lastPos.equals(curPos) - && (lastHex.containsTerrain(Terrains.FIRE) - || lastHex.containsTerrain(Terrains.MAGMA)) - && ( step.getMovementType() != IEntityMovementType.MOVE_JUMP - // Bug #828741 -- jumping bypasses fire, but not on the first step - // getMpUsed -- total MP used to this step - // getMp -- MP used in this step - // the difference will always be 0 on the "first step" of a jump, - // and >0 on a step in the midst of a jump - || ( 0 == step.getMpUsed() - step.getMp() ) ) ) - { - int heat=0; - if(lastHex.containsTerrain(Terrains.FIRE)) - heat+=2; - if(lastHex.terrainLevel(Terrains.MAGMA) == 1) { - heat+=2; - } - else if(lastHex.terrainLevel(Terrains.MAGMA) == 2) { - heat+=5; - } - entity.heatBuildup+=heat; - r = new Report(2115); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(heat); - addReport(r); - } - } - - // check to see if we are not a mech and we've moved INTO fire - if (!(entity instanceof Mech)) { - if ( game.getBoard().getHex(curPos).containsTerrain(Terrains.FIRE) - && !lastPos.equals(curPos) - && step.getMovementType() != IEntityMovementType.MOVE_JUMP - && step.getElevation() <= 1 ) { - if(game.getOptions().booleanOption("vehicle_fires") - && entity instanceof Tank) { - checkForVehicleFire((Tank)entity, false); - } else { - doFlamingDeath(entity); - } - } - } - // check for extreme gravity movement - if (!i.hasMoreElements() && !firstStep) { - checkExtremeGravityMovement(entity, step, curPos, cachedGravityLimit); - } - // check for minefields. - if ((!lastPos.equals(curPos) && (step.getMovementType() != IEntityMovementType.MOVE_JUMP)) - || ((overallMoveType == IEntityMovementType.MOVE_JUMP) && (!i.hasMoreElements()))) { - checkVibrabombs(entity, curPos, false, lastPos, curPos); - if (game.containsMinefield(curPos)) { - Enumeration minefields = game.getMinefields(curPos).elements(); - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - - boolean isOnGround = (!i.hasMoreElements()); - isOnGround |= (step.getMovementType() != IEntityMovementType.MOVE_JUMP); - isOnGround &= step.getElevation() == 0; - if (isOnGround) { - enterMinefield(entity, mf, curPos, curPos, true); - } else if (mf.getType() == Minefield.TYPE_THUNDER_ACTIVE) { - enterMinefield(entity, mf, curPos, curPos, true, 2); - } - } - } - } - - // infantry discovers minefields if they end their move - // in a minefield. - - if (!lastPos.equals(curPos) && - !i.hasMoreElements() && - isInfantry) { - if (game.containsMinefield(curPos)) { - Player owner = entity.getOwner(); - Enumeration minefields = game.getMinefields(curPos).elements(); - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - if (!owner.containsMinefield(mf)) { - r = new Report(2120); - r.subject = entity.getId(); - r.add(entity.getShortName(), true); - addReport(r); - revealMinefield(owner, mf); - } - } - } - } - - // check if we've moved into water - rollTarget = entity.checkWaterMove(step, curHex, lastPos, curPos, - isPavementStep); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - // Swarmers need special handling. - final int swarmerId = entity.getSwarmAttackerId(); - boolean swarmerDone = true; - Entity swarmer = null; - if (Entity.NONE != swarmerId) { - swarmer = game.getEntity( swarmerId ); - swarmerDone = swarmer.isDone(); - } - - // Now do the skill check. - doSkillCheckWhileMoving(entity, lastPos, curPos, rollTarget, - true); - - // Swarming infantry platoons may drown. - if (curHex.terrainLevel(Terrains.WATER) > 1) { - drownSwarmer(entity, curPos); - } - - // Do we need to remove a game turn for the swarmer - if (!swarmerDone && - ( swarmer.isDoomed() || swarmer.isDestroyed() )) { - // We have to diddle with the swarmer's - // status to get its turn removed. - swarmer.setDone( false ); - swarmer.setUnloaded( false ); - - // Dead entities don't take turns. - game.removeTurnFor( swarmer ); - send( createTurnVectorPacket() ); - - // Return the original status. - swarmer.setDone( true ); - swarmer.setUnloaded( true ); - } - - // check for inferno wash-off - checkForWashedInfernos(entity, curPos); - } - - // In water, may or may not be a new hex, neccessary to - // check during movement, for breach damage, and always - // set dry if appropriate - //TODO: possibly make the locations local and set later - doSetLocationsExposure(entity, curHex, - step.getMovementType() == IEntityMovementType.MOVE_JUMP, - step.getElevation()); - - //check for breaking ice by breaking through from below - if(prevHex != null && prevStep != null - && prevStep.getElevation() < 0 - && step.getElevation() == 0 - && prevHex.containsTerrain(Terrains.ICE) - && prevHex.containsTerrain(Terrains.WATER) - && step.getMovementType() != IEntityMovementType.MOVE_JUMP - && !(lastPos.equals(curPos))) { - r = new Report(2410); - r.addDesc(entity); - addReport(r); - resolveIceBroken(lastPos); - } - //check for breaking ice by stepping on it - if(curHex.containsTerrain(Terrains.ICE) - && curHex.containsTerrain(Terrains.WATER) - && step.getMovementType() != IEntityMovementType.MOVE_JUMP - && !(lastPos.equals(curPos))) { - if(step.getElevation() == 0 - ) { - int roll = Compute.d6(1); - r = new Report(2118); - r.addDesc(entity); - r.add(roll); - r.subject = entity.getId(); - addReport(r); - if(roll == 6) { - resolveIceBroken(curPos); - doEntityFallsInto(entity, lastPos, curPos, entity.getBasePilotingRoll(), false); - } - } - //or intersecting it - else if(step.getElevation() + entity.height() == 0) { - r = new Report(2410); - r.addDesc(entity); - addReport(r); - resolveIceBroken(curPos); - } - } - - // Handle loading units. - if ( step.getType() == MovePath.STEP_LOAD ) { - - // Find the unit being loaded. - Entity loaded = null; - Enumeration entities = game.getEntities( curPos ); - while ( entities.hasMoreElements() ) { - - // Is the other unit friendly and not the current entity? - loaded = (Entity)entities.nextElement(); - if ( entity.getOwner() == loaded.getOwner() && - !entity.equals(loaded) ) { - - // The moving unit should be able to load the other - // unit and the other should be able to have a turn. - if ( !entity.canLoad(loaded) || - !loaded.isSelectableThisTurn() ) { - // Something is fishy in Denmark. - System.err.println( entity.getShortName() + - " can not load " + - loaded.getShortName() ); - loaded = null; - } - else { - // Have the deployed unit load the indicated unit. - this.loadUnit( entity, loaded ); - - // Stop looking. - break; - } - - } else { - // Nope. Discard it. - loaded = null; - } - - } // Handle the next entity in this hex. - - // We were supposed to find someone to load. - if ( loaded == null ) { - System.err.println( "Could not find unit for " + - entity.getShortName() + - " to load in " + curPos ); - } - - } // End STEP_LOAD - - // Handle unloading units. - if ( step.getType() == MovePath.STEP_UNLOAD ) { - Targetable unloaded = step.getTarget( game ); - if ( !this.unloadUnit( entity, unloaded, - curPos, curFacing, step.getElevation() ) ) { - System.err.println( "Error! Server was told to unload " + - unloaded.getDisplayName() + - " from " + entity.getDisplayName() + - " into " + curPos.getBoardNum() ); - } - } - - // Handle non-infantry moving into a building. - int buildingMove = entity.checkMovementInBuilding(step, prevStep, curPos, lastPos); - if (buildingMove > 0) { - - // Get the building being exited. - Building bldgExited = null; - if((buildingMove & 1) == 1) - bldgExited = game.getBoard().getBuildingAt( lastPos ); - - // Get the building being entered. - Building bldgEntered = null; - if((buildingMove & 2) == 2) - bldgEntered = game.getBoard().getBuildingAt( curPos ); - - // Get the building being stepped on. - Building bldgStepped = null; - if((buildingMove & 4) == 4) - bldgStepped = game.getBoard().getBuildingAt( curPos ); - - boolean collapsed = false; - //are we passing through a building wall? - if(bldgEntered != null || bldgExited != null) { - // If we're not leaving a building, just handle the "entered". - if ( bldgExited == null) { - collapsed = passBuildingWall( entity, bldgEntered, - lastPos, curPos, - distance, "entering" ); - this.addAffectedBldg( bldgEntered, collapsed ); - } - - // If we're moving withing the same building, just handle - // the "within". - else if ( bldgExited.equals( bldgEntered ) ) { - collapsed = passBuildingWall( entity, bldgEntered, - lastPos, curPos, - distance, "moving in" ); - this.addAffectedBldg( bldgEntered, collapsed ); - } - - // If we have different buildings, roll for each. - else if ( bldgExited != null && bldgEntered != null ) { - collapsed = passBuildingWall( entity, bldgExited, - lastPos, curPos, - distance, "exiting" ); - this.addAffectedBldg( bldgExited, collapsed ); - collapsed = passBuildingWall( entity, bldgEntered, - lastPos, curPos, - distance, "entering" ); - this.addAffectedBldg( bldgEntered, collapsed ); - } - - // Otherwise, just handle the "exited". - else if (bldgExited != null){ - collapsed = passBuildingWall( entity, bldgExited, - lastPos, curPos, - distance, "exiting" ); - this.addAffectedBldg( bldgExited, collapsed ); - } - } - - //stepping on roof, no PSR just check for over weight - if(bldgStepped != null) { - collapsed = checkBuildingCollapseWhileMoving(bldgStepped, entity, curPos); - this.addAffectedBldg( bldgStepped, collapsed ); - } - - // Clean up the entity if it has been destroyed. - if ( entity.isDoomed() ) { - entity.setDestroyed(true); - game.moveToGraveyard(entity.getId()); - send(createRemoveEntityPacket(entity.getId())); - - // The entity's movement is completed. - return; - } - - // TODO: what if a building collapses into rubble? - } - - // did the entity just fall? - if (!wasProne && entity.isProne()) { - curFacing = entity.getFacing(); - curPos = entity.getPosition(); - mpUsed = step.getMpUsed(); - fellDuringMovement = true; - break; - } - - // dropping prone intentionally? - if (step.getType() == MovePath.STEP_GO_PRONE) { - mpUsed = step.getMpUsed(); - rollTarget = entity.checkDislodgeSwarmers(step); - if (rollTarget.getValue() == TargetRoll.CHECK_FALSE) { - // Not being swarmed - entity.setProne(true); - // check to see if we washed off infernos - checkForWashedInfernos(entity, curPos); - break; - } else { - // Being swarmed - entity.setPosition(curPos); - if (doDislodgeSwarmerSkillCheck(entity, - rollTarget, - curPos)) { - // Entity falls - curFacing = entity.getFacing(); - curPos = entity.getPosition(); - fellDuringMovement = true; - break; - } - } - } - - //going hull down - if(step.getType() == MovePath.STEP_HULL_DOWN) { - mpUsed = step.getMpUsed(); - entity.setHullDown(true); - } - - // Track this step's location. - movePath.addElement( new UnitLocation( entity.getId(), - curPos, - curFacing ) ); - - // update lastPos, prevStep, prevFacing & prevHex - lastPos = new Coords(curPos); - prevStep = step; - /* Bug 754610: Revert fix for bug 702735. - if (prevHex != null && !curHex.equals(prevHex)) { - */ - if (!curHex.equals(prevHex)) { - prevFacing = curFacing; - } - prevHex = curHex; - - firstStep = false; - } - - // set entity parameters - entity.setPosition(curPos); - entity.setFacing(curFacing); - entity.setSecondaryFacing(curFacing); - entity.delta_distance = distance; - entity.moved = moveType; - entity.mpUsed = mpUsed; - if (!sideslipped && !fellDuringMovement) { - entity.setElevation(curVTOLElevation); - } - entity.setClimbMode(md.getFinalClimbMode()); - - - - // if we ran with destroyed hip or gyro, we need a psr - rollTarget = entity.checkRunningWithDamage(overallMoveType); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - doSkillCheckInPlace(entity, rollTarget); - } - - // but the danger isn't over yet! landing from a jump can be risky! - if (overallMoveType == IEntityMovementType.MOVE_JUMP && !entity.isMakingDfa()) { - final IHex curHex = game.getBoard().getHex(curPos); - // check for damaged criticals - rollTarget = entity.checkLandingWithDamage(); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - doSkillCheckInPlace(entity, rollTarget); - } - // jumped into water? - int waterLevel = curHex.terrainLevel(Terrains.WATER); - if(curHex.containsTerrain(Terrains.ICE) && waterLevel > 0) { - waterLevel = 0; - //check for breaking ice - int roll = Compute.d6(1); - r = new Report(2122); - r.add(entity.getDisplayName(), true); - r.add(roll); - r.subject = entity.getId(); - addReport(r); - if(roll >= 4) { - //oops! - resolveIceBroken(curPos); - doEntityFallsInto(entity, lastPos, curPos, entity.getBasePilotingRoll(), false); - } - } - rollTarget = entity.checkWaterMove(waterLevel); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - doSkillCheckInPlace(entity, rollTarget); - } - if (waterLevel > 1) { - // Any swarming infantry will be destroyed. - drownSwarmer(entity, curPos); - } - - //check for building collapse - Building bldg = game.getBoard().getBuildingAt(curPos); - if(bldg != null) { - checkForCollapse( bldg, game.getPositionMap() ); - } - - //check for breaking magma crust - if(curHex.terrainLevel(Terrains.MAGMA) == 1) { - int roll = Compute.d6(1); - r = new Report(2395); - r.addDesc(entity); - r.add(roll); - r.subject = entity.getId(); - addReport(r); - if(roll == 6) { - curHex.removeTerrain(Terrains.MAGMA); - curHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.MAGMA, 2)); - sendChangedHex(curPos); - for(Enumeration e=game.getEntities(curPos);e.hasMoreElements();) { - Entity en = (Entity)e.nextElement(); - if(en != entity) - doMagmaDamage(en, false); - } - } - } - - //check for entering liquid magma - if(curHex.terrainLevel(Terrains.MAGMA) == 2) { - doMagmaDamage(entity, false); - } - - // jumped into swamp? maybe stuck! - if (curHex.containsTerrain(Terrains.SWAMP) - || curHex.containsTerrain(Terrains.MAGMA) - || curHex.containsTerrain(Terrains.SNOW) - || curHex.containsTerrain(Terrains.MUD) - || curHex.containsTerrain(Terrains.TUNDRA)) { - if (entity instanceof Mech) { - entity.setStuck(true); - r = new Report(2121); - r.add(entity.getDisplayName(), true); - r.subject = entity.getId(); - addReport(r); - } else if (entity instanceof Infantry) { - PilotingRollData roll = entity.getBasePilotingRoll(); - roll.addModifier(5, "infantry jumping into swamp"); - if (!doSkillCheckWhileMoving(entity, curPos, curPos, roll, false)) { - entity.setStuck(true); - r = new Report(2081); - r.add(entity.getDisplayName()); - r.subject = entity.getId(); - addReport(r); - } - } - } - - // If the entity is being swarmed, jumping may dislodge the fleas. - final int swarmerId = entity.getSwarmAttackerId(); - if ( Entity.NONE != swarmerId ) { - final Entity swarmer = game.getEntity( swarmerId ); - final PilotingRollData roll = - entity.getBasePilotingRoll(); - - entity.addPilotingModifierForTerrain(roll); - - // Add a +4 modifier. - roll.addModifier( 4, "dislodge swarming infantry" ); - - // If the swarmer has Assault claws, give a 1 modifier. - // We can stop looking when we find our first match. - for ( Enumeration iter = swarmer.getMisc(); - iter.hasMoreElements(); ) { - Mounted mount = (Mounted) iter.nextElement(); - EquipmentType equip = mount.getType(); - if ( BattleArmor.ASSAULT_CLAW.equals - (equip.getInternalName()) ) { - roll.addModifier( 1, "swarmer has assault claws" ); - break; - } - } - - // okay, print the info - r = new Report(2125); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - - // roll - final int diceRoll = Compute.d6(2); - r = new Report(2130); - r.subject = entity.getId(); - r.add(roll.getValueAsString()); - r.add(roll.getDesc()); - r.add(diceRoll); - if (diceRoll < roll.getValue()) { - r.choose(false); - addReport(r); - } else { - // Dislodged swarmers don't get turns. - game.removeTurnFor( swarmer ); - send( createTurnVectorPacket() ); - - // Update the report and the swarmer's status. - r.choose(true); - addReport(r); - entity.setSwarmAttackerId( Entity.NONE ); - swarmer.setSwarmTargetId( Entity.NONE ); - - // Did the infantry fall into water? - if ( curHex.terrainLevel(Terrains.WATER) > 0 ) { - // Swarming infantry die. - swarmer.setPosition( curPos ); - r = new Report(2135); - r.subject = entity.getId(); - r.indent(); - r.addDesc(swarmer); - addReport(r); - addReport( - destroyEntity(swarmer, "a watery grave", false)); - } else { - // Swarming infantry take an 11 point hit. - // ASSUMPTION : damage should not be doubled. - r = new Report(2140); - r.subject = entity.getId(); - r.indent(); - r.addDesc(swarmer); - addReport(r); - addReport(damageEntity(swarmer, swarmer.rollHitLocation(ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT), 11)); - addNewLines(); - swarmer.setPosition( curPos ); - } - entityUpdate( swarmerId ); - } // End successful-PSR - - } // End try-to-dislodge-swarmers - - // one more check for inferno wash-off - checkForWashedInfernos(entity, curPos); - - } // End entity-is-jumping - // update entity's locations' exposure - doSetLocationsExposure(entity, game.getBoard().getHex(curPos), false, entity.getElevation()); - - // should we give another turn to the entity to keep moving? - if (fellDuringMovement && entity.mpUsed < entity.getRunMP() - && entity.isSelectableThisTurn() && !entity.isDoomed()) { - entity.applyDamage(); - entity.setDone(false); - GameTurn newTurn = new GameTurn.SpecificEntityTurn(entity.getOwner().getId(), entity.getId()); - game.insertNextTurn(newTurn); - // brief everybody on the turn update - send(createTurnVectorPacket()); - // let everyone know about what just happened - send(entity.getOwner().getId(), createSpecialReportPacket()); - } else { - entity.setDone(true); - } - - // If the entity is being swarmed, update the attacker's position. - final int swarmerId = entity.getSwarmAttackerId(); - if ( Entity.NONE != swarmerId ) { - final Entity swarmer = game.getEntity( swarmerId ); - swarmer.setPosition( curPos ); - // If the hex is on fire, and the swarming infantry is - // *not* Battle Armor, it drops off. - if ( !(swarmer instanceof BattleArmor) && - game.getBoard().getHex(curPos).containsTerrain(Terrains.FIRE) ) { - swarmer.setSwarmTargetId( Entity.NONE ); - entity.setSwarmAttackerId( Entity.NONE ); - r = new Report(2145); - r.subject = entity.getId(); - r.indent(); - r.add(swarmer.getShortName(), true); - addReport(r); - } - entityUpdate( swarmerId ); - } - - // Update the entitiy's position, - // unless it is off the game map. - if (!game.isOutOfGame(entity)) { - entityUpdate( entity.getId(), movePath ); - if (entity.isDoomed()) { - send(createRemoveEntityPacket(entity.getId(), entity.getRemovalCondition())); - } - } - - // if using double blind, update the player on new units he might see - if (doBlind()) { - send(entity.getOwner().getId(), createFilteredEntitiesPacket(entity.getOwner())); - } - - // if we generated a charge attack, report it now - if (charge != null) { - send(createAttackPacket(charge, 1)); - } - } - - - /** - * Delivers a thunder-aug shot to the targetted hex area. - * Thunder-Augs are 7 hexes, though, so... - */ - private void deliverThunderAugMinefield( Coords coords, - int playerId, int damage ) { - Coords mfCoord = null; - for (int dir=0; dir < 7; dir++) { - switch (dir) { - case 6: - // The targeted hex. - mfCoord = new Coords(coords); - break; - default: - // The hex in the dir direction from the targeted hex. - mfCoord = coords.translated(dir); - break; - } - - // Only if this is on the board... - if ( game.getBoard().contains(mfCoord) ) { - Minefield minefield = null; - Enumeration minefields = game.getMinefields(mfCoord).elements(); - // Check if there already are Thunder minefields in the hex. - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - if (mf.getType() == Minefield.TYPE_THUNDER) { - minefield = mf; - break; - } - } - - // Did we find a Thunder minefield in the hex? - // N.B. damage Thunder minefields equals the number of - // missiles, divided by two, rounded up. - if (minefield == null) { - // Nope. Create a new Thunder minefield - minefield = Minefield.createThunderMF - ( mfCoord, playerId, (damage/2 + damage%2) ); - game.addMinefield(minefield); - revealMinefield(minefield); - } else if (minefield.getDamage() < Minefield.MAX_DAMAGE) { - // Yup. Replace the old one. - removeMinefield(minefield); - int newDamage = (damage/2 + damage%2); - newDamage += minefield.getDamage(); - - // Damage from Thunder minefields are capped. - if ( newDamage > Minefield.MAX_DAMAGE ) { - newDamage = Minefield.MAX_DAMAGE; - } - minefield.setDamage(newDamage); - game.addMinefield(minefield); - revealMinefield(minefield); - } - } // End coords-on-board - - } // Handle the next coords - - } - - /** - * Adds a Thunder minefield to the hex. - * @param coords - * @param playerId - * @param damage - */ - private void deliverThunderMinefield( Coords coords, int playerId, - int damage ) { - Minefield minefield = null; - Enumeration minefields = game.getMinefields(coords).elements(); - // Check if there already are Thunder minefields in the hex. - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - if (mf.getType() == Minefield.TYPE_THUNDER) { - minefield = mf; - break; - } - } - - // Create a new Thunder minefield - if (minefield == null) { - minefield = Minefield.createThunderMF(coords, playerId, damage); - // Add to the old one - game.addMinefield(minefield); - revealMinefield(minefield); - } else if (minefield.getDamage() < Minefield.MAX_DAMAGE) { - removeMinefield(minefield); - int oldDamage = minefield.getDamage(); - damage += oldDamage; - damage = (damage > Minefield.MAX_DAMAGE) ? Minefield.MAX_DAMAGE : damage; - minefield.setDamage(damage); - game.addMinefield(minefield); - revealMinefield(minefield); - } - } - - /** - * Adds a Thunder Inferno minefield to the hex. - * @param coords - * @param playerId - * @param damage - */ - private void deliverThunderInfernoMinefield(Coords coords, int playerId, int damage) { - Minefield minefield = null; - Enumeration minefields = game.getMinefields(coords).elements(); - // Check if there already are Thunder minefields in the hex. - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - if (mf.getType() == Minefield.TYPE_THUNDER_INFERNO) { - minefield = mf; - break; - } - } - - // Create a new Thunder Inferno minefield - if (minefield == null) { - minefield = Minefield.createThunderInfernoMF(coords, playerId, damage); - // Add to the old one - game.addMinefield(minefield); - revealMinefield(minefield); - } else if (minefield.getDamage() < Minefield.MAX_DAMAGE) { - removeMinefield(minefield); - int oldDamage = minefield.getDamage(); - damage += oldDamage; - damage = (damage > Minefield.MAX_DAMAGE) ? Minefield.MAX_DAMAGE : damage; - minefield.setDamage(damage); - game.addMinefield(minefield); - revealMinefield(minefield); - } - } - - /** - *Delivers a Arrow IV FASCAM shot to the targetted hex area. - */ - private void deliverFASCAMMinefield( Coords coords, int playerId) { - // Only if this is on the board... - if ( game.getBoard().contains(coords) ) { - Minefield minefield = null; - Enumeration minefields = game.getMinefields(coords).elements(); - // Check if there already are Thunder minefields in the hex. - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - if (mf.getType() == Minefield.TYPE_THUNDER) { - minefield = mf; - break; - } - } - // Did we find a Thunder minefield in the hex? - // N.B. damage of FASCAM minefields is 30 - if (minefield == null) minefield = Minefield.createThunderMF( coords, playerId, 30 ); - removeMinefield(minefield); - minefield.setDamage(30); - game.addMinefield(minefield); - revealMinefield(minefield); - } // End coords-on-board - } - - /** - * Adds a Thunder-Active minefield to the hex. - */ - private void deliverThunderActiveMinefield(Coords coords, int playerId, int damage) { - Minefield minefield = null; - Enumeration minefields = game.getMinefields(coords).elements(); - // Check if there already are Thunder minefields in the hex. - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - if (mf.getType() == Minefield.TYPE_THUNDER_ACTIVE) { - minefield = mf; - break; - } - } - - // Create a new Thunder-Active minefield - if (minefield == null) { - minefield = Minefield.createThunderActiveMF(coords, playerId, damage); - // Add to the old one - game.addMinefield(minefield); - revealMinefield(minefield); - } else if (minefield.getDamage() < Minefield.MAX_DAMAGE) { - removeMinefield(minefield); - int oldDamage = minefield.getDamage(); - damage += oldDamage; - damage = (damage > Minefield.MAX_DAMAGE) ? Minefield.MAX_DAMAGE : damage; - minefield.setDamage(damage); - game.addMinefield(minefield); - revealMinefield(minefield); - } - } - - /** - * Adds a Thunder-Vibrabomb minefield to the hex. - */ - private void deliverThunderVibraMinefield(Coords coords, int playerId, int damage, int sensitivity) { - Minefield minefield = null; - Enumeration minefields = game.getMinefields(coords).elements(); - // Check if there already are Thunder minefields in the hex. - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - if (mf.getType() == Minefield.TYPE_THUNDER_VIBRABOMB) { - minefield = mf; - break; - } - } - - // Create a new Thunder-Vibra minefield - if (minefield == null) { - minefield = Minefield.createThunderVibrabombMF(coords, playerId, damage, sensitivity); - // Add to the old one - game.addVibrabomb(minefield); - revealMinefield(minefield); - } else if (minefield.getDamage() < Minefield.MAX_DAMAGE) { - removeMinefield(minefield); - int oldDamage = minefield.getDamage(); - damage += oldDamage; - damage = (damage > Minefield.MAX_DAMAGE) ? Minefield.MAX_DAMAGE : damage; - minefield.setDamage(damage); - game.addVibrabomb(minefield); - revealMinefield(minefield); - } - } - - /** - * Creates a flare above the target - */ - private void deliverFlare(Coords coords, int rackSize) { - Flare flare = new Flare(coords, Math.max(1, rackSize / 5), 3, 0); - game.addFlare(flare); - } - - private void deliverArtilleryFlare(Coords coords, int radius) { - Flare flare = new Flare(coords, 12, radius, Flare.F_DRIFTING); - game.addFlare(flare); - } - - private void deliverArtillerySmoke(Coords coords) { - if(game.getOptions().booleanOption("maxtech_fire")) { - IHex h = game.getBoard().getHex(coords); - //Unless there is a heavy smoke in the hex already, add one. - if ( h.terrainLevel( Terrains.SMOKE ) < 2 ) { - Report r = new Report(5185, Report.PUBLIC); - r.indent(2); - r.add(coords.getBoardNum()); - addReport(r); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.SMOKE, 2)); - sendChangedHex(coords); - } - } - } - - private void deliverArtilleryInferno(Coords coords, int subjectId) { - IHex h = game.getBoard().getHex(coords); - Report r; - //Unless there is a fire in the hex already, start one. - if ( !h.containsTerrain( Terrains.FIRE ) ) { - r = new Report(3005); - r.subject = subjectId; - r.indent(2); - r.add(coords.getBoardNum()); - addReport(r); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - } - game.getBoard().addInfernoTo( coords, InfernoTracker.INFERNO_IV_ROUND, 1 ); - sendChangedHex(coords); - for(Enumeration impactHexHits = game.getEntities(coords);impactHexHits.hasMoreElements();) { - Entity entity = (Entity)impactHexHits.nextElement(); - entity.infernos.add( InfernoTracker.INFERNO_IV_ROUND, 1 ); - //entity on fire now - r = new Report(3205); - r.indent(2); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(entity.infernos.getTurnsLeftToBurn()); - addReport(r); - } - for(int dir=0;dir<=5;dir++) { - Coords tempcoords=coords.translated(dir); - if(!game.getBoard().contains(tempcoords)) { - continue; - } - if(coords.equals(tempcoords)) { - continue; - } - h = game.getBoard().getHex(tempcoords); - // Unless there is a fire in the hex already, start one. - if ( !h.containsTerrain( Terrains.FIRE ) ) { - r = new Report(3005); - r.subject = subjectId; - r.indent(2); - r.add(tempcoords.getBoardNum()); - addReport(r); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - } - game.getBoard().addInfernoTo( tempcoords, InfernoTracker.INFERNO_IV_ROUND, 1 ); - sendChangedHex(tempcoords); - for (Enumeration splashHexHits = game.getEntities(tempcoords);splashHexHits.hasMoreElements();) { - Entity entity = (Entity)splashHexHits.nextElement(); - entity.infernos.add( InfernoTracker.INFERNO_IV_ROUND, 1 ); - //entity on fire - r = new Report(3205); - r.indent(2); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(entity.infernos.getTurnsLeftToBurn()); - addReport(r); - } - } - } - - /** - * When an entity enters a conventional or Thunder minefield. - */ - private void enterMinefield(Entity entity, Minefield mf, Coords src, Coords dest, boolean resolvePSRNow) { - enterMinefield(entity, mf, src, dest, resolvePSRNow, 0); - } - - /** - * When an entity enters a conventional or Thunder minefield. - * @param entity - * - * @param mf - * @param src - * @param dest - * @param resolvePSRNow - * @param hitMod - */ - private void enterMinefield(Entity entity, Minefield mf, Coords src, Coords dest, boolean resolvePSRNow, int hitMod) { - Report r; - // Bug 954272: Mines shouldn't work underwater - if (!game.getBoard().getHex(mf.getCoords()).containsTerrain(Terrains.WATER) - || game.getBoard().getHex(mf.getCoords()).containsTerrain(Terrains.PAVEMENT) - || game.getBoard().getHex(mf.getCoords()).containsTerrain(Terrains.ICE)) { - switch (mf.getType()) { - case (Minefield.TYPE_CONVENTIONAL) : - case (Minefield.TYPE_THUNDER) : - case (Minefield.TYPE_THUNDER_ACTIVE) : - if (mf.getTrigger() != Minefield.TRIGGER_NONE && - Compute.d6(2) < (mf.getTrigger()+hitMod)) { - return; - } - - r = new Report(2150); - r.subject = entity.getId(); - r.add(entity.getShortName(), true); - r.add(mf.getCoords().getBoardNum(), true); - addReport(r); - HitData hit = entity.rollHitLocation(Minefield.TO_HIT_TABLE, Minefield.TO_HIT_SIDE); - addReport( damageEntity(entity, hit, mf.getDamage())); - addNewLines(); - - if (resolvePSRNow) { - resolvePilotingRolls(entity, true, src, dest); - } - - if (!mf.isOneUse()) { - revealMinefield(mf); - } else { - removeMinefield(mf); - } - break; - - case (Minefield.TYPE_THUNDER_INFERNO) : - if (mf.getTrigger() != Minefield.TRIGGER_NONE && - Compute.d6(2) < (mf.getTrigger()+hitMod)) { - return; - } - entity.infernos.add( InfernoTracker.STANDARD_ROUND, mf.getDamage() ); - //report hitting an inferno mine - r = new Report(2155); - r.subject = entity.getId(); - r.add(entity.getShortName(), true); - r.add(mf.getCoords().getBoardNum(), true); - r.addDesc(entity); - r.add(entity.infernos.getTurnsLeftToBurn()); - addReport(r); - - // start a fire in the targets hex - IHex h = game.getBoard().getHex(dest); - - // Unless there a fire in the hex already, start one. - if ( !h.containsTerrain( Terrains.FIRE ) ) { - r = new Report(3005); - r.subject = entity.getId(); - r.add(dest.getBoardNum(), true); - addReport(r); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - } - game.getBoard().addInfernoTo(dest, InfernoTracker.STANDARD_ROUND, 1); - sendChangedHex(dest); - break; - } - } - } - - /** - * Checks to see if an entity sets off any vibrabombs. - */ - private void checkVibrabombs(Entity entity, Coords coords, boolean displaced) { - checkVibrabombs(entity, coords, displaced, null, null); - } - - private void checkVibrabombs(Entity entity, Coords coords, boolean displaced, Coords lastPos, Coords curPos) { - // Only mechs can set off vibrabombs. - if (!(entity instanceof Mech)) { - return; - } - - int mass = (int) entity.getWeight(); - - Enumeration e = game.getVibrabombs().elements(); - - while (e.hasMoreElements()) { - Minefield mf = (Minefield) e.nextElement(); - - // Bug 954272: Mines shouldn't work underwater, and BMRr says Vibrabombs are mines - if (game.getBoard().getHex(mf.getCoords()).containsTerrain(Terrains.WATER) - && !game.getBoard().getHex(mf.getCoords()).containsTerrain(Terrains.PAVEMENT) - && !game.getBoard().getHex(mf.getCoords()).containsTerrain(Terrains.ICE)) { - continue; - } - - // Mech weighing 10 tons or less can't set off the bomb - if (mass <= mf.getSetting() - 10) { - continue; - } - - int effectiveDistance = (mass - mf.getSetting()) / 10; - int actualDistance = coords.distance(mf.getCoords()); - - if (actualDistance <= effectiveDistance) { - Report r = new Report(2156); - r.subject = entity.getId(); - r.add(entity.getShortName(), true); - r.add(mf.getCoords().getBoardNum(), true); - addReport(r); - explodeVibrabomb(mf); - } - - // Hack; when moving, the Mech isn't in the hex during - // the movement. - if (!displaced && actualDistance == 0) { - //report getting hit by vibrabomb - Report r = new Report(2160); - r.subject = entity.getId(); - r.add(entity.getShortName(), true); - addReport(r); - HitData hit = entity.rollHitLocation(Minefield.TO_HIT_TABLE, Minefield.TO_HIT_SIDE); - addReport( damageEntity(entity, hit, mf.getDamage())); - addNewLines(); - resolvePilotingRolls(entity, true, lastPos, curPos); - // we need to apply Damage now, in case the entity lost a leg, - // otherwise it won't get a leg missing mod if it hasn't yet - // moved and lost a leg, see bug 1071434 for an example - entity.applyDamage(); - } - } - } - /** - * Remove all minefields in the specified coords from the game - * @param coords The Coords from which to remove minefields - */ - private void removeMinefieldsFrom(Coords coords) { - Vector v = game.getMinefields(coords); - while (v.elements().hasMoreElements()) { - Minefield mf = (Minefield)v.elements().nextElement(); - removeMinefield(mf); - } - - } - - /** - * Removes the minefield from the game. - * @param mf The Minefield to remove - */ - private void removeMinefield(Minefield mf) { - if (game.containsVibrabomb(mf)) { - game.removeVibrabomb(mf); - } - game.removeMinefield(mf); - - Enumeration players = game.getPlayers(); - while (players.hasMoreElements()) { - Player player = (Player) players.nextElement(); - removeMinefield(player, mf); - } - } - - /** - * Removes the minfield from a player. - * @param player The Player who's minefield should be removed - * @param mf The Minefield to be removed - */ - private void removeMinefield(Player player, Minefield mf) { - if (player.containsMinefield(mf)) { - player.removeMinefield(mf); - send(player.getId(), new Packet(Packet.COMMAND_REMOVE_MINEFIELD, mf)); - } - } - - /** - * Reveals a minefield for all players. - * @param mf The Minefield to be revealed - */ - private void revealMinefield(Minefield mf) { - Enumeration players = game.getPlayers(); - while (players.hasMoreElements()) { - Player player = (Player) players.nextElement(); - revealMinefield(player, mf); - } - } - - /** - * Reveals a minefield for a player. - * @param player The Player who's minefiled should be revealed - * @param mf The Minefield to be revealed - */ - private void revealMinefield(Player player, Minefield mf) { - if (!player.containsMinefield(mf)) { - player.addMinefield(mf); - send(player.getId(), new Packet(Packet.COMMAND_REVEAL_MINEFIELD, mf)); - } - } - - /** - * Explodes a vibrabomb. - * @param mf The Minefield to explode - */ - private void explodeVibrabomb(Minefield mf) { - Enumeration targets = game.getEntities(mf.getCoords()); - Report r; - - while (targets.hasMoreElements()) { - Entity entity = (Entity) targets.nextElement(); - - // check for the "no_premove_vibra" option - // If it's set, and the target has not yet moved, - // it doesn't get damaged. - if (!entity.isDone() && game.getOptions().booleanOption("no_premove_vibra")) { - r = new Report(2157); - r.subject = entity.getId(); - r.add(entity.getShortName(), true); - addReport(r); - continue; - } - //report hitting vibrabomb - r = new Report(2160); - r.subject = entity.getId(); - r.add(entity.getShortName(), true); - addReport(r); - - if (mf.getType() == Minefield.TYPE_VIBRABOMB) { - // normal vibrabombs do all damage in one pack - HitData hit = entity.rollHitLocation(Minefield.TO_HIT_TABLE, Minefield.TO_HIT_SIDE); - addReport( damageEntity(entity, hit, mf.getDamage())); - addNewLines(); - } else if (mf.getType() == Minefield.TYPE_THUNDER_VIBRABOMB) { - int damage = mf.getDamage(); - HitData hit = entity.rollHitLocation(Minefield.TO_HIT_TABLE, Minefield.TO_HIT_SIDE); - addReport( damageEntity(entity, hit, damage)); - } - - resolvePilotingRolls(entity, true, entity.getPosition(), entity.getPosition()); - // we need to apply Damage now, in case the entity lost a leg, - // otherwise it won't get a leg missing mod if it hasn't yet - // moved and lost a leg, see bug 1071434 for an example - game.resetPSRs(entity); - entity.applyDamage(); - addNewLines(); - entityUpdate(entity.getId()); - } - - if (!mf.isOneUse()) { - revealMinefield(mf); - } else { - removeMinefield(mf); - } - } - - /** - * drowns any units swarming the entity - * @param entity The Entity that is being swarmed - * @param pos The Coords the entity is at - */ - private void drownSwarmer(Entity entity, Coords pos) { - // Any swarming infantry will be destroyed. - final int swarmerId = entity.getSwarmAttackerId(); - if ( Entity.NONE != swarmerId ) { - final Entity swarmer = game.getEntity( swarmerId ); - // Only *platoons* drown while swarming. - if (!(swarmer instanceof BattleArmor)) { - swarmer.setSwarmTargetId( Entity.NONE ); - entity.setSwarmAttackerId( Entity.NONE ); - swarmer.setPosition( pos ); - Report r = new Report(2165); - r.subject = entity.getId(); - r.indent(); - r.add(entity.getShortName(), true); - addReport(r); - addReport( destroyEntity(swarmer, "a watery grave", false)); - entityUpdate( swarmerId ); - } - } - } - - /** - * Checks to see if we may have just washed off infernos. Call after - * a step which may have done this. - * - * @param entity The Entity that is being checked - * @param coords The Coords the entity is at - */ - void checkForWashedInfernos(Entity entity, Coords coords) { - IHex hex = game.getBoard().getHex(coords); - int waterLevel = hex.terrainLevel(Terrains.WATER); - // Mech on fire with infernos can wash them off. - if (!(entity instanceof Mech) || !entity.infernos.isStillBurning()) { - return; - } - // Check if entering depth 2 water or prone in depth 1. - if (waterLevel > 0 && entity.absHeight() < 0) { - washInferno(entity, coords); - } - } - - /** - * Washes off an inferno from a mech and adds it to the (water) hex. - * - * @param entity The Entity that is taking a bath - * @param coords The Coords the entity is at - */ - void washInferno(Entity entity, Coords coords) { - game.getBoard().addInfernoTo( coords, InfernoTracker.STANDARD_ROUND, 1 ); - entity.infernos.clear(); - - // Start a fire in the hex? - IHex hex = game.getBoard().getHex(coords); - Report r = new Report(2170); - r.subject = entity.getId(); - r.addDesc(entity); - if ( hex.containsTerrain(Terrains.FIRE) ) { - } else { - r.messageId = 2175; - hex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - } - addReport(r); - sendChangedHex(coords); - } - - /** - * Add heat from the movement phase - */ - public void addMovementHeat() { - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - Entity entity = (Entity)i.nextElement(); - // build up heat from movement - if (entity.moved == IEntityMovementType.MOVE_NONE) { - entity.heatBuildup += entity.getStandingHeat(); - } else if (entity.moved == IEntityMovementType.MOVE_WALK - || entity.moved == IEntityMovementType.MOVE_VTOL_WALK) { - entity.heatBuildup += entity.getWalkHeat(); - } else if (entity.moved == IEntityMovementType.MOVE_RUN - || entity.moved == IEntityMovementType.MOVE_VTOL_RUN - || entity.moved == IEntityMovementType.MOVE_SKID) { - entity.heatBuildup += entity.getRunHeat(); - } else if (entity.moved == IEntityMovementType.MOVE_JUMP) { - entity.heatBuildup += entity.getJumpHeat(entity.delta_distance); - } - } - } - - /** - * Set the locationsexposure of an entity - * - * @param entity The Entity who's exposure is being set - * @param hex The IHex the entity is in - * @param isJump a boolean value wether the entity is jumping - * @param elevation the elevation the entity should be at. - */ - - public void doSetLocationsExposure(Entity entity, IHex hex, boolean isJump, int elevation) { - if ( hex.terrainLevel(Terrains.WATER) > 0 - && !isJump - && elevation < 0) { - if (entity instanceof Mech - && !entity.isProne() - && hex.terrainLevel(Terrains.WATER) == 1) { - for (int loop = 0; loop < entity.locations(); loop++) { - if (game.getOptions().booleanOption("vacuum")) - entity.setLocationStatus(loop, ILocationExposureStatus.VACUUM); - else entity.setLocationStatus(loop, ILocationExposureStatus.NORMAL); - } - entity.setLocationStatus(Mech.LOC_RLEG, ILocationExposureStatus.WET); - entity.setLocationStatus(Mech.LOC_LLEG, ILocationExposureStatus.WET); - addReport( - breachCheck(entity, Mech.LOC_RLEG, hex)); - addReport( - breachCheck(entity, Mech.LOC_LLEG, hex)); - if (entity instanceof QuadMech) { - entity.setLocationStatus(Mech.LOC_RARM, ILocationExposureStatus.WET); - entity.setLocationStatus(Mech.LOC_LARM, ILocationExposureStatus.WET); - addReport( - breachCheck(entity, Mech.LOC_RARM, hex)); - addReport( - breachCheck(entity, Mech.LOC_LARM, hex)); - } - } else { - for (int loop = 0; loop < entity.locations(); loop++) { - entity.setLocationStatus(loop, ILocationExposureStatus.WET); - addReport( breachCheck(entity, loop, hex)); - } - } - } else { - for (int loop = 0; loop < entity.locations(); loop++) { - if (game.getOptions().booleanOption("vacuum")) - entity.setLocationStatus(loop, ILocationExposureStatus.VACUUM); - else entity.setLocationStatus(loop, ILocationExposureStatus.NORMAL); - } - } - - } - - /** - * Do a piloting skill check while standing still (during the - * movement phase). - * - * @param entity The Entity that should make the PSR - * @param roll The PilotingRollData to be used for this PSR. - * - *@param Returns true if check succeeds, false otherwise. - * - */ - private boolean doSkillCheckInPlace(Entity entity, PilotingRollData roll) { - if (roll.getValue() == TargetRoll.AUTOMATIC_SUCCESS) { - return true; - } - - // non-mechs should never get here - if (! (entity instanceof Mech) || entity.isProne()) { - return true; - } - - // okay, print the info - Report r = new Report(2180); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(roll.getLastPlainDesc(), true); - addReport(r); - - // roll - final int diceRoll = Compute.d6(2); - r = new Report(2185); - r.subject = entity.getId(); - r.add(roll.getValueAsString()); - r.add(roll.getDesc()); - r.add(diceRoll); - boolean suc; - if (diceRoll < roll.getValue()) { - r.choose(false); - addReport(r); - doEntityFall(entity, roll); - suc = false; - } else { - r.choose(true); - addReport(r); - suc = true; - } - - return suc; - } - - /** - * Do a Piloting Skill check to dislogde swarming infantry. - * - * @param entity The Entity that is doing the dislodging. - * @param roll The PilotingRollData for this PSR. - * @param curPos The Coords the entity is at. - * @return true if the dislodging is successful. - */ - private boolean doDislodgeSwarmerSkillCheck - (Entity entity, PilotingRollData roll, Coords curPos) - { - // okay, print the info - Report r = new Report(2180); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(roll.getLastPlainDesc(), true); - addReport(r); - - // roll - final int diceRoll = Compute.d6(2); - r = new Report(2190); - r.subject = entity.getId(); - r.add(roll.getValueAsString()); - r.add(roll.getDesc()); - r.add(diceRoll); - if (diceRoll < roll.getValue()) { - r.choose(false); - addReport(r); - return false; - } else { - // Dislodged swarmers don't get turns. - int swarmerId = entity.getSwarmAttackerId(); - final Entity swarmer = game.getEntity( swarmerId ); - game.removeTurnFor( swarmer ); - send( createTurnVectorPacket() ); - - // Update the report and cause a fall. - r.choose(true); - addReport(r); - entity.setPosition( curPos ); - doEntityFallsInto(entity, curPos, curPos, roll, false); - return true; - } - } - - /** - * Do a piloting skill check while moving. - * - * @param entity - the Entity that must roll. - * @param src - the Coords the entity is moving from. - * @param dest - the Coords the entity is moving to. - * This value can be the same as src for in-place checks. - * @param reason - the PilotingRollData that is causing - * this check. - * @param isFallRoll - a boolean flag that indicates that - * failure will result in a fall or not. Falls will be processed. - * @return true if the pilot passes the skill check. - */ - private boolean doSkillCheckWhileMoving( Entity entity, - Coords src, - Coords dest, - PilotingRollData roll, - boolean isFallRoll ) { - boolean result = true; - boolean fallsInPlace; - - // Start the info for this roll. - Report r = new Report(1210); - r.subject = entity.getId(); - r.addDesc(entity); - - // Will the entity fall in the source or destination hex? - if ( src.equals(dest) ) { - fallsInPlace = true; - r.messageId = 2195; - r.add(src.getBoardNum(), true); - } else { - fallsInPlace = false; - r.messageId = 2200; - r.add(src.getBoardNum(), true); - r.add(dest.getBoardNum(), true); - } - - // Finish the info. - r.add(roll.getLastPlainDesc(), true); - addReport(r); - - // roll - final int diceRoll = Compute.d6(2); - r = new Report(2185); - r.subject = entity.getId(); - r.add(roll.getValueAsString()); - r.add(roll.getDesc()); - r.add(diceRoll); - if (diceRoll < roll.getValue()) { - // Does failing the PSR result in a fall. - if ( isFallRoll ) { - r.choose(false); - addReport(r); - doEntityFallsInto( entity, - (fallsInPlace ? dest : src), - (fallsInPlace ? src : dest), - roll ); - } else { - r.messageId = 2190; - r.choose(false); - addReport(r); - entity.setPosition( fallsInPlace ? src : dest ); - } - result = false; - } else { - r.choose(true); - addReport(r); - } - return result; - } - - - /** - * The entity falls into the hex specified. Check for any conflicts and - * resolve them. Deal damage to faller. - * - * @param entity The Entity that is falling. - * @param src The Coords of the source hex. - * @param dest The Coords of the destination hex. - * @param roll The PilotingRollData to be used for PSRs induced - * by the falling. - */ - private void doEntityFallsInto(Entity entity, Coords src, Coords dest, PilotingRollData roll) { - doEntityFallsInto(entity, src, dest, roll, true); - } - - /** - * The entity falls into the hex specified. Check for any conflicts and - * resolve them. Deal damage to faller. - * - * @param entity The Entity that is falling. - * @param src The Coords of the source hex. - * @param dest The Coords of the destination hex. - * @param roll The PilotingRollData to be used for PSRs induced - * by the falling. - * @param causeAffa The boolean value wether this fall should - * be able to cause an accidental fall from above - */ - private void doEntityFallsInto(Entity entity, Coords src, Coords dest, PilotingRollData roll, boolean causeAffa) { - final IHex srcHex = game.getBoard().getHex(src); - final IHex destHex = game.getBoard().getHex(dest); - final int srcHeightAboveFloor = entity.getElevation() + srcHex.depth(); - final int fallElevation = Math.max(0, srcHex.floor() + srcHeightAboveFloor - destHex.floor()); - int direction = src.direction(dest); - Report r; - // check entity in target hex - Entity affaTarget = game.getAffaTarget(dest, entity); - // falling mech falls - r = new Report(2205); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(fallElevation); - r.add(dest.getBoardNum(), true); - addReport(r); - - // if hex was empty, deal damage and we're done - if (affaTarget == null) { - doEntityFall(entity, dest, fallElevation, roll); - return; - } - - // hmmm... somebody there... problems. - if (fallElevation >= 2 && causeAffa && affaTarget != null) { - // accidental fall from above: havoc! - r = new Report(2210); - r.subject = entity.getId(); - r.addDesc(affaTarget); - addReport(r); - - // determine to-hit number - ToHitData toHit = new ToHitData(7, "base"); - if (affaTarget instanceof Tank ) { - toHit = new ToHitData(TargetRoll.AUTOMATIC_FAIL, "Target is a Tank"); - } else { - toHit.append(Compute.getTargetMovementModifier(game, affaTarget.getId())); - toHit.append(Compute.getTargetTerrainModifier(game, affaTarget)); - } - - if (toHit.getValue() != TargetRoll.AUTOMATIC_FAIL) { - // collision roll - final int diceRoll = Compute.d6(2); - r = new Report(2215); - r.subject = entity.getId(); - r.add(toHit.getValue()); - r.add(diceRoll); - if (diceRoll >= toHit.getValue()) { - r.choose(true); - addReport(r); - // deal damage to target - int damage = Compute.getAffaDamageFor(entity); - r = new Report(2220); - r.subject = affaTarget.getId(); - r.addDesc(affaTarget); - r.add(damage); - addReport(r); - while (damage > 0) { - int cluster = Math.min(5, damage); - HitData hit = affaTarget.rollHitLocation(ToHitData.HIT_PUNCH, ToHitData.SIDE_FRONT); - addReport( - damageEntity(affaTarget, hit, cluster)); - damage -= cluster; - } - addNewLines(); - - // attacker falls as normal, on his back - // only given a modifier, so flesh out into a full piloting roll - PilotingRollData pilotRoll = entity.getBasePilotingRoll(); - pilotRoll.append(roll); - entity.addPilotingModifierForTerrain(pilotRoll, dest); - doEntityFall(entity, dest, fallElevation, 3, pilotRoll); - doEntityDisplacementMinefieldCheck(entity, src, dest); - - // defender pushed away, or destroyed, if there is a stacking violation - Entity violation = Compute.stackingViolation(game, entity.getId(), dest); - if (violation != null) { - Coords targetDest = Compute.getValidDisplacement(game, violation.getId(), dest, direction); - if (targetDest != null) { - doEntityDisplacement(affaTarget, dest, targetDest, new PilotingRollData(violation.getId(), 2, "fallen on")); - // Update the violating entity's postion on the client. - entityUpdate( affaTarget.getId() ); - } else { - // ack! automatic death! Tanks - // suffer an ammo/power plant hit. - // TODO : a Mech suffers a Head Blown Off crit. - addReport( - destroyEntity(affaTarget, "impossible displacement", (violation instanceof Mech), (violation instanceof Mech))); - } - } - return; - } else { - r.choose(false); - addReport(r); - } - } else { - //automatic miss - r = new Report(2225); - r.add(toHit.getDesc()); - addReport(r); - } - // ok, we missed, let's fall into a valid other hex and not cause an AFFA while doing so - Coords targetDest = Compute.getValidDisplacement(game, entity.getId(), dest, direction); - if (targetDest != null) { - doEntityFallsInto(entity, src, targetDest, new PilotingRollData(entity.getId(), PilotingRollData.IMPOSSIBLE, "pushed off a cliff"), false); - // Update the entity's postion on the client. - entityUpdate( entity.getId() ); - } else { - // ack! automatic death! Tanks - // suffer an ammo/power plant hit. - // TODO : a Mech suffers a Head Blown Off crit. - addReport( destroyEntity(entity, "impossible displacement", (entity instanceof Mech), (entity instanceof Mech))); - } - } else { - // damage as normal - doEntityFall(entity, dest, fallElevation, roll); - Entity violation = Compute.stackingViolation(game, entity.getId(), dest); - if(violation != null) { - // target gets displaced, because of low elevation - Coords targetDest = Compute.getValidDisplacement(game, entity.getId(), dest, direction); - doEntityDisplacement(violation, dest, targetDest, new PilotingRollData(violation.getId(), 0, "domino effect")); - // Update the violating entity's postion on the client. - entityUpdate( violation.getId() ); - } - } - } - - /** - * Displace a unit in the direction specified. The unit moves in that - * direction, and the piloting skill roll is used to determine if it - * falls. The roll may be unnecessary as certain situations indicate an - * automatic fall. Rolls are added to the piloting roll list. - */ - private void doEntityDisplacement(Entity entity, Coords src, Coords dest, - PilotingRollData roll) { - Report r; - if (!game.getBoard().contains(dest)) { - // set position anyway, for pushes moving through and stuff like - // that - entity.setPosition(dest); - if (!entity.isDoomed()) { - game.removeEntity(entity.getId(), - IEntityRemovalConditions.REMOVE_PUSHED); - send(createRemoveEntityPacket(entity.getId(), - IEntityRemovalConditions.REMOVE_PUSHED)); - //entity forced from the field - r = new Report(2230); - r.addDesc(entity); - addReport(r); - // TODO: remove passengers and swarmers. - } - return; - } - final IHex srcHex = game.getBoard().getHex(src); - final IHex destHex = game.getBoard().getHex(dest); - final int direction = src.direction(dest); - - // Handle null hexes. - if ( srcHex == null || destHex == null ) { - System.err.println( "Can not displace " + entity.getShortName() + - " from " + src + - " to " + dest + "." ); - return; - } - int fallElevation = entity.elevationOccupied(srcHex) - entity.elevationOccupied(destHex); - if (fallElevation > 1) { - if(roll == null) - roll = entity.getBasePilotingRoll(); - doEntityFallsInto(entity, src, dest, roll); - return; - } else { - //move the entity into the new location gently - entity.setPosition(dest); - entity.setElevation(entity.elevationOccupied(destHex) - destHex.surface()); - Entity violation = Compute.stackingViolation(game, entity.getId(), dest); - if (violation == null) { - // move and roll normally - r = new Report(2235); - r.indent(); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(dest.getBoardNum(), true); - addReport(r); - } else { - // domino effect: move & displace target - r = new Report(2240); - r.indent(); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(dest.getBoardNum(), true); - r.addDesc(violation); - addReport(r); - } - // trigger any special things for moving to the new hex - doEntityDisplacementMinefieldCheck(entity, src, dest); - doSetLocationsExposure(entity, destHex, false, entity.getElevation()); - if (roll != null) { - game.addPSR(roll); - } - // Update the entity's postion on the client. - entityUpdate( entity.getId() ); - - if(violation != null) { - doEntityDisplacement(violation, dest, dest.translated(direction), new PilotingRollData(violation.getId(), 0, "domino effect")); - // Update the violating entity's postion on the client, - // if it didn't get displaced off the board. - if ( !game.isOutOfGame(violation) ) { - entityUpdate( violation.getId() ); - } - } - } - } - - private void doEntityDisplacementMinefieldCheck(Entity entity, Coords src, Coords dest) { - if (game.containsMinefield(dest)) { - Enumeration minefields = game.getMinefields(dest).elements(); - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - enterMinefield(entity, mf, src, dest, false); - } - } - checkVibrabombs(entity, dest, true); - } - - /** - * Receive a deployment packet. If valid, execute it and end the current - * turn. - */ - private void receiveDeployment(Packet packet, int connId) { - Entity entity = game.getEntity(packet.getIntValue(0)); - Coords coords = (Coords)packet.getObject(1); - int nFacing = packet.getIntValue(2); - - // Handle units that deploy loaded with other units. - int loadedCount = packet.getIntValue(3); - Vector loadVector = new Vector(); - for ( int i = 0; i < loadedCount; i++ ){ - int loadedId = packet.getIntValue( 5 + i ); - loadVector.addElement(game.getEntity( loadedId )); - } - - // is this the right phase? - if (game.getPhase() != IGame.PHASE_DEPLOYMENT) { - System.err.println("error: server got deployment packet in wrong phase"); - return; - } - - // can this player/entity act right now? - final boolean assaultDrop = packet.getBooleanValue(4); - if ( !game.getTurn().isValid(connId, entity, game) - || !(game.getBoard().isLegalDeployment(coords, entity.getOwner()) - ||(assaultDrop && game.getOptions().booleanOption("assault_drop") && entity.canAssaultDrop()))) { - System.err.println("error: server got invalid deployment packet"); - return; - } - - // looks like mostly everything's okay - processDeployment(entity, coords, nFacing, loadVector, assaultDrop); - - // Update visibility indications if using double blind. - if (doBlind()) { - updateVisibilityIndicator(); - } - - endCurrentTurn(entity); - } - - /** - * Process a deployment packet by... deploying the entity! We load any - * other specified entities inside of it too. Also, check that the - * deployment is valid. - */ - private void processDeployment(Entity entity, Coords coords, int nFacing, Vector loadVector, boolean assaultDrop) { - for (Enumeration i = loadVector.elements(); i.hasMoreElements();) { - Entity loaded = (Entity)i.nextElement(); - if ( loaded == null || loaded.getPosition() != null || - loaded.getTransportId() != Entity.NONE ) { - // Something is fishy in Denmark. - System.err.println("error: " + entity + " can not load entity #" + loaded ); - break; - } - else { - // Have the deployed unit load the indicated unit. - this.loadUnit( entity, loaded ); - } - } - - entity.setPosition(coords); - entity.setFacing(nFacing); - entity.setSecondaryFacing(nFacing); - IHex hex = game.getBoard().getHex(coords); - if(assaultDrop) { - entity.setElevation(hex.ceiling() - hex.surface() + 100); //falling from the sky! - entity.setAssaultDropInProgress(true); - } else if (entity instanceof VTOL) { - // We should let players pick, but this simplifies a lot. - // Only do it for VTOLs, though; assume everything else is on the ground. - entity.setElevation(hex.ceiling()-hex.surface()+1); - while ((Compute.stackingViolation(game, entity, coords, null) != null) && (entity.getElevation() <= 50)) { - entity.setElevation(entity.getElevation() + 1); - } - if (entity.getElevation() > 50) { - throw new IllegalStateException("Entity #" + entity.getId() + " appears to be in an infinite loop trying to get a legal elevation."); - } - } else if (entity.getMovementMode() == IEntityMovementMode.SUBMARINE) { - // TODO: Submarines should have a selectable height. - // For now, pretend they're regular naval. - entity.setElevation(0); - } else if ((entity.getMovementMode() == IEntityMovementMode.HOVER) - || (entity.getMovementMode() == IEntityMovementMode.NAVAL) - || (entity.getMovementMode() == IEntityMovementMode.HYDROFOIL)) { - // For now, assume they're on the surface. - // entity elevation is relative to hex surface - entity.setElevation(0); - } else if (hex.containsTerrain(Terrains.ICE) - || hex.containsTerrain(Terrains.BRIDGE)) { - entity.setElevation(0); - } else { - // For anything else, assume they're on the floor. - // entity elevation is relative to hex surface - entity.setElevation(hex.floor()-hex.surface()); - } - entity.setDone(true); - entity.setDeployed(true); - entityUpdate(entity.getId()); - } - - private void receiveArtyAutoHitHexes(Packet packet, int connId) { - Vector artyAutoHitHexes = (Vector) packet.getObject(0); - - Integer playerId = (Integer)artyAutoHitHexes.firstElement(); - artyAutoHitHexes.removeElementAt(0); - - // is this the right phase? - if (game.getPhase() != IGame.PHASE_SET_ARTYAUTOHITHEXES) { - System.err.println("error: server got set artyautohithexespacket in wrong phase"); - return; - } - game.getPlayer(playerId.intValue()).setArtyAutoHitHexes(artyAutoHitHexes); - endCurrentTurn(null); - } - - private void receiveDeployMinefields(Packet packet, int connId) { - Vector minefields = (Vector) packet.getObject(0); - - // is this the right phase? - if (game.getPhase() != IGame.PHASE_DEPLOY_MINEFIELDS) { - System.err.println("error: server got deploy minefields packet in wrong phase"); - return; - } - - // looks like mostly everything's okay - processDeployMinefields(minefields); - endCurrentTurn(null); - } - - private void processDeployMinefields(Vector minefields) { - int playerId = Player.PLAYER_NONE; - for (int i = 0; i < minefields.size(); i++) { - Minefield mf = (Minefield) minefields.elementAt(i); - playerId = mf.getPlayerId(); - - game.addMinefield(mf); - if (mf.getType() == Minefield.TYPE_VIBRABOMB) { - game.addVibrabomb(mf); - } - } - - Player player = game.getPlayer( playerId ); - if ( null != player ) { - int teamId = player.getTeam(); - - if (teamId != Player.TEAM_NONE) { - Enumeration teams = game.getTeams(); - while (teams.hasMoreElements()) { - Team team = (Team) teams.nextElement(); - if (team.getId() == teamId) { - Enumeration players = team.getPlayers(); - while (players.hasMoreElements()) { - Player teamPlayer = (Player) players.nextElement(); - if (teamPlayer.getId() != player.getId()) { - send(teamPlayer.getId(), new Packet(Packet.COMMAND_DEPLOY_MINEFIELDS, minefields)); - } - teamPlayer.addMinefields(minefields); - } - break; - } - } - } else { - player.addMinefields(minefields); - } - } - } - /** - * Gets a bunch of entity attacks from the packet. If valid, processess - * them and ends the current turn. - */ - private void receiveAttack(Packet packet, int connId) { - Entity entity = game.getEntity(packet.getIntValue(0)); - Vector vector = (Vector)packet.getObject(1); - - // is this the right phase? - if (game.getPhase() != IGame.PHASE_FIRING - && game.getPhase() != IGame.PHASE_PHYSICAL - && game.getPhase() != IGame.PHASE_TARGETING - && game.getPhase() != IGame.PHASE_OFFBOARD) { - System.err.println("error: server got attack packet in wrong phase"); - return; - } - - // can this player/entity act right now? - if (!game.getTurn().isValid(connId, entity, game)) { - System.err.println("error: server got invalid attack packet"); - return; - } - - // looks like mostly everything's okay - processAttack(entity, vector); - - // Update visibility indications if using double blind. - if (doBlind()) { - updateVisibilityIndicator(); - } - - endCurrentTurn(entity); - } - - /** - * Process a batch of entity attack (or twist) actions by adding them to - * the proper list to be processed later. - */ - private void processAttack(Entity entity, Vector vector) { - - // Not **all** actions take up the entity's turn. - boolean setDone = - !(game.getTurn() instanceof GameTurn.TriggerAPPodTurn); - for (Enumeration i = vector.elements(); i.hasMoreElements();) { - EntityAction ea = (EntityAction)i.nextElement(); - - // is this the right entity? - if (ea.getEntityId() != entity.getId()) { - System.err.println("error: attack packet has wrong attacker"); - continue; - } - - // Anti-mech and pointblank attacks from - // hiding may allow the target to respond. - if ( ea instanceof WeaponAttackAction ) { - final WeaponAttackAction waa = (WeaponAttackAction) ea; - final String weaponName = entity.getEquipment - ( waa.getWeaponId() ).getType().getInternalName(); - - if ( Infantry.SWARM_MEK.equals(weaponName) || - Infantry.LEG_ATTACK.equals(weaponName) ) { - - // Does the target have any AP Pods available? - final Entity target = game.getEntity( waa.getTargetId() ); - Enumeration misc = target.getMisc(); - while ( misc.hasMoreElements() ) { - final Mounted equip = (Mounted) misc.nextElement(); - if ( equip.getType().hasFlag(MiscType.F_AP_POD) && - equip.canFire()) { - - // Yup. Insert a game turn to handle AP pods. - // ASSUMPTION : AP pod declarations come - // immediately after the attack declaration. - game.insertNextTurn( new GameTurn.TriggerAPPodTurn - ( target.getOwnerId(), target.getId() ) ); - send(createTurnVectorPacket()); - - // We can stop looking. - break; - - } // end found-available-ap-pod - - } // Check the next piece of equipment on the target. - - } // End check-for-available-ap-pod - } - - // The equipment type of a club needs to be restored. - if (ea instanceof ClubAttackAction) { - ClubAttackAction caa = (ClubAttackAction) ea; - Mounted club = caa.getClub(); - club.restore(); - } - - if (ea instanceof PushAttackAction) { - // push attacks go the end of the displacement attacks - PushAttackAction paa = (PushAttackAction)ea; - entity.setDisplacementAttack(paa); - game.addCharge(paa); - } else if (ea instanceof DodgeAction) { - entity.dodging = true; - } else if (ea instanceof SpotAction) { - entity.setSpotting(true); - } else { - // add to the normal attack list. - game.addAction(ea); - } - - // Mark any AP Pod as used in this turn. - if ( ea instanceof TriggerAPPodAction ) { - TriggerAPPodAction tapa = (TriggerAPPodAction) ea; - Mounted pod = entity.getEquipment( tapa.getPodId() ); - pod.setUsedThisRound( true ); - } - } - - // Unless otherwise stated, - // this entity is done for the round. - if ( setDone ) { - entity.setDone(true); - } - entityUpdate(entity.getId()); - - // update all players on the attacks. Don't worry about pushes being a - // "charge" attack. It doesn't matter to the client. - send(createAttackPacket(vector, 0)); - } - - /** - * Auto-target active AMS systems - */ - private void assignAMS() { - - // sort all missile-based attacks by the target - Hashtable htAttacks = new Hashtable(); - for (Enumeration i = game.getActions(); i.hasMoreElements(); ) { - Object o = i.nextElement(); - if (o instanceof WeaponAttackAction) { - WeaponAttackAction waa = (WeaponAttackAction)o; - Mounted weapon = game.getEntity(waa.getEntityId()).getEquipment(waa.getWeaponId()); - - // Only entities can have AMS. - if ( Targetable.TYPE_ENTITY != waa.getTargetType() ) { - continue; - } - - // Can only use AMS versus missles. - if (((WeaponType)weapon.getType()).getDamage() == WeaponType.DAMAGE_MISSILE) { - Entity target = game.getEntity(waa.getTargetId()); - Vector v = (Vector)htAttacks.get(target); - if (v == null) { - v = new Vector(); - htAttacks.put(target, v); - } - v.addElement(waa); - } - } - } - - // let each target assign its AMS - for (Enumeration i = htAttacks.keys(); i.hasMoreElements(); ) { - Entity e = (Entity)i.nextElement(); - Vector vAttacks = (Vector)htAttacks.get(e); - e.assignAMS(vAttacks); - } - } - - /** - * Called during the weapons fire phase. Resolves anything other than - * weapons fire that happens. Torso twists, for example. - */ - private void resolveAllButWeaponAttacks() { - if (game.getPhase()==IGame.PHASE_FIRING) { - //Phase report header - addReport(new Report(3000, Report.PUBLIC)); - Report r; - for (Enumeration e = game.getLayMinefieldActions(); e.hasMoreElements();) { - LayMinefieldAction lma = (LayMinefieldAction)e.nextElement(); - Entity ent = game.getEntity(lma.getEntityId()); - Mounted mine = ent.getEquipment(lma.getMineId()); - if (!mine.isMissing()) { - switch (mine.getMineType()) { - case 0: - deliverThunderMinefield(ent.getPosition(), ent.getOwnerId(), 10); - mine.setMissing(true); - r = new Report(3500); - r.subject = ent.getId(); - r.addDesc(ent); - r.add(ent.getPosition().getBoardNum()); - addReport(r); - break; - case 1: - deliverThunderVibraMinefield(ent.getPosition(), ent.getOwnerId(), 10, mine.getVibraSetting()); - mine.setMissing(true); - r = new Report(3505); - r.subject = ent.getId(); - r.addDesc(ent); - r.add(ent.getPosition().getBoardNum()); - addReport(r); - break; - //TODO: command-detonated mines - // case 2: - } - } - } - game.resetLayMinefieldActions(); - } - - Vector clearAttempts = new Vector(); - Vector triggerPodActions = new Vector(); - // loop thru actions and handle everything we expect except attacks - for (Enumeration i = game.getActions(); i.hasMoreElements();) { - EntityAction ea = (EntityAction)i.nextElement(); - Entity entity = game.getEntity(ea.getEntityId()); - if (ea instanceof TorsoTwistAction) { - TorsoTwistAction tta = (TorsoTwistAction)ea; - if ( entity.canChangeSecondaryFacing() ) { - entity.setSecondaryFacing(tta.getFacing()); - } - } - else if (ea instanceof FlipArmsAction) { - FlipArmsAction faa = (FlipArmsAction)ea; - entity.setArmsFlipped(faa.getIsFlipped()); - } - else if (ea instanceof FindClubAction) { - resolveFindClub(entity); - } - else if (ea instanceof UnjamAction) { - resolveUnjam(entity); - } - else if (ea instanceof ClearMinefieldAction) { - clearAttempts.addElement(entity); - } - else if (ea instanceof TriggerAPPodAction) { - TriggerAPPodAction tapa = (TriggerAPPodAction) ea; - - // Don't trigger the same pod twice. - if ( !triggerPodActions.contains( tapa ) ) { - triggerAPPod(entity, tapa.getPodId()); - triggerPodActions.addElement( tapa ); - } else { - System.err.print( "AP Pod #" ); - System.err.print( tapa.getPodId() ); - System.err.print( " on " ); - System.err.print( entity.getDisplayName() ); - System.err.println(" was already triggered this round!!"); - } - } - else if (ea instanceof SearchlightAttackAction) { - SearchlightAttackAction saa = (SearchlightAttackAction)ea; - addReport( - saa.resolveAction(game)); - } - } - - resolveClearMinefieldAttempts(clearAttempts); - } - - private void resolveClearMinefieldAttempts(Vector clearAttempts) { - - for (int i = 0; i < clearAttempts.size(); i++) { - Vector temp = new Vector(); - Entity e = (Entity) clearAttempts.elementAt(i); - Coords pos = e.getPosition(); - temp.addElement(e); - - for (int j = i + 1; j < clearAttempts.size(); j++) { - Entity ent = (Entity) clearAttempts.elementAt(j); - if (ent.getPosition().equals(pos)) { - temp.addElement(ent); - clearAttempts.removeElement(ent); - } - } - - boolean accident = false; - boolean cleared = false; - for (int j = 0; j < temp.size(); j++) { - Entity ent = (Entity) temp.elementAt(j); - int roll = Compute.d6(2); - int clear = Minefield.CLEAR_NUMBER_INFANTRY; - int boom = Minefield.CLEAR_NUMBER_INFANTRY_ACCIDENT; - - // Does the entity has a minesweeper? - Enumeration equip = ent.getMisc(); - while ( equip.hasMoreElements() ) { - Mounted mounted = (Mounted) equip.nextElement(); - if ( mounted.getType().hasFlag(MiscType.F_TOOLS) - && mounted.getType().hasSubType(MiscType.S_MINESWEEPER) ) { - int sweeperType = mounted.getType().getToHitModifier(); - clear = Minefield.CLEAR_NUMBER_SWEEPER[sweeperType]; - boom = Minefield.CLEAR_NUMBER_SWEEPER_ACCIDENT[sweeperType]; - break; - } - } - //mine clearing roll - Report r = new Report(2245); - r.subject = ent.getId(); - r.add(ent.getShortName(), true); - r.add(pos.getBoardNum(), true); - r.add(clear); - r.add(roll); - r.newlines = 0; - addReport(r); - - if (roll >= clear) { - //success - r = new Report(2250); - r.subject = ent.getId(); - addReport(r); - cleared = true; - } else if (roll <= boom) { - //"click"...oops! - r = new Report(2255); - r.subject = ent.getId(); - addReport(r); - accident = true; - } else { - //failure - r = new Report(2260); - r.subject = ent.getId(); - addReport(r); - } - } - if (accident) { - Enumeration minefields = game.getMinefields(pos).elements(); - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - switch (mf.getType()) { - case (Minefield.TYPE_CONVENTIONAL) : - case (Minefield.TYPE_THUNDER) : - for (int j = 0; j < temp.size(); j++) { - Entity entity = (Entity) temp.elementAt(j); - Report r = new Report(2265); - r.subject = entity.getId(); - r.add(entity.getShortName(), true); - addReport(r); - HitData hit = entity.rollHitLocation(Minefield.TO_HIT_TABLE, Minefield.TO_HIT_SIDE); - addReport( damageEntity(entity, hit, mf.getDamage())); - addNewLines(); - } - break; - case (Minefield.TYPE_VIBRABOMB) : - explodeVibrabomb(mf); - break; - } - } - } - if (cleared) { - removeMinefieldsFrom(pos); - } - } - } - - /** - * Called during the fire phase to resolve all (and only) weapon attacks - */ - private void resolveOnlyWeaponAttacks() { - Vector results = new Vector(game.actionsSize()); - - // loop thru received attack actions, getting weapon results - for (Enumeration i = game.getActions(); i.hasMoreElements();) { - Object o = i.nextElement(); - if (o instanceof WeaponAttackAction) { - WeaponAttackAction waa = (WeaponAttackAction)o; - results.addElement(preTreatWeaponAttack(waa)); - } - } - - // loop through weapon results and resolve - int cen = Entity.NONE; - for (Enumeration i = results.elements(); i.hasMoreElements();) { - WeaponResult wr = (WeaponResult)i.nextElement(); - resolveWeaponAttack(wr, cen); - cen = wr.waa.getEntityId(); - } - - // and clear the attacks Vector - game.resetActions(); - } - - /** - * Trigger the indicated AP Pod of the entity. - * - * @param entity the Entity triggering the AP Pod. - * @param podId the int ID of the AP Pod. - */ - private void triggerAPPod( Entity entity, int podId ) { - - // Get the mount for this pod. - Mounted mount = entity.getEquipment( podId ); - - // Confirm that this is, indeed, an AP Pod. - if ( null == mount ) { - System.err.print( "Expecting to find an AP Pod at " ); - System.err.print( podId ); - System.err.print( " on the unit, " ); - System.err.print( entity.getDisplayName() ); - System.err.println( " but found NO equipment at all!!!" ); - return; - } - EquipmentType equip = mount.getType(); - if ( !(equip instanceof MiscType) || - !equip.hasFlag(MiscType.F_AP_POD) ) { - System.err.print( "Expecting to find an AP Pod at " ); - System.err.print( podId ); - System.err.print( " on the unit, " ); - System.err.print( entity.getDisplayName() ); - System.err.print( " but found " ); - System.err.print( equip.getName() ); - System.err.println( " instead!!!" ); - return; - } - - // Now confirm that the entity can trigger the pod. - // Ignore the "used this round" flag. - boolean oldFired = mount.isUsedThisRound(); - mount.setUsedThisRound( false ); - boolean canFire = mount.canFire(); - mount.setUsedThisRound( oldFired ); - if ( !canFire ) { - System.err.print( "Can not trigger the AP Pod at " ); - System.err.print( podId ); - System.err.print( " on the unit, " ); - System.err.print( entity.getDisplayName() ); - System.err.println( "!!!" ); - return; - } - - Report r; - - // Mark the pod as fired and log the action. - mount.setFired( true ); - r = new Report(3010); - r.newlines = 0; - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - - // Walk through ALL entities in the triggering entity's hex. - Enumeration targets = game.getEntities( entity.getPosition() ); - while ( targets.hasMoreElements() ) { - final Entity target = (Entity) targets.nextElement(); - - // Is this an unarmored infantry platoon? - if ( target instanceof Infantry && - !(target instanceof BattleArmor) ) { - - // Roll d6-1 for damage. - final int damage = Compute.d6() - 1; - - // If the platoon took no damage, log it and go no further - if ( 0 == damage ) { - r = new Report(3015); - r.indent(2); - r.subject = target.getId(); - r.addDesc(target); - addReport(r); - } - else { - // Damage the platoon. - addReport( damageEntity( target, new HitData(Infantry.LOC_INFANTRY),damage )); - - // Damage from AP Pods is applied immediately. - target.applyDamage(); - } - - } // End target-is-unarmored - - // Nope, the target is immune. - // Don't make a log entry for the triggering entity. - else if ( !entity.equals( target ) ) { - r = new Report(3020); - r.indent(2); - r.subject = target.getId(); - r.addDesc(target); - addReport(r); - } - - } // Check the next entity in the triggering entity's hex. - } - - /** - * Resolve an Unjam Action object - */ - private void resolveUnjam(Entity entity) { - Report r; - final int TN = entity.getCrew().getGunnery() + 3; - r = new Report(3025); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - for (Enumeration i = entity.getWeapons(); i.hasMoreElements();) { - Mounted mounted = (Mounted)i.nextElement(); - if(mounted.isJammed()) { - WeaponType wtype = (WeaponType)mounted.getType(); - if (wtype.getAmmoType() == AmmoType.T_AC_ROTARY) { - int roll = Compute.d6(2); - r = new Report(3030); - r.indent(); - r.subject = entity.getId(); - r.add(wtype.getName()); - r.add(TN); - r.add(roll); - if(roll >= TN) { - r.choose(true); - mounted.setJammed(false); - } else { - r.choose(false); - } - addReport(r); - } - } - } - } - - private void resolveFindClub(Entity entity) { - EquipmentType clubType = null; - - entity.setFindingClub(true); - - // Get the entity's current hex. - Coords coords = entity.getPosition(); - IHex curHex = game.getBoard().getHex( coords ); - - Report r; - - // Is there a blown off arm in the hex? - if (curHex.terrainLevel(Terrains.ARMS) > 0) { - clubType = EquipmentType.get("Limb Club"); - curHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.ARMS, curHex.terrainLevel(Terrains.ARMS)-1)); - sendChangedHex(entity.getPosition()); - r = new Report(3035); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - } - // Is there a blown off leg in the hex? - else if (curHex.terrainLevel(Terrains.LEGS) > 0) { - clubType = EquipmentType.get("Limb Club"); - curHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.LEGS, curHex.terrainLevel(Terrains.LEGS)-1)); - sendChangedHex(entity.getPosition()); - r = new Report(3040); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - } - - // Is there the rubble of a medium, heavy, - // or hardened building in the hex? - else if ( Building.LIGHT < curHex.terrainLevel( Terrains.RUBBLE ) ) { - - // Finding a club is not guaranteed. The chances are - // based on the type of building that produced the - // rubble. - boolean found = false; - int roll = Compute.d6(2); - switch ( curHex.terrainLevel( Terrains.RUBBLE ) ) { - case Building.MEDIUM: - if ( roll >= 7 ) { - found = true; - } - break; - case Building.HEAVY: - if ( roll >= 6 ) { - found = true; - } - break; - case Building.HARDENED: - if ( roll >= 5 ) { - found = true; - } - break; - } - - // Let the player know if they found a club. - if ( found ) { - clubType = EquipmentType.get("Girder Club"); - r = new Report(3045); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - } else { - // Sorry, no club for you. - clubType = null; - r = new Report(3050); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - } - } - - // Are there woods in the hex? - else if ( curHex.containsTerrain( Terrains.WOODS ) - || curHex.containsTerrain( Terrains.JUNGLE ) ) { - clubType = EquipmentType.get("Tree Club"); - r = new Report(3055); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - } - - // add the club - try { - if (clubType != null) { - entity.addEquipment(clubType, Mech.LOC_NONE); - } - } catch (LocationFullException ex) { - // unlikely... - r = new Report(3060); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - } - } - - /** - * Generates a WeaponResult object for a WeaponAttackAction. Adds heat, - * depletes ammo, sets weapons used. - */ - private WeaponResult preTreatWeaponAttack(WeaponAttackAction waa) { - final Entity ae = game.getEntity(waa.getEntityId()); - final Mounted weapon = ae.getEquipment(waa.getWeaponId()); - final WeaponType wtype = (WeaponType)weapon.getType(); - // 2003-01-02 BattleArmor MG and Small Lasers have unlimited ammo. - final boolean usesAmmo = wtype.getAmmoType() != AmmoType.T_NA && - wtype.getAmmoType() != AmmoType.T_BA_MG && - wtype.getAmmoType() != AmmoType.T_BA_SMALL_LASER && - !wtype.hasFlag(WeaponType.F_INFANTRY); - - Mounted ammo = null; - if (usesAmmo) { - if (waa.getAmmoId() > -1) { - ammo = ae.getEquipment(waa.getAmmoId()); - weapon.setLinked(ammo); - } else { - ammo = weapon.getLinked(); - } - } - boolean streakMiss; - - WeaponResult wr = new WeaponResult(); - wr.waa = waa; - - // has this weapon fired already? - if (weapon.isUsedThisRound()) { - wr.toHit = new ToHitData(TargetRoll.IMPOSSIBLE, "Weapon has already been used this round"); - return wr; - } - // is the weapon functional? - if (weapon.isDestroyed()) { - wr.toHit = new ToHitData(TargetRoll.IMPOSSIBLE, "Weapon was destroyed in a previous round"); - return wr; - } - // is it jammed? - if (weapon.isJammed()) { - wr.toHit = new ToHitData(TargetRoll.IMPOSSIBLE, "Weapon is jammed"); - return wr; - } - // make sure ammo is loaded - if (usesAmmo && (ammo == null || ammo.getShotsLeft() == 0 || ammo.isDumping())) { - ae.loadWeaponWithSameAmmo(weapon); - ammo = weapon.getLinked(); - } - - // store the ammo type for later use (needed for artillery attacks) - waa.setAmmoId(ae.getEquipmentNum(ammo)); - - // compute to-hit - wr.toHit = waa.toHit(game); - - if (waa.isNemesisConfused()) { - wr.toHit.addModifier(1, "iNarc Nemesis pod"); - } - // roll dice - wr.roll = Compute.d6(2); - - // if the shot is possible and not a streak miss - // and not a nemesis-confused shot, add heat and use ammo - streakMiss = (((wtype.getAmmoType() == AmmoType.T_SRM_STREAK) - || (wtype.getAmmoType() == AmmoType.T_LRM_STREAK)) - && wr.roll < wr.toHit.getValue()); - if (wr.toHit.getValue() != TargetRoll.IMPOSSIBLE - && (!streakMiss || Compute.isAffectedByAngelECM(ae, ae.getPosition(), waa.getTarget(game).getPosition())) - && !waa.isNemesisConfused()) { - wr = addHeatUseAmmoFor(waa, wr); - } - - // set the weapon as having fired - weapon.setUsedThisRound(true); - - // if not streak miss, resolve any AMS attacks on this attack - if (!streakMiss) { - wr = resolveAmsFor(waa, wr); - } - - return wr; - } - - /** - * Adds heat and uses ammo appropriate for a single attack of this weapon. - * Call only on a valid attack (and with a streak weapon, only on hits.) - * - * @returns modified WeaponResult - */ - private WeaponResult addHeatUseAmmoFor(WeaponAttackAction waa, WeaponResult wr) { - if (waa.isSwarmingMissiles()) return wr; - - final Entity ae = game.getEntity(waa.getEntityId()); - final Mounted weapon = ae.getEquipment(waa.getWeaponId()); - final WeaponType wtype = (WeaponType)weapon.getType(); - // 2003-01-02 BattleArmor MG and Small Lasers have unlimited ammo. - final boolean usesAmmo = wtype.getAmmoType() != AmmoType.T_NA && - wtype.getAmmoType() != AmmoType.T_BA_MG && - wtype.getAmmoType() != AmmoType.T_BA_SMALL_LASER && - !wtype.hasFlag(WeaponType.F_INFANTRY); - - Mounted ammo = weapon.getLinked(); - - // how many shots are we firing? - int nShots = weapon.howManyShots(); - - // do we need to revert to single shot? - if (usesAmmo && nShots > 1) { - int nAvail = ae.getTotalAmmoOfType(ammo.getType()); - if (nAvail < nShots) { - wr.revertsToSingleShot = true; - nShots = 1; - } - } - - // use up ammo - if (usesAmmo) { - for (int i = 0; i < nShots; i++) { - if (ammo.getShotsLeft() <= 0) { - ae.loadWeaponWithSameAmmo(weapon); - ammo = weapon.getLinked(); - } - ammo.setShotsLeft(ammo.getShotsLeft() - 1); - } - } - - // build up some heat - ae.heatBuildup += (wtype.getHeat() * nShots); - - return wr; - } - - /** - * Resolves any AMS fire for this weapon attack, adding AMS heat, depleting - * AMS ammo. - * @returns the appropriately modified WeaponResult - */ - private WeaponResult resolveAmsFor(WeaponAttackAction waa, WeaponResult wr) { - final Entity te = game.getEntity(waa.getTargetId()); - - // any AMS attacks by the target? - Vector vCounters = waa.getCounterEquipment(); - if (null != vCounters) { - // resolve AMS counter-fire - wr.amsShotDown = new int[vCounters.size()]; - for (int x = 0; x < vCounters.size(); x++) { - wr.amsShotDown[x] = 0; - - Mounted counter = (Mounted)vCounters.elementAt(x); - Mounted mAmmo = counter.getLinked(); - if ((!(counter.getType() instanceof WeaponType)) - || (!(counter.getType().hasFlag(WeaponType.F_AMS))) - || (!counter.isReady()) - || (counter.isMissing())) { - continue; - } - // roll hits - int amsHits = Compute.d6(((WeaponType)counter.getType()).getDamage()); - - // build up some heat (assume target is ams owner) - if (counter.getType().hasFlag(WeaponType.F_HEATASDICE)) - te.heatBuildup += Compute.d6(((WeaponType)counter.getType()).getHeat()); - else - te.heatBuildup += ((WeaponType)counter.getType()).getHeat(); - - // decrement the ammo - if (mAmmo != null) - mAmmo.setShotsLeft(Math.max(0, mAmmo.getShotsLeft() - amsHits)); - - // set the ams as having fired - counter.setUsedThisRound(true); - - wr.amsShotDown[x] = amsHits; - wr.amsShotDownTotal += amsHits; - } - } - - return wr; - } - - /** - * Try to ignite the hex, taking into account exisiting fires and the - * effects of Inferno rounds. - * - * @param c - the Coords of the hex being lit. - * @param bInferno - true if the weapon igniting the - * hex is an Inferno round. If some other weapon or ammo - * is causing the roll, this should be false. - * @param nTargetRoll - the int target number for the - * ignition roll. - * @param nTargetRoll - the int roll target for the attempt. - * @param bReportAttempt - true if the attempt roll should - * be added to the report. - */ - private boolean tryIgniteHex( Coords c, int entityId, boolean bInferno, - int nTargetRoll, boolean bReportAttempt ) { - - IHex hex = game.getBoard().getHex(c); - boolean bAnyTerrain = false; - Report r; - - // Ignore bad coordinates. - if ( hex == null ) { - return false; - } - - // inferno always ignites - if (bInferno) { - game.getBoard().addInfernoTo(c, InfernoTracker.STANDARD_ROUND, 1); - nTargetRoll = 0; - bAnyTerrain = true; - } - - // The hex may already be on fire. - if ( hex.containsTerrain( Terrains.FIRE ) ) { - if ( bReportAttempt ) { - r = new Report(3065); - r.indent(3); - r.subject = entityId; - addReport(r); - } - return true; - } - else if ( ignite(hex, nTargetRoll, bAnyTerrain, entityId) ) { - //hex ignites - r = new Report(3070); - r.indent(3); - r.subject = entityId; - addReport(r); - sendChangedHex(c); - return true; - } - return false; - } - - /** - * Try to ignite the hex, taking into account exisiting fires and the - * effects of Inferno rounds. This version of the method will not report - * the attempt roll. - * - * @param c - the Coords of the hex being lit. - * @param bInferno - true if the weapon igniting the - * hex is an Inferno round. If some other weapon or ammo - * is causing the roll, this should be false. - * @param nTargetRoll - the int roll target for the attempt. - */ - private boolean tryIgniteHex(Coords c, int entityId, boolean bInferno, - int nTargetRoll) { - return tryIgniteHex(c, entityId, bInferno, nTargetRoll, false); - } - - private void tryClearHex(Coords c, int nTarget, int entityId) { - IHex h = game.getBoard().getHex(c); - int woods = h.terrainLevel(Terrains.WOODS); - int jungle = h.terrainLevel(Terrains.JUNGLE); - boolean ice = h.containsTerrain(Terrains.ICE); - Report r; - if (woods == ITerrain.LEVEL_NONE && jungle == ITerrain.LEVEL_NONE && !ice) { - //woods already cleared - r = new Report(3075); - r.indent(3); - r.subject = entityId; - addReport(r); - } else { - int woodsRoll = Compute.d6(2); - r = new Report(3080); - r.indent(3); - r.subject = entityId; - r.add(nTarget); - r.add(woodsRoll); - r.newlines = 0; - addReport(r); - if(woodsRoll >= nTarget) { - if(woods > 2) { - h.removeTerrain(Terrains.WOODS); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.WOODS, woods - 1)); - //ultra heavy converted to heavy - r = new Report(3082); - r.subject = entityId; - addReport(r); - } - else if(woods == 2) { - h.removeTerrain(Terrains.WOODS); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.WOODS, woods - 1)); - //heavy converted to light - r = new Report(3085); - r.subject = entityId; - addReport(r); - } - else if(woods == 1) { - h.removeTerrain(Terrains.WOODS); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.ROUGH, 1)); - //light converted to rough - r = new Report(3090); - r.subject = entityId; - addReport(r); - } - else if(jungle > 2) { - h.removeTerrain(Terrains.JUNGLE); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.JUNGLE, jungle - 1)); - //ultra heavy converted to heavy - r = new Report(3083); - r.subject = entityId; - addReport(r); - } - else if(jungle == 2) { - h.removeTerrain(Terrains.JUNGLE); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.JUNGLE, jungle - 1)); - //heavy converted to light - r = new Report(3086); - r.subject = entityId; - addReport(r); - } - else if(jungle == 1) { - h.removeTerrain(Terrains.JUNGLE); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.ROUGH, 1)); - //light converted to rough - r = new Report(3091); - r.subject = entityId; - addReport(r); - } - else if(ice) { - h.removeTerrain(Terrains.ICE); - r = new Report(3092); - r.subject = entityId; - addReport(r); - resolveIceBroken(c); - } - sendChangedHex(c); - } else { - //fails to clear woods - r = new Report(3095); - r.subject = entityId; - addReport(r); - } - } - } - - private void resolveWeaponAttack(WeaponResult wr, int lastEntityId) { - resolveWeaponAttack(wr, lastEntityId, false); - } - - private boolean resolveWeaponAttack(WeaponResult wr, int lastEntityId, boolean isNemesisConfused) { - return resolveWeaponAttack(wr, lastEntityId, isNemesisConfused, 0); - } - - /** - * Resolve a single Weapon Attack object - * @param wr The WeaponResult to resolve - * @param lastEntityId The int ID of the last - * resolved weaponattack's attacking entity - * @param isNemesisConfused The boolean value of wether - * this attack is one caused by homing in on a iNarc Nemesis pod - * and so should not be further diverted - * @param swarmMissilesLeft The int number of remaining swarm - * missiles this attack has, 0 if this is not a remaining swarm - * missile attack - * @return wether we hit or not, only needed for nemesis pod stuff - */ - private boolean resolveWeaponAttack(WeaponResult wr, int lastEntityId, boolean isNemesisConfused, int swarmMissilesLeft) { - // If it's an artillery shot, the shooting entity - // might have died in the meantime - Entity ae = game.getEntity( wr.waa.getEntityId() ); - if (ae == null) { - ae = game.getOutOfGameEntity( wr.waa.getEntityId() ); - } - final Targetable target = game.getTarget(wr.waa.getTargetType(), - wr.waa.getTargetId()); - Report r; - boolean throughFront; - if (target instanceof Mech) { - throughFront = Compute.isThroughFrontHex(game, wr.waa.getEntityId(), (Entity)target); - } else { - throughFront = true; - } - - int subjectId = Entity.NONE; - Entity entityTarget = null; - if (target.getTargetType() == Targetable.TYPE_ENTITY) { - entityTarget = (Entity) target; - // The target of the attack should definately see the report. - // The attacker usually will, but they might not if the attack - // was indirect without a spotter. - subjectId = entityTarget.getId(); - } else { - //The target is not an entity, so we will show the report to - // the attacker instead. - subjectId = ae.getId(); - } - final Mounted weapon = ae.getEquipment(wr.waa.getWeaponId()); - final WeaponType wtype = (WeaponType) weapon.getType(); - final boolean isWeaponInfantry = wtype.hasFlag(WeaponType.F_INFANTRY); - // 2002-09-16 Infantry weapons have unlimited ammo. - final boolean usesAmmo = wtype.getAmmoType() != AmmoType.T_NA && - wtype.getAmmoType() != AmmoType.T_BA_MG && - wtype.getAmmoType() != AmmoType.T_BA_SMALL_LASER && - !isWeaponInfantry; - //retrieve ammo from the WeaponAttackAction rather than weapon.getLinked, because selected ammo may have changed - //in the case of artillery attacks - Mounted ammo = usesAmmo ? ae.getEquipment(wr.waa.getAmmoId()) : null; - final AmmoType atype = ammo == null ? null : (AmmoType) ammo.getType(); - Infantry platoon = null; - final boolean isBattleArmorAttack = wtype.hasFlag(WeaponType.F_BATTLEARMOR); - ToHitData toHit = wr.toHit; - boolean bInferno = (usesAmmo - && ((atype.getAmmoType() == AmmoType.T_SRM) - || (atype.getAmmoType() == AmmoType.T_BA_INFERNO)) - && atype.getMunitionType() == AmmoType.M_INFERNO); - boolean bFragmentation = (usesAmmo - && ((atype.getAmmoType() == AmmoType.T_LRM) || (atype.getAmmoType() == AmmoType.T_SRM)) - && atype.getMunitionType() == AmmoType.M_FRAGMENTATION); - boolean bAcidHead = (usesAmmo - && atype.getAmmoType() == AmmoType.T_SRM - && atype.getMunitionType() == AmmoType.M_AX_HEAD); - boolean bFlechette = (usesAmmo && (atype.getAmmoType() == AmmoType.T_AC) - && atype.getMunitionType() == AmmoType.M_FLECHETTE); - boolean bArtillery = target.getTargetType() == Targetable.TYPE_HEX_ARTILLERY; - boolean bArtilleryFLAK = target.getTargetType() == Targetable.TYPE_ENTITY - && wtype.hasFlag(WeaponType.F_ARTILLERY) - && (usesAmmo && atype.getMunitionType() == AmmoType.M_STANDARD) - && entityTarget.getMovementMode() == IEntityMovementMode.VTOL - && entityTarget.getElevation() > 0; - boolean bIncendiary = (usesAmmo && atype.getAmmoType() == AmmoType.T_AC && - (atype.getMunitionType() == AmmoType.M_INCENDIARY_AC)); - boolean bTracer = (usesAmmo && atype.getAmmoType() == AmmoType.T_AC && - (atype.getMunitionType() == AmmoType.M_TRACER)); - boolean bAntiTSM = (usesAmmo - && ((atype.getAmmoType() == AmmoType.T_LRM) || (atype.getAmmoType() == AmmoType.T_SRM)) - && atype.getMunitionType() == AmmoType.M_ANTI_TSM); - boolean bSwarm = (usesAmmo - && (atype.getAmmoType() == AmmoType.T_LRM) - && atype.getMunitionType() == AmmoType.M_SWARM); - boolean bSwarmI = (usesAmmo - && (atype.getAmmoType() == AmmoType.T_LRM) - && atype.getMunitionType() == AmmoType.M_SWARM_I); - boolean isIndirect = ((wtype.getAmmoType() == AmmoType.T_LRM) || (wtype.getAmmoType() == AmmoType.T_LRM_TORPEDO)) - && weapon.curMode().equals("Indirect"); - boolean isHotLoaded = ((wtype.getAmmoType() == AmmoType.T_LRM) || - (wtype.getAmmoType() == AmmoType.T_LRM_STREAK) || - (wtype.getAmmoType() == AmmoType.T_LRM_TORPEDO) || - (wtype.getAmmoType() == AmmoType.T_LRM_TORPEDO_COMBO)) - && weapon.curMode().equals("Hot Load"); - boolean isAngelECMAffected = Compute.isAffectedByAngelECM(ae, ae.getPosition(), target.getPosition()); - if (isIndirect && game.getOptions().booleanOption("indirect_fire") && - !game.getOptions().booleanOption("indirect_always_possible") && - LosEffects.calculateLos(game, ae.getId(), target).canSee()) { - r = new Report(3470); - r.subject = subjectId; - r.addDesc(ae); - addReport(r); - return false; - } - boolean bGlancing = false; // For Glancing Hits Rule - int swarmMissilesNowLeft = 0; - int hits = 1, glancingMissileMod = 0; - int glancingCritMod = 0; - - if (!bInferno) { - // also check for inferno infantry - bInferno = (isWeaponInfantry && wtype.hasFlag(WeaponType.F_INFERNO)); - } - final boolean targetInBuilding = - Compute.isInBuilding(game, entityTarget); - if ((bArtillery||bArtilleryFLAK) && game.getPhase()==IGame.PHASE_FIRING) { //if direct artillery - wr.artyAttackerCoords=ae.getPosition(); - } - if ( (bSwarm || bSwarmI) && entityTarget != null) { - entityTarget.addTargetedBySwarm(ae.getId(), wr.waa.getWeaponId()); - } - - // Which building takes the damage? - Building bldg = game.getBoard().getBuildingAt(target.getPosition()); - - // Are we iNarc Nemesis Confusable? - boolean isNemesisConfusable = false; - Mounted mLinker = weapon.getLinkedBy(); - if ( wtype.getAmmoType() == AmmoType.T_ATM || - ( mLinker != null && - mLinker.getType() instanceof MiscType && - !mLinker.isDestroyed() && !mLinker.isMissing() && !mLinker.isBreached() && - mLinker.getType().hasFlag(MiscType.F_ARTEMIS) ) ) { - if ((!weapon.getType().hasModes() || - !weapon.curMode().equals("Indirect")) && - ( ((atype.getAmmoType() == AmmoType.T_ATM) && - (atype.getMunitionType() == AmmoType.M_STANDARD || - atype.getMunitionType() == AmmoType.M_EXTENDED_RANGE || - atype.getMunitionType() == AmmoType.M_HIGH_EXPLOSIVE) ) || - ((atype.getAmmoType() == AmmoType.T_LRM || - atype.getAmmoType() == AmmoType.T_SRM) && - atype.getMunitionType() == AmmoType.M_ARTEMIS_CAPABLE))) { - isNemesisConfusable = true; - } - } else if (wtype.getAmmoType() == AmmoType.T_LRM || - wtype.getAmmoType() == AmmoType.T_SRM) { - if (usesAmmo && atype.getMunitionType() == AmmoType.M_NARC_CAPABLE) { - isNemesisConfusable = true; - } - } - - if (lastEntityId != ae.getId()) { - //report who is firing - r = new Report(3100); - r.subject = subjectId; - r.addDesc(ae); - addReport(r); - } - - // Swarming infantry can stop during any weapons phase after start. - if (Infantry.STOP_SWARM.equals(wtype.getInternalName())) { - // ... but only as their *only* attack action. - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - r = new Report(3105); - r.subject = subjectId; - r.add(toHit.getDesc()); - addReport(r); - return true; - } else { - //swarming ended succesfully - r = new Report(3110); - r.subject = subjectId; - addReport(r); - // Only apply the "stop swarm 'attack'" to the swarmed Mek. - if (ae.getSwarmTargetId() != target.getTargetId()) { - Entity other = game.getEntity(ae.getSwarmTargetId()); - other.setSwarmAttackerId(Entity.NONE); - } - else { - entityTarget.setSwarmAttackerId(Entity.NONE); - } - ae.setSwarmTargetId(Entity.NONE); - return true; - } - } - - // Report weapon attack and its to-hit value. - r = new Report(3115); - r.indent(); - r.newlines = 0; - r.subject = subjectId; - r.add(wtype.getName()); - if (entityTarget != null) { - r.addDesc(entityTarget); - } else { - r.messageId = 3120; - r.add(target.getDisplayName(), true); - } - addReport(r); - - boolean shotAtNemesisTarget = false; - // check for nemesis - if (isNemesisConfusable && !isNemesisConfused) { - // loop through nemesis targets - for (Enumeration e = game.getNemesisTargets(ae, target.getPosition());e.hasMoreElements();) { - Entity entity = (Entity)e.nextElement(); - //friendly unit with attached iNarc Nemesis pod standing in the way - r = new Report(3125); - r.subject = subjectId; - addReport(r); - weapon.setUsedThisRound(false); - WeaponAttackAction newWaa = new WeaponAttackAction(ae.getId(), - entity.getTargetId(), wr.waa.getWeaponId()); - newWaa.setNemesisConfused(true); - WeaponResult newWr = preTreatWeaponAttack(newWaa); - // attack the new target, and if we hit it, return; - if (resolveWeaponAttack(newWr, ae.getId(), true)) return true; - shotAtNemesisTarget = true; - } - } - if (shotAtNemesisTarget) { - //back to original target - r = new Report(3130); - r.subject = subjectId; - r.newlines = 0; - addReport(r); - } - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - r = new Report(3135); - r.subject = subjectId; - r.add(toHit.getDesc()); - addReport(r); - return false; - } - else if (toHit.getValue() == ToHitData.AUTOMATIC_FAIL) { - r = new Report(3140); - r.newlines = 0; - r.subject = subjectId; - r.add(toHit.getDesc()); - addReport(r); - } - else if (toHit.getValue() == ToHitData.AUTOMATIC_SUCCESS) { - r = new Report(3145); - r.newlines = 0; - r.subject = subjectId; - r.add(toHit.getDesc()); - addReport(r); - } - else { - //roll to hit - r = new Report(3150); - r.newlines = 0; - r.subject = subjectId; - r.add(toHit.getValue()); - addReport(r); - } - - // if firing an HGR unbraced, schedule a PSR - if (wtype.getAmmoType() == AmmoType.T_GAUSS_HEAVY && ae.mpUsed > 0) { - // the mod is weight-based - int nMod; - switch (ae.getWeightClass()) { - case EntityWeightClass.WEIGHT_LIGHT: - nMod = 2; - break; - case EntityWeightClass.WEIGHT_MEDIUM: - nMod = 1; - break; - case EntityWeightClass.WEIGHT_HEAVY: - nMod = 0; - break; - default: - nMod = -1; - } - PilotingRollData psr = new PilotingRollData(ae.getId(), nMod, - "fired HeavyGauss unbraced"); - psr.setCumulative(false); - game.addPSR(psr); - } - - // dice have been rolled, thanks - r = new Report(3155); - r.newlines = 0; - r.subject = subjectId; - r.add(wr.roll); - addReport(r); - - // check for AC or Prototype jams - int nShots = weapon.howManyShots(); - if (nShots > 1 || - (wtype.hasFlag(WeaponType.F_PROTOTYPE) && - wtype.getAmmoType() != AmmoType.T_NA) ) { - int jamCheck = 0; - if ((((wtype.getAmmoType() == AmmoType.T_AC_ULTRA) - || (wtype.getAmmoType() == AmmoType.T_AC_ULTRA_THB)) - && weapon.curMode().equals("Ultra")) || - wtype.hasFlag(WeaponType.F_PROTOTYPE)) { - jamCheck = 2; - if (weapon.getType().hasModes() && - weapon.curMode().equals("Ultra") && - wtype.hasFlag(WeaponType.F_PROTOTYPE)) { - jamCheck = 4; - } - } else if (wtype.getAmmoType() == AmmoType.T_AC_ROTARY) { - if (nShots == 2) { - jamCheck = 2; - } else if (nShots == 4) { - jamCheck = 3; - } else if (nShots == 6) { - jamCheck = 4; - } - } - - if (jamCheck > 0 && wr.roll <= jamCheck) { - r = new Report(1210); - // ultras and prototypes are destroyed by jamming - if ((wtype.getAmmoType() == AmmoType.T_AC_ULTRA) - || (wtype.getAmmoType() == AmmoType.T_AC_ULTRA_THB)) { - r.messageId = 3160; - weapon.setJammed(true); - weapon.setHit(true); - } else if (wtype.hasFlag(WeaponType.F_PROTOTYPE)) { - r.messageId = 3165; - weapon.setJammed(true); - weapon.setHit(true); - } else { - r.messageId = 3170; - weapon.setJammed(true); - } - r.subject = subjectId; - addReport(r); - return true; - } - } - - // Resolve roll for disengaged field inhibitors on PPCs, if needed - if (game.getOptions().booleanOption("maxtech_ppc_inhibitors") - && wtype.hasModes() - && weapon.curMode().equals("Field Inhibitor OFF") ) { - int rollTarget = 0; - int dieRoll = Compute.d6(2); - int distance = Compute.effectiveDistance(game, ae, target); - - if (distance>=3) { - rollTarget = 3; - } else if (distance == 2) { - rollTarget = 6; - } else if (distance == 1) { - rollTarget = 10; - } - //roll to avoid damage - r = new Report(3175); - r.subject = ae.getId(); - r.indent(); - addReport(r); - r = new Report(3180); - r.subject = ae.getId(); - r.indent(); - r.add(rollTarget); - r.add(dieRoll); - if (dieRoll0) { - for (int i=0; i 0) { - r = new Report(3230); - r.indent(); - r.subject = subjectId; - r.add(wr.amsShotDown[i]); - addReport(r); - } - } - - // Figure out the maximum number of missile hits. - // TODO: handle this in a different place. - int maxMissiles = 0; - if ( usesAmmo ) { - maxMissiles = wtype.getRackSize(); - if ( wtype.hasFlag(WeaponType.F_DOUBLE_HITS) ) { - maxMissiles *= 2; - } - if ( ae instanceof BattleArmor ) { - platoon = (Infantry) ae; - maxMissiles *= platoon.getShootingStrength(); - } - } - if (bSwarm || bSwarmI) { - swarmMissilesNowLeft = swarmMissilesLeft > 0 ? swarmMissilesLeft : maxMissiles; - maxMissiles = swarmMissilesLeft > 0 ? swarmMissilesLeft : maxMissiles; - } - - // If the AMS shot down *all* incoming missiles, if - // the shot is an automatic failure, or if it's from - // a Streak rack, then Infernos can't ignite the hex - // and any building is safe from damage. - if ( (usesAmmo && wr.amsShotDownTotal >= maxMissiles) - || toHit.getValue() == TargetRoll.AUTOMATIC_FAIL - || ((wtype.getAmmoType() == AmmoType.T_SRM_STREAK - || wtype.getAmmoType() == AmmoType.T_LRM_STREAK) - && !isAngelECMAffected)) { - return !bMissed; - } - // If we're using swarm munition, set the number of missiles that - // are left - if ((bSwarm || bSwarmI) && entityTarget != null) { - swarmMissilesNowLeft -= wr.amsShotDownTotal; - Entity swarmTarget = Compute.getSwarmTarget(game, ae.getId(), entityTarget, wr.waa.getWeaponId()); - if (swarmTarget != null) { - r = new Report(3420); - r.subject = ae.getId(); - r.indent(); - r.add(swarmMissilesNowLeft); - addReport(r); - weapon.setUsedThisRound(false); - WeaponAttackAction newWaa = new WeaponAttackAction(ae.getId(), - swarmTarget.getTargetId(), wr.waa.getWeaponId()); - newWaa.setSwarmingMissiles(true); - newWaa.setOldTargetId(target.getTargetId()); - newWaa.setAmmoId(wr.waa.getAmmoId()); - WeaponResult newWr = preTreatWeaponAttack(newWaa); - resolveWeaponAttack(newWr, ae.getId(), false, swarmMissilesNowLeft); - } else { - r = new Report(3425); - r.subject = ae.getId(); - r.indent(); - addReport(r); - } - } - - // Shots that miss an entity can set fires. - // Infernos always set fires. Otherwise - // Buildings can't be accidentally ignited, - // and some weapons can't ignite fires. - if ( entityTarget != null && - ( bInferno || - ( bldg == null && - wtype.getFireTN() != TargetRoll.IMPOSSIBLE ) ) ) { - tryIgniteHex(target.getPosition(), ae.getId(), bInferno, 11); - } - - // BMRr, pg. 51: "All shots that were aimed at a target inside - // a building and miss do full damage to the building instead." - // BMRr, pg. 77: If the spotting unit successfully designates the target but - // the missile misses, it still detonates in the hex and causes 5 - // points of artillery damage each to all units in the target hex - if ( !targetInBuilding) { - return !bMissed; - } - } - - // special case NARC hits. No damage, but a beacon is appended - if (!bMissed && - wtype.getAmmoType() == AmmoType.T_NARC && - atype.getMunitionType() != AmmoType.M_NARC_EX) { - - if (wr.amsShotDownTotal > 0) { - r = new Report(3235); - r.subject = subjectId; - addReport(r); - for (int i=0; i < wr.amsShotDown.length; i++) { - r = new Report(3230); - r.indent(1); - r.subject = subjectId; - r.add(wr.amsShotDown[i]); - addReport(r); - } - r = new Report(3240); - r.subject = subjectId; - addReport(r); - } else if (entityTarget == null) { - r = new Report(3245); - r.subject = subjectId; - addReport(r); - } else { - entityTarget.setNarcedBy(ae.getOwner().getTeam()); - //narced - r = new Report(3250); - r.subject = subjectId; - addReport(r); - } - return !bMissed; - } - - // special case iNARC hits. No damage, but a beacon is appended - if (!bMissed && - wtype.getAmmoType() == AmmoType.T_INARC && - atype.getMunitionType() != AmmoType.M_EXPLOSIVE) { - - if (wr.amsShotDownTotal > 0) { - r = new Report(3235); - r.subject = subjectId; - addReport(r); - for (int i=0; i < wr.amsShotDown.length; i++) { - r = new Report(3230); - r.indent(1); - r.subject = subjectId; - r.add(wr.amsShotDown[i]); - addReport(r); - } - r = new Report(3240); - r.subject = subjectId; - addReport(r); - } else if (entityTarget == null) { - r = new Report(3245); - r.subject = subjectId; - addReport(r); - } else { - INarcPod pod = null; - if (atype.getMunitionType() == AmmoType.M_ECM) { - pod = new INarcPod( ae.getOwner().getTeam(), - INarcPod.ECM ); - r = new Report(3251); - r.subject = subjectId; - addReport(r); - } else if (atype.getMunitionType() == AmmoType.M_HAYWIRE) { - pod = new INarcPod( ae.getOwner().getTeam(), - INarcPod.HAYWIRE ); - r = new Report(3252); - r.subject = subjectId; - addReport(r); - } else if (atype.getMunitionType() == AmmoType.M_NEMESIS) { - pod = new INarcPod( ae.getOwner().getTeam(), - INarcPod.NEMESIS ); - r = new Report(3253); - r.subject = subjectId; - addReport(r); - } else { - pod = new INarcPod( ae.getOwner().getTeam(), - INarcPod.HOMING ); - r = new Report(3254); - r.subject = subjectId; - addReport(r); - } - entityTarget.attachINarcPod(pod); - } - return !bMissed; - } - - // attempt to clear minefield by LRM/MRM fire. - if (!bMissed && target.getTargetType() == Targetable.TYPE_MINEFIELD_CLEAR) { - int clearAttempt = Compute.d6(2); - - if (clearAttempt >= Minefield.CLEAR_NUMBER_WEAPON) { - //minefield cleared - r = new Report(3255); - r.indent(1); - r.subject = subjectId; - addReport(r); - Coords coords = target.getPosition(); - - Enumeration minefields = game.getMinefields(coords).elements(); - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - - removeMinefield(mf); - } - } else { - //fails to clear - r = new Report(3260); - r.indent(1); - r.subject = subjectId; - addReport(r); - } - return !bMissed; - } - - // yeech. handle damage. . different weapons do this in very different ways - int nCluster = 1, nSalvoBonus = 0; - boolean bSalvo = false; - // ecm check is heavy, so only do it once - boolean bCheckedECM = false; - boolean bECMAffected = false; - boolean bMekStealthActive = false; - String sSalvoType = " shot(s) "; - boolean bAllShotsHit = false; - int nRange = ae.getPosition().distance(target.getPosition()); - int nMissilesModifier = 0; - boolean maxtechmissiles = game.getOptions().booleanOption("maxtech_mslhitpen"); - if (maxtechmissiles) { - if (nRange<=1) { - nMissilesModifier = +1; - } else if (nRange <= wtype.getShortRange()) { - nMissilesModifier = 0; - } else if (nRange <= wtype.getMediumRange()) { - nMissilesModifier = -1; - } else { - nMissilesModifier = -2; - } - } - // All shots fired by a Streak SRM weapon, during - // a Mech Swarm hit, or at an adjacent building. - if (((wtype.getAmmoType() == AmmoType.T_SRM_STREAK - || wtype.getAmmoType() == AmmoType.T_LRM_STREAK) - && !isAngelECMAffected) - || wtype.getAmmoType() == AmmoType.T_NARC - || ae.getSwarmTargetId() == wr.waa.getTargetId() - || ((target.getTargetType() == Targetable.TYPE_BLDG_IGNITE - || target.getTargetType() == Targetable.TYPE_BUILDING) - && ae.getPosition().distance(target.getPosition()) <= 1)) { - bAllShotsHit = true; - } - - // Mek swarms attach the attacker to the target. - if ( !bMissed && Infantry.SWARM_MEK.equals( wtype.getInternalName() ) ) { - // Is the target already swarmed? - if ( Entity.NONE != entityTarget.getSwarmAttackerId() ) { - r = new Report(3265); - r.subject = subjectId; - addReport(r); - } - // Did the target get destroyed by weapons fire? - else if ( entityTarget.isDoomed() || entityTarget.isDestroyed() || - entityTarget.getCrew().isDead() ) { - r = new Report(3270); - r.subject = subjectId; - addReport(r); - } else { - //success - r = new Report(3275); - r.subject = subjectId; - addReport(r); - ae.setSwarmTargetId( wr.waa.getTargetId() ); - entityTarget.setSwarmAttackerId( wr.waa.getEntityId() ); - } - return !bMissed; - } - - // Magnetic Mine Launchers roll number of hits on battle armor - // hits table but use # mines firing instead of men shooting. - else if ( wtype.getInternalName().equals(BattleArmor.MINE_LAUNCHER) ) { - hits = nShots; - if ( !bAllShotsHit ) { - hits = Compute.getBattleArmorHits( hits ); - } - bSalvo = true; - sSalvoType = " mine(s) "; - } - - // Other battle armor attacks use # of men firing to determine hits. - // Each hit can be in a new location. The damage per shot comes from - // the "racksize", or from the ammo, for ammo weapons - else if ( isBattleArmorAttack ) { - bSalvo = true; - platoon = (Infantry) ae; - nCluster = 1; - if (usesAmmo) { - nDamPerHit = atype.getDamagePerShot(); - } - nDamPerHit = wtype.getRackSize(); - hits = platoon.getShootingStrength(); - // All attacks during Mek Swarms hit; all - // others use the Battle Armor hits table. - if ( !bAllShotsHit ) { - hits = Compute.getBattleArmorHits( hits ); - } - - // Handle Inferno SRM squads. - if (bInferno) { - nCluster = hits; - nDamPerHit = 0; - sSalvoType = " Inferno missle(s) "; - bSalvo = false; - } - if (ae.getSwarmTargetId() == wr.waa.getTargetId()) - nDamPerHit += ((BattleArmor)ae).getVibroClawDamage(); - } - - // Infantry damage depends on # men left in platoon. - else if (isWeaponInfantry) { - bSalvo = true; - platoon = (Infantry)ae; - nCluster = 5; - nDamPerHit = 1; - hits = platoon.getDamage(platoon.getShootingStrength()); - //TODO: Hmm, this should be localizable - sSalvoType = " damage are inflicted by the shots that "; - - // Handle Inferno SRM infantry. - if (bInferno) { - nCluster = hits; - nDamPerHit = 0; - sSalvoType = " Inferno missile(s) "; - bSalvo = false; - } - } else if (wtype.getDamage() == WeaponType.DAMAGE_MISSILE || - wtype.hasFlag(WeaponType.F_MISSILE_HITS) ) { - bSalvo = true; - - // Weapons with ammo type T_BA_MG or T_BA_SMALL_LASER - // don't have an atype object. - if ( wtype.getAmmoType() == AmmoType.T_BA_MG || - wtype.getAmmoType() == AmmoType.T_BA_SMALL_LASER ) { - nDamPerHit = Math.abs( wtype.getAmmoType() ); - } else { - sSalvoType = " missile(s) "; - // Get the damage from the linked ammo. - nDamPerHit = atype.getDamagePerShot(); - if ((wtype.getAmmoType() == AmmoType.T_TBOLT5 - || wtype.getAmmoType() == AmmoType.T_TBOLT10 - || wtype.getAmmoType() == AmmoType.T_TBOLT15 - || wtype.getAmmoType() == AmmoType.T_TBOLT20 - ) && nRange <= wtype.getMinimumRange()) { - nDamPerHit /= 2; - } - } - - if ( wtype.getAmmoType() == AmmoType.T_LRM || - wtype.getAmmoType() == AmmoType.T_LRM_STREAK || - wtype.getAmmoType() == AmmoType.T_MRM || - wtype.getAmmoType() == AmmoType.T_ATM || - wtype.getAmmoType() == AmmoType.T_EXLRM || - wtype.getAmmoType() == AmmoType.T_ROCKET_LAUNCHER ) { - nCluster = 5; - } - - // calculate # of missiles hitting - if ( wtype.getAmmoType() == AmmoType.T_LRM || - wtype.getAmmoType() == AmmoType.T_SRM || - wtype.getAmmoType() == AmmoType.T_ATM ) { - - // check for artemis, else check for narc and similar things - mLinker = weapon.getLinkedBy(); - if ( wtype.getAmmoType() == AmmoType.T_ATM || - ( mLinker != null && - mLinker.getType() instanceof MiscType && - !mLinker.isDestroyed() && !mLinker.isMissing() && !mLinker.isBreached() && - mLinker.getType().hasFlag(MiscType.F_ARTEMIS) ) && - atype.getMunitionType() == AmmoType.M_ARTEMIS_CAPABLE) { - - // check ECM interference - if (!bCheckedECM) { - // Attacking Meks using stealth suffer ECM effects. - if ( ae instanceof Mech ) { - bMekStealthActive = ae.isStealthActive(); - } - //if the attacker is effected by ECM or the target is protected by ECM then - //act as if effected. - if (Compute.isAffectedByECM(ae, ae.getPosition(), target.getPosition()) || - Compute.isAffectedByAngelECM(ae, ae.getPosition(), target.getPosition())) - bECMAffected = true; - else if ( Compute.isProtectedByECM((Entity)target,target.getPosition(),ae.getPosition()) || - Compute.isProtectedByAngelECM((Entity)target,target.getPosition(),ae.getPosition())) - bECMAffected = true; - else - bECMAffected = false; - bCheckedECM = true; - } - // also no artemis for IDF, and only use standard ammo (excepot for ATMs) - if (!bECMAffected && !bMekStealthActive - && (!weapon.getType().hasModes() - || !weapon.curMode().equals("Indirect")) - && ( (atype.getAmmoType() == AmmoType.T_ATM && - (atype.getMunitionType() == AmmoType.M_STANDARD|| - atype.getMunitionType() == AmmoType.M_EXTENDED_RANGE || - atype.getMunitionType() == AmmoType.M_HIGH_EXPLOSIVE)) || - ( (atype.getAmmoType() == AmmoType.T_LRM || - atype.getAmmoType() == AmmoType.T_SRM) && - atype.getMunitionType() == AmmoType.M_ARTEMIS_CAPABLE))) { - nSalvoBonus += 2; - } - } else if (entityTarget != null && - (entityTarget.isNarcedBy(ae.getOwner().getTeam()) || - entityTarget.isINarcedBy(ae.getOwner().getTeam()))) { - // check ECM interference - if (!bCheckedECM) { - // Attacking Meks using stealth suffer ECM effects. - if ( ae instanceof Mech ) { - bMekStealthActive = ae.isStealthActive(); - } - - //if the attacker is effected by ECM or the target is protected by ECM then - //act as if effected. - if (Compute.isAffectedByECM(ae, ae.getPosition(), target.getPosition()) || - Compute.isAffectedByAngelECM(ae, ae.getPosition(), target.getPosition())) - bECMAffected = true; - else if ( Compute.isProtectedByECM((Entity)target,target.getPosition(),ae.getPosition()) || - Compute.isProtectedByAngelECM((Entity)target,target.getPosition(),ae.getPosition())) - bECMAffected = true; - else - bECMAffected = false; - bCheckedECM = true; - } - // only apply Narc bonus if we're not suffering ECM effect - // and we are using narc ammo. - if (!bECMAffected - && !bMekStealthActive - && ((atype.getAmmoType() == AmmoType.T_LRM) || (atype.getAmmoType() == AmmoType.T_SRM)) - && atype.getMunitionType() == AmmoType.M_NARC_CAPABLE) { - nSalvoBonus += 2; - } - } - } - - // If dealing with Inferno rounds set damage to zero and reset - // all salvo bonuses (cannot mix with other special munitions). - if (bInferno) { - nDamPerHit = 0; - nSalvoBonus = 0; - sSalvoType = " inferno missile(s) "; - bSalvo = false; - } - if (bSwarm) { - sSalvoType = " swarm missile(s) "; - } - if (bSwarmI) { - sSalvoType = " swarm-I missile(s) "; - } - if (bAntiTSM) { - sSalvoType = " anti-TSM missile(s) "; - } - - // If dealing with fragmentation missiles, - // it does double damage to infantry... - if (bFragmentation) { - sSalvoType = " fragmentation missile(s) "; - } - - // Acid-heads, like infernos, can't mix with any other munitions type. - if (bAcidHead) { - nDamPerHit = 1; - nSalvoBonus = -2; - sSalvoType = " acid-head missile(s) "; - } - - // Large MRM missile racks roll twice. - // MRM missiles never recieve hit bonuses. - if ( wtype.getRackSize() == 30 || wtype.getRackSize() == 40 ) { - hits = Compute.missilesHit(wtype.getRackSize() / 2, nMissilesModifier+glancingMissileMod, maxtechmissiles | bGlancing) + - Compute.missilesHit(wtype.getRackSize() / 2, nMissilesModifier+glancingMissileMod, maxtechmissiles | bGlancing); - } - - // Battle Armor units multiply their racksize by the number - // of men shooting and they can't get missile hit bonuses. - else if ( ae instanceof BattleArmor ) { - platoon = (Infantry) ae; - int temp = wtype.getRackSize() * platoon.getShootingStrength(); - - // Do all shots hit? - if ( bAllShotsHit ) { - hits = temp; - } else { - // Account for more than 20 missles hitting. - hits = 0; - while ( temp > 20 ) { - hits += Compute.missilesHit( 20, nMissilesModifier+glancingMissileMod, maxtechmissiles | bGlancing ); - temp -= 20; - } - hits += Compute.missilesHit( temp, nMissilesModifier+glancingMissileMod, maxtechmissiles | bGlancing ); - } // End not-all-shots-hit - } - - // If all shots hit, use the full racksize. - else if ( bAllShotsHit ) { - hits = wtype.getRackSize(); - } - // In all other circumstances, roll for hits. - else { - hits = Compute.missilesHit(wtype.getRackSize(), nSalvoBonus + nMissilesModifier + glancingMissileMod, maxtechmissiles | bGlancing); - // swarm missiles that didn't hit continue - if ( (bSwarm || bSwarmI) && swarmMissilesLeft == 0) { - swarmMissilesNowLeft = wtype.getRackSize() - hits; - } - } - // anti TSM missiles hit with half the number, round up - if (bAntiTSM) { - hits = (int)Math.ceil((double)hits/2); - } - // swarm or swarm-I shots may just hit with the remaining missiles - if ((bSwarm || bSwarmI) && (swarmMissilesLeft > 0)) { - int swarmsForHitTable = 5; - if (swarmMissilesLeft > 5 && swarmMissilesLeft <= 10) - swarmsForHitTable = 10; - else if (swarmMissilesLeft > 10 && swarmMissilesLeft <= 15) - swarmsForHitTable = 15; - else if (swarmMissilesLeft > 15 && swarmMissilesLeft <= 20) - swarmsForHitTable = 20; - hits = Compute.missilesHit(swarmsForHitTable, nSalvoBonus + nMissilesModifier + glancingMissileMod, maxtechmissiles | bGlancing); - if (hits > swarmMissilesLeft) { - hits = swarmMissilesLeft; - } - swarmMissilesNowLeft = swarmMissilesLeft - hits; - } - - // Advanced SRMs may get additional missiles - if ( usesAmmo && - atype.getAmmoType() == AmmoType.T_SRM_ADVANCED) { - int tmp = wtype.getRackSize() * platoon.getShootingStrength(); - if (hits%2 == 1 && hits < tmp) { - hits++; - } - } - - } else if (usesAmmo - && ((atype.getAmmoType() == AmmoType.T_AC_LBX) - || (atype.getAmmoType() == AmmoType.T_AC_LBX_THB)) - && atype.getMunitionType() == AmmoType.M_CLUSTER) { - // Cluster shots break into single point clusters. - bSalvo = true; - hits = wtype.getRackSize(); - // war of 3039 prototype LBXs get -1 mod on missile chart - int nMod = wtype.hasFlag(WeaponType.F_PROTOTYPE) ? 0 : -1; - if ( !bAllShotsHit ) { - if (!bGlancing) { - hits = Compute.missilesHit( hits, nMod ); - } else { - // if glancing blow, half the number of missiles that hit, - // that halves damage. do this, and not adjust number of - // pellets, because maxtech only talks about missile weapons - hits = Compute.missilesHit(hits, nMod)/2; - } - } - nDamPerHit = 1; - } else if (nShots > 1) { - // this should handle multiple attacks from ultra and rotary ACs - bSalvo = true; - hits = nShots; - if ( !bAllShotsHit ) { - hits = Compute.missilesHit( hits ); - } - } - else if (wtype.getAmmoType() == AmmoType.T_GAUSS_HEAVY) { - // HGR does range-dependent damage - if (nRange <= wtype.getShortRange()) { - nDamPerHit = 25; - } else if (nRange <= wtype.getMediumRange()) { - nDamPerHit = 20; - } else { - nDamPerHit = 10; - } - } else if (wtype.hasFlag(WeaponType.F_ENERGY)) { - // Check for Altered Damage from Energy Weapons (MTR, pg.22) - nDamPerHit = wtype.getDamage(); - if (game.getOptions().booleanOption("maxtech_altdmg")) { - if (nRange<=1) { - nDamPerHit++; - } else if (nRange <= wtype.getMediumRange()) { - // Do Nothing for Short and Medium Range - } else if (nRange <= wtype.getLongRange()) { - nDamPerHit--; - } else if (nRange <= wtype.getExtremeRange()) { - nDamPerHit = (int)Math.floor(nDamPerHit/2.0); - } - } - } else if (weapon.isRapidfire() && - !(target instanceof Infantry && - !(target instanceof BattleArmor)) ){ - // Check for rapid fire Option. Only MGs can be rapidfire. - nDamPerHit = Compute.d6(); - ammoUsage = 3*nDamPerHit; - if (ae.getTotalAmmoOfType(ammo.getType())>0) { - for (int i=0; i 0) { - for (int i=0; i < wr.amsShotDown.length; i++) { - int shotDown = Math.min(wr.amsShotDown[i], hits); - r = new Report(3280); - r.indent(1); - r.subject = subjectId; - r.add(shotDown); - addReport(r); - } - hits -= wr.amsShotDownTotal; - } - - // Is the building hit by Inferno rounds? - if ( bInferno && hits > 0 ) { - - // start a fire in the targets hex - Coords c = target.getPosition(); - IHex h = game.getBoard().getHex(c); - - // Is there a fire in the hex already? - if ( h.containsTerrain( Terrains.FIRE ) ) { - r = new Report(3285); - r.indent(2); - r.subject = subjectId; - r.add(hits); - r.add(c.getBoardNum()); - addReport(r); - } else { - r = new Report(3290); - r.indent(2); - r.subject = subjectId; - r.add(hits); - r.add(c.getBoardNum()); - addReport(r); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - } - game.getBoard().addInfernoTo - ( c, InfernoTracker.STANDARD_ROUND, hits ); - sendChangedHex(c); - - } - - // Damage the building in one big lump. - else { - - // Only report if damage was done to the building. - int toBldg = hits * nDamPerHit; - if ( toBldg > 0 ) { - Report buildingReport = damageBuilding( bldg, toBldg ); - buildingReport.indent(2); - buildingReport.newlines = 1; - buildingReport.subject = subjectId; - addReport(buildingReport); - } - - } // End rounds-hit - - } // End missed-target-in-building - return !bMissed; - - } // End missed-target - - // The building shields all units from a certain amount of damage. - // The amount is based upon the building's CF at the phase's start. - int bldgAbsorbs = 0; - if ( targetInBuilding && bldg != null ) { - bldgAbsorbs = (int) Math.ceil( bldg.getPhaseCF() / 10.0 ); - } - - // All attacks (except from infantry weapons) - // during Mek Swarms hit the same location. - if ( !isWeaponInfantry && - ae.getSwarmTargetId() == wr.waa.getTargetId() ) { - nCluster = hits; - } - - // Battle Armor MGs do one die of damage per hit to PBI. - if ( wtype.getAmmoType() == AmmoType.T_BA_MG && - (target instanceof Infantry) && - !(target instanceof BattleArmor) ) { - - // ASSUMPTION: Building walls protect infantry from BA MGs. - if ( bldgAbsorbs > 0 ) { - int toBldg = nDamPerHit * hits; - r = new Report(3295); - r.newlines = 0; - r.subject = subjectId; - r.add(hits); - r.add(sSalvoType); - addReport(r); - - Report buildingReport = - damageBuilding( bldg, - Math.min( toBldg, bldgAbsorbs ), - " absorbs the shots, taking " ); - buildingReport.newlines = 1; - buildingReport.subject = subjectId; - addReport(buildingReport); - return !bMissed; - } - nDamPerHit = Compute.d6(hits); - r = new Report(3300); - r.newlines = 0; - r.subject = subjectId; - r.add(nDamPerHit); - r.add(sSalvoType); - addReport(r); - hits = 1; - } - - // Mech and Vehicle MGs do *DICE* of damage to PBI. - else if (usesAmmo && atype.hasFlag(AmmoType.F_MG) && - !isWeaponInfantry && (target instanceof Infantry) && - !(target instanceof BattleArmor) && !weapon.isRapidfire()) { - - int dice = wtype.getDamage(); - - // A building may absorb the entire shot. - if ( nDamPerHit <= bldgAbsorbs ) { - int toBldg = nDamPerHit * hits; - int curCF = bldg.getCurrentCF(); - curCF = Math.min( curCF, toBldg ); - bldg.setCurrentCF( curCF ); - if ( bSalvo ) { - r = new Report(3305); - r.subject = subjectId; - r.add(hits); - r.add(sSalvoType); - addReport(r); - } else{ - r = new Report(3310); - r.subject = subjectId; - addReport(r); - } - r = new Report(3315); - r.indent(2); - r.subject = subjectId; - addReport(r); - Report buildingReport = - damageBuilding( bldg, - Math.min( toBldg, bldgAbsorbs ), - " absorbs the shots, taking " ); - buildingReport.newlines = 1; - buildingReport.subject = subjectId; - addReport(buildingReport); - return !bMissed; - } - - // If a building absorbs partial damage, reduce the dice of damage. - else if ( bldgAbsorbs > 0 ) { - dice -= bldgAbsorbs; - } - - nDamPerHit = Compute.d6( dice ); - r = new Report(3320); - r.subject = subjectId; - r.add(nDamPerHit); - r.add(sSalvoType); - addReport(r); - bSalvo = true; - - // If a building absorbed partial damage, report it now - // instead of later and then clear the variable. - if ( bldgAbsorbs > 0 ) { - Report buildingReport = damageBuilding( bldg, bldgAbsorbs ); - buildingReport.indent(2); - buildingReport.subject = subjectId; - addReport(buildingReport); - bldgAbsorbs = 0; - } - - } - - // Report the number of hits. Infernos have their own reporting - else if (bSalvo && !bInferno) { - r = new Report(3325); - r.subject = subjectId; - r.add(hits); - r.add(sSalvoType); - r.add(toHit.getTableDesc()); - r.newlines = 0; - addReport(r); - if (bECMAffected) { - //ECM prevents bonus - r = new Report(3330); - r.subject = subjectId; - r.newlines = 0; - addReport(r); - } - else if (bMekStealthActive) { - //stealth prevents bonus - r = new Report(3335); - r.subject = subjectId; - r.newlines = 0; - addReport(r); - } - if (nSalvoBonus > 0) { - r = new Report(3340); - r.subject = subjectId; - r.add(nSalvoBonus); - r.newlines = 0; - addReport(r); - } - r = new Report(3345); - r.subject = subjectId; - r.newlines = 0; - addReport(r); - - if (wr.amsShotDownTotal > 0) { - for (int i=0; i < wr.amsShotDown.length; i++) { - int shotDown = Math.min(wr.amsShotDown[i], hits); - r = new Report(3350); - r.indent(); - r.subject = subjectId; - r.add(wr.amsShotDown[i]); - r.add(shotDown); - r.newlines = 0; - addReport(r); - } - hits -= wr.amsShotDownTotal; - - addNewLines(); - if (hits < 1) { - //all missiles shot down - r = new Report(3355); - r.indent(); - r.subject = subjectId; - r.newlines = 0; - addReport(r); - } else { - r = new Report(3360); - r.indent(); - r.subject = subjectId; - r.add(hits); - r.newlines = 0; - addReport(r); - } - } - } - - // convert the ATM missile damages to LRM type 5 point cluster damage - // done here after AMS has been performed - if (wtype.getAmmoType() == AmmoType.T_ATM) { - hits = nDamPerHit * hits; - nDamPerHit = 1; - } - - // Make sure the player knows when his attack causes no damage. - if ( hits == 0 ) { - r = new Report(3365); - r.subject = subjectId; - addReport(r); - } - - // for each cluster of hits, do a chunk of damage - while (hits > 0) { - int nDamage; - - // If the attack was with inferno rounds then - // do heat and fire instead of damage. - if ( bInferno ) { - // AMS can shoot down infernos, too. - if (wr.amsShotDownTotal > 0) { - for (int i=0; i < wr.amsShotDown.length; i++) { - int shotDown = Math.min(wr.amsShotDown[i], hits); - r = new Report(3350); - r.indent(); - r.subject = subjectId; - r.add(wr.amsShotDown[i]); - r.add(shotDown); - r.newlines = 0; - addReport(r); - } - hits -= wr.amsShotDownTotal; - - addNewLines(); - if (hits < 1) { - //all missiles shot down - r = new Report(3355); - r.indent(); - r.subject = subjectId; - r.newlines = 0; - addReport(r); - } else { - r = new Report(3360); - r.indent(); - r.subject = subjectId; - r.add(hits); - r.newlines = 0; - addReport(r); - } - if ( hits <= 0 ) { - continue; - } - } - - // targeting a hex for ignition - if( target.getTargetType() == Targetable.TYPE_HEX_IGNITE || - target.getTargetType() == Targetable.TYPE_BLDG_IGNITE ) { - - //inferno missiles hit - r = new Report(3370); - r.subject = subjectId; - r.add(hits); - addReport(r); - - // Unless there a fire in the hex already, start one. - Coords c = target.getPosition(); - IHex h = game.getBoard().getHex(c); - if ( !h.containsTerrain( Terrains.FIRE ) ) { - r = new Report(3005); - r.subject = subjectId; - r.add(c.getBoardNum()); - addReport(r); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - } - game.getBoard().addInfernoTo - ( c, InfernoTracker.STANDARD_ROUND, hits ); - sendChangedHex(c); - - return !bMissed; - } - - // Targeting an entity - if (entityTarget != null ) { - r = new Report(3375); - r.subject = subjectId; - r.add(hits); - addReport(r); - - if(game.getOptions().booleanOption("vehicle_fires") - && entityTarget instanceof Tank) { - checkForVehicleFire((Tank)entityTarget, true); - } else { - entityTarget.infernos.add( InfernoTracker.STANDARD_ROUND, - hits ); - r = new Report(3205); - r.indent(2); - r.subject = subjectId; - r.addDesc(entityTarget); - r.add(entityTarget.infernos.getTurnsLeftToBurn()); - addReport(r); - } - - // Start a fire in the targets hex, unless already on fire. - Coords c = target.getPosition(); - IHex h = game.getBoard().getHex(c); - - // Unless there a fire in the hex already, start one. - if ( !h.containsTerrain( Terrains.FIRE ) ) { - r = new Report(3005); - r.subject = subjectId; - r.add(c.getBoardNum()); - addReport(r); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - } - game.getBoard().addInfernoTo - ( c, InfernoTracker.STANDARD_ROUND, 1 ); - sendChangedHex(c); - - return !bMissed; - } - - } // End is-inferno - - // targeting a hex for igniting - if( target.getTargetType() == Targetable.TYPE_HEX_IGNITE || - target.getTargetType() == Targetable.TYPE_BLDG_IGNITE ) { - if ( !bSalvo ) { - //hits! - r = new Report(2270); - r.subject = subjectId; - r.newlines = 0; - addReport(r); - } - // We handle Inferno rounds above. - int tn = wtype.getFireTN(); - if(bIncendiary) { - tn = 5; // Incendiary AC and LRM - } - if (tn != TargetRoll.IMPOSSIBLE) { - if ( bldg != null ) { - tn += bldg.getType() - 1; - } - addNewLines(); - tryIgniteHex( target.getPosition(), ae.getId(), bInferno, tn, true ); - } - return !bMissed; - } - - // targeting a hex for clearing - if (target.getTargetType() == Targetable.TYPE_HEX_CLEAR) { - - nDamage = nDamPerHit * hits; - if ( !bSalvo ) { - //hits! - r = new Report(2270); - r.subject = subjectId; - r.newlines = 0; - addReport(r); - } - if (ae instanceof Infantry) { - //infantry cannot clear hexes - r = new Report(3380); - r.indent(); - r.subject = subjectId; - addReport(r); - return !bMissed; - } - - - //report that damge was "applied" to terrain - r = new Report(3385); - r.indent(); - r.subject = subjectId; - r.add(nDamage); - addReport(r); - - // Any clear attempt can result in accidental ignition, even - // weapons that can't normally start fires. that's weird. - // Buildings can't be accidentally ignited. - if ( bldg == null) { - boolean alreadyIgnited = game.getBoard().getHex(target.getPosition()).containsTerrain(Terrains.FIRE); - boolean ignited = tryIgniteHex(target.getPosition(), subjectId, bInferno, 9); - if (!alreadyIgnited && ignited) return !bMissed; - } - - int tn = 14 - nDamage; - tryClearHex(target.getPosition(), tn, ae.getId()); - - return !bMissed; - } - - // Targeting a building. - if ( target.getTargetType() == Targetable.TYPE_BUILDING ) { - - // Is the building hit by Inferno rounds? - if ( bInferno ) { - - // start a fire in the targets hex - Coords c = target.getPosition(); - IHex h = game.getBoard().getHex(c); - - // Is there a fire in the hex already? - if ( h.containsTerrain( Terrains.FIRE ) ) { - r = new Report(3285); - r.subject = subjectId; - r.add(hits); - r.add(c.getBoardNum()); - addReport(r); - } else { - r = new Report(3290); - r.subject = subjectId; - r.add(hits); - r.add(c.getBoardNum()); - addReport(r); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - } - game.getBoard().addInfernoTo - ( c, InfernoTracker.STANDARD_ROUND, hits ); - sendChangedHex(c); - - } else { - // The building takes the full brunt of the attack. - nDamage = nDamPerHit * hits; - if ( !bSalvo ) { - //hits! - r = new Report(3390); - r.subject = subjectId; - addReport(r); - } - addNewLines(); - Report buildingReport = damageBuilding( bldg, nDamage ); - buildingReport.indent(2); - buildingReport.newlines = 1; - buildingReport.subject = subjectId; - addReport(buildingReport); - - // Damage any infantry in the hex. - this.damageInfantryIn( bldg, nDamage ); - } - - // And we're done! - return !bMissed; - } - - // Battle Armor squads equipped with fire protection - // gear automatically avoid flaming death. - if ( wtype.hasFlag(WeaponType.F_FLAMER) && - target instanceof BattleArmor ) { - - for ( Enumeration iter = entityTarget.getMisc(); - iter.hasMoreElements(); ) { - Mounted mount = (Mounted) iter.nextElement(); - EquipmentType equip = mount.getType(); - if ( BattleArmor.FIRE_PROTECTION.equals - (equip.getInternalName()) ) { - if ( !bSalvo ) { - //hits - r = new Report(3390); - r.subject = subjectId; - addReport(r); - } - r = new Report(3395); - r.indent(2); - r.subject = subjectId; - r.addDesc(entityTarget); - addReport(r); - - // A building may be damaged, even if the squad is not. - if ( bldgAbsorbs > 0 ) { - int toBldg = nDamPerHit * Math.min( bldgAbsorbs, - hits ); - Report buildingReport = damageBuilding( bldg, toBldg ); - buildingReport.indent(2); - buildingReport.newlines = 1; - buildingReport.subject = subjectId; - addReport(buildingReport); - } - - return !bMissed; - } - } - } // End target-may-be-immune - - // Flamers do heat to mechs instead damage if the option is - // available and the mode is set. - if (entityTarget != null - && (entityTarget instanceof Mech) - && wtype.hasFlag(WeaponType.F_FLAMER) - && game.getOptions().booleanOption("flamer_heat") - && wtype.hasModes() - && weapon.curMode().equals("Heat")) { - nDamage = nDamPerHit * hits; - if ( !bSalvo ) { - //hits - r = new Report(3390); - r.subject = subjectId; - addReport(r); - } - r = new Report(3400); - r.subject = subjectId; - r.indent(2); - r.add(nDamage); - r.newlines = 0; - addReport(r); - entityTarget.heatBuildup += nDamage; - hits = 0; - } else if (entityTarget != null) { - HitData hit = entityTarget.rollHitLocation - ( toHit.getHitTable(), - toHit.getSideTable(), - wr.waa.getAimedLocation(), - wr.waa.getAimingMode() ); - - if (wtype.hasFlag(WeaponType.F_PLASMA_MFUK) - && (entityTarget instanceof Mech)) { - nDamage = nDamPerHit * hits; - if (!bSalvo) { - //hits - r = new Report(3390); - r.subject = subjectId; - addReport(r); - } - r = new Report(3400); - r.subject = subjectId; - r.indent(2); - r.add(5); - r.newlines = 0; - addReport(r); - entityTarget.heatBuildup += 5; - } - - // If a leg attacks hit a leg that isn't - // there, then hit the other leg. - if ( wtype.getInternalName().equals("LegAttack") && - entityTarget.getInternal(hit) <= 0 ) { - if ( hit.getLocation() == Mech.LOC_RLEG ) { - hit = new HitData( Mech.LOC_LLEG ); - } - else { - hit = new HitData( Mech.LOC_RLEG ); - } - } - - // Mine Launchers automatically hit the - // CT of a Mech or the front of a Tank. - if ( wtype.getInternalName() - .equals(BattleArmor.MINE_LAUNCHER) ) { - if ( target instanceof Mech ) { - hit = new HitData( Mech.LOC_CT ); - } - else { // te instanceof Tank - hit = new HitData( Tank.LOC_FRONT ); - } - } - - // Each hit in the salvo get's its own hit location. - if (!bSalvo) { - r = new Report(3405); - r.subject = subjectId; - r.add(toHit.getTableDesc()); - r.add(entityTarget.getLocationAbbr(hit)); - r.newlines = 0; - addReport(r); - if (hit.hitAimedLocation()) { - r = new Report(3410); - r.subject = subjectId; - r.newlines = 0; - addReport(r); - } - } - - // Special weapons do criticals instead of damage. - if ( nDamPerHit == WeaponType.DAMAGE_SPECIAL ) { - // Do criticals. - //String specialDamage = criticalEntity( entityTarget, hit.getLocation() ); - Vector specialDamageReport = criticalEntity( entityTarget, hit.getLocation() ); - - // Replace "no effect" results with 4 points of damage. - //if ( specialDamage.endsWith(" no effect.") ) { - if (((Report)specialDamageReport.lastElement()).messageId == 6005) { - int damage = 4; - if (ae instanceof BattleArmor) - damage += ((BattleArmor)ae).getVibroClawDamage(); - // ASSUMPTION: buildings CAN'T absorb *this* damage. - //specialDamage = damageEntity(entityTarget, hit, damage); - specialDamageReport = damageEntity(entityTarget, hit, damage, false, 0, false, false, throughFront); - } - else { - //add newline _before_ last report - try { - ((Report) specialDamageReport.elementAt(specialDamageReport.size() - 2)).newlines++; - } catch (ArrayIndexOutOfBoundsException aiobe) { - System.err.println("ERROR: no previous report when trying to add newline"); - } - } - - // Report the result - addReport( specialDamageReport); - } - else if(game.getOptions().booleanOption("maxtech_partial_cover") && - toHit.getHitTable() == ToHitData.HIT_PARTIAL_COVER && - entityTarget.removePartialCoverHits(hit.getLocation(), toHit.getCover(), toHit.getSideTable())) { - r = new Report(3460); - r.subject = entityTarget.getId(); - r.indent(2); - r.add(entityTarget.getDisplayName()); - r.add(entityTarget.getLocationAbbr(hit)); - r.newlines = 0; - addReport(r); - } - else { - // Resolve damage normally. - nDamage = nDamPerHit * Math.min(nCluster, hits); - - // A building may be damaged, even if the squad is not. - if ( bldgAbsorbs > 0 ) { - int toBldg = Math.min( bldgAbsorbs, nDamage ); - nDamage -= toBldg; - addNewLines(); - Report buildingReport = damageBuilding( bldg, toBldg ); - buildingReport.indent(2); - buildingReport.subject = subjectId; - addReport(buildingReport); - } - - // A building may absorb the entire shot. - if ( nDamage == 0 ) { - r = new Report(3415); - r.subject = subjectId; - r.indent(2); - r.addDesc(entityTarget); - r.newlines = 0; - addReport(r); - } else if (bFragmentation) { - // If it's a frag missile... - if (bGlancing) { - hit.makeGlancingBlow(); - } - addReport( - damageEntity(entityTarget, hit, nDamage, false, 1, false, false, throughFront)); - } else if (bFlechette) { - // If it's a frag missile... - if (bGlancing) { - hit.makeGlancingBlow(); - } - addReport( - damageEntity(entityTarget, hit, nDamage, false, 2, false, false, throughFront)); - } else if (bAcidHead) { - // If it's an acid-head warhead... - if (bGlancing) { - hit.makeGlancingBlow(); - } - addReport( - damageEntity(entityTarget, hit, nDamage, false, 3, false, false, throughFront) ); - } else if(bIncendiary && usesAmmo && atype.getAmmoType() == AmmoType.T_AC) { - //incendiary AC ammo - if (bGlancing) { - hit.makeGlancingBlow(); - } - addReport( - damageEntity(entityTarget, hit, nDamage, false, 4, false, false, throughFront)); - } else { - if (usesAmmo - && (atype.getAmmoType() == AmmoType.T_AC) - && (atype.getMunitionType() == AmmoType.M_ARMOR_PIERCING) - && !(entityTarget.getArmorType() == EquipmentType.T_ARMOR_HARDENED)) - hit.makeArmorPiercing(atype); - if (bGlancing) { - hit.makeGlancingBlow(); - } - if (bAntiTSM) { - entityTarget.hitThisRoundByAntiTSM = true; - } - addReport( - damageEntity(entityTarget, hit, nDamage, false, 0, false, false, throughFront)); - } - } - hits -= nCluster; - creditKill(entityTarget, ae); - } else { - System.err.println("Unable to resolve hit against "+target.getDisplayName()); - if(entityTarget == null) { - System.err.println(" entityTarget is null"); - } - hits = 0; //prevents server lock-up - } - } // Handle the next cluster. - - //deal with splash damage from Arrow IV homing - if(atype != null && atype.getMunitionType() == AmmoType.M_HOMING) { - artilleryDamageHex(target.getPosition(), wr.artyAttackerCoords, 5, atype, subjectId, ae, entityTarget, false, 0); - } - - addNewLines(); - - if (swarmMissilesNowLeft > 0 && entityTarget != null) { - Entity swarmTarget = Compute.getSwarmTarget(game, ae.getId(), entityTarget, wr.waa.getWeaponId()); - if (swarmTarget != null) { - //missiles keep swarming - r = new Report(3420); - r.subject = swarmTarget.getId(); - r.indent(); - r.add(swarmMissilesNowLeft); - addReport(r); - weapon.setUsedThisRound(false); - WeaponAttackAction newWaa = new WeaponAttackAction(ae.getId(), - swarmTarget.getTargetId(), wr.waa.getWeaponId()); - newWaa.setSwarmingMissiles(true); - newWaa.setOldTargetId(target.getTargetId()); - newWaa.setAmmoId(wr.waa.getAmmoId()); - WeaponResult newWr = preTreatWeaponAttack(newWaa); - resolveWeaponAttack(newWr, ae.getId(), false, swarmMissilesNowLeft); - } else { - //missiles can't find another target - r = new Report(3425); - r.subject = ae.getId(); - r.indent(); - addReport(r); - } - } - - return !bMissed; - } - - /** - * Handle all physical attacks for the round - */ - private void resolvePhysicalAttacks() { - //Physical phase header - addReport(new Report(4000, Report.PUBLIC)); - - // add any pending charges - for (Enumeration i = game.getCharges(); i.hasMoreElements();) { - game.addAction((EntityAction)i.nextElement()); - } - game.resetCharges(); - - // remove any duplicate attack declarations - cleanupPhysicalAttacks(); - - // loop thru received attack actions - for (Enumeration i = game.getActions(); i.hasMoreElements();) { - Object o = i.nextElement(); - - // verify that the attacker is still active - AttackAction aa = (AttackAction)o; - if (!(game.getEntity(aa.getEntityId()).isActive()) - && !(o instanceof DfaAttackAction)) { - continue; - } - AbstractAttackAction aaa = (AbstractAttackAction)o; - // do searchlights immediately - if (aaa instanceof SearchlightAttackAction) { - SearchlightAttackAction saa = (SearchlightAttackAction)aaa; - addReport( - saa.resolveAction(game)); - } else { - physicalResults.addElement(preTreatPhysicalAttack(aaa)); - } - } - int cen = Entity.NONE; - for (Enumeration i = physicalResults.elements(); i.hasMoreElements();) { - PhysicalResult pr = (PhysicalResult)i.nextElement(); - resolvePhysicalAttack(pr, cen); - cen = pr.aaa.getEntityId(); - } - physicalResults.removeAllElements(); - } - - /** - * Cleans up the attack declarations for the physical phase by removing - * all attacks past the first for any one mech. Also clears out attacks - * by dead or disabled mechs. - */ - private void cleanupPhysicalAttacks() { - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - Entity entity = (Entity)i.nextElement(); - removeDuplicateAttacks(entity.getId()); - } - removeDeadAttacks(); - } - - /** - * Removes any actions in the attack queue beyond the first by the - * specified entity. - */ - private void removeDuplicateAttacks(int entityId) { - boolean attacked = false; - Vector toKeep = new Vector(/*game.actionsSize()*/); - - for (Enumeration i = game.getActions(); i.hasMoreElements();) { - EntityAction action = (EntityAction)i.nextElement(); - if (action.getEntityId() != entityId) { - toKeep.addElement(action); - } else if (!attacked) { - toKeep.addElement(action); - if(!(action instanceof SearchlightAttackAction)) { - attacked = true; - } - } else { - System.err.println("server: removing duplicate phys attack for id#" + entityId); - System.err.println(" action was "+ action.toString()); - } - } - - // reset actions and re-add valid elements - game.resetActions(); - for (Enumeration i = toKeep.elements(); i.hasMoreElements();) { - game.addAction((EntityAction)i.nextElement()); - } - } - - /** - * Removes all attacks by any dead entities. It does this by going through - * all the attacks and only keeping ones from active entities. DFAs are - * kept even if the pilot is unconscious, so that he can fail. - */ - private void removeDeadAttacks() { - Vector toKeep = new Vector(game.actionsSize()); - - for (Enumeration i = game.getActions(); i.hasMoreElements();) { - EntityAction action = (EntityAction)i.nextElement(); - Entity entity = game.getEntity(action.getEntityId()); - if (entity != null && !entity.isDestroyed() - && (entity.isActive() || action instanceof DfaAttackAction)) { - toKeep.addElement(action); - } - } - - // reset actions and re-add valid elements - game.resetActions(); - for (Enumeration i = toKeep.elements(); i.hasMoreElements();) { - game.addAction((EntityAction)i.nextElement()); - } - } - - /** - * Handle a punch attack - */ - private void resolvePunchAttack(PhysicalResult pr, int lastEntityId) { - final PunchAttackAction paa = (PunchAttackAction)pr.aaa; - final Entity ae = game.getEntity(paa.getEntityId()); - final Targetable target = game.getTarget(paa.getTargetType(), paa.getTargetId()); - Entity te = null; - if (target.getTargetType() == Targetable.TYPE_ENTITY) { - te = (Entity)target; - } - boolean throughFront = true; - if (te!=null) { - throughFront = Compute.isThroughFrontHex(game, paa.getEntityId(), te); - } - final String armName = paa.getArm() == PunchAttackAction.LEFT - ? "Left Arm" : "Right Arm"; - // get damage, ToHitData and roll from the PhysicalResult - int damage = paa.getArm() == PunchAttackAction.LEFT - ? pr.damage : pr.damageRight; - final ToHitData toHit = paa.getArm() == PunchAttackAction.LEFT - ? pr.toHit : pr.toHitRight; - int roll = paa.getArm() == PunchAttackAction.LEFT - ? pr.roll : pr.rollRight; - final boolean targetInBuilding = Compute.isInBuilding( game, te ); - final boolean glancing = (game.getOptions().booleanOption("maxtech_glancing_blows") && (roll == toHit.getValue())); - Report r; - - // Which building takes the damage? - Building bldg = game.getBoard().getBuildingAt( target.getPosition() ); - - if (lastEntityId != paa.getEntityId()) { - //report who is making the attacks - r = new Report(4005); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - } - - r = new Report(4010); - r.subject = ae.getId(); - r.indent(); - r.add(armName); - r.add(target.getDisplayName()); - r.newlines = 0; - addReport(r); - - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - r = new Report(4015); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - return; - } else if (toHit.getValue() == ToHitData.AUTOMATIC_SUCCESS) { - r = new Report(4020); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - r.newlines = 0; - addReport(r); - roll = Integer.MAX_VALUE; - } else { - r = new Report(4025); - r.subject = ae.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - if (glancing) { - r = new Report(4030); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - } - } - - // do we hit? - if (roll < toHit.getValue()) { - //nope - r = new Report(4035); - r.subject = ae.getId(); - addReport(r); - - // If the target is in a building, the building absorbs the damage. - if ( targetInBuilding && bldg != null ) { - - // Only report if damage was done to the building. - if ( damage > 0 ) { - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - } - - } - return; - } - - // Targeting a building. - if ( target.getTargetType() == Targetable.TYPE_BUILDING ) { - - // The building takes the full brunt of the attack. - r = new Report(4040); - r.subject = ae.getId(); - addReport(r); - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - - // Damage any infantry in the hex. - this.damageInfantryIn( bldg, damage ); - - // And we're done! - return; - } - - HitData hit = te.rollHitLocation(toHit.getHitTable(), toHit.getSideTable()); - r = new Report(4045); - r.subject = ae.getId(); - r.add(toHit.getTableDesc()); - r.add(te.getLocationAbbr(hit)); - r.newlines = 0; - addReport(r); - - // The building shields all units from a certain amount of damage. - // The amount is based upon the building's CF at the phase's start. - if ( targetInBuilding && bldg != null ) { - int bldgAbsorbs = (int) Math.ceil( bldg.getPhaseCF() / 10.0 ); - int toBldg = Math.min( bldgAbsorbs, damage ); - damage -= toBldg; - addNewLines(); - Report buildingReport = damageBuilding( bldg, toBldg ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - } - - // A building may absorb the entire shot. - if ( damage == 0 ) { - r = new Report(4050); - r.subject = ae.getId(); - r.add(te.getShortName()); - r.add(te.getOwner().getName()); - r.newlines = 0; - addReport(r); - } else { - if (glancing) { - damage = (int)Math.floor(damage/2.0); - } - addReport(damageEntity(te, hit, damage, false, 0, false, false, throughFront)); - } - - addNewLines(); - } - - /** - * Handle a kick attack - */ - private void resolveKickAttack(PhysicalResult pr, int lastEntityId) { - KickAttackAction kaa = (KickAttackAction)pr.aaa; - final Entity ae = game.getEntity(kaa.getEntityId()); - final Targetable target = game.getTarget(kaa.getTargetType(), kaa.getTargetId()); - Entity te = null; - if (target.getTargetType() == Targetable.TYPE_ENTITY) { - te = (Entity)target; - } - boolean throughFront = true; - if (te!=null) { - throughFront = Compute.isThroughFrontHex(game, kaa.getEntityId(), te); - } - String legName = ( (kaa.getLeg() == KickAttackAction.LEFT) || - (kaa.getLeg() == KickAttackAction.LEFTMULE) ) - ? "Left " - : "Right "; - if (game.getOptions().booleanOption("maxtech_mulekicks")) { - if ( (kaa.getLeg() == KickAttackAction.LEFTMULE) || - (kaa.getLeg() == KickAttackAction.RIGHTMULE) ) { - legName.concat(" rear "); - } else { - legName.concat(" front "); - } - } - legName.concat("leg"); - Report r; - - // get damage, ToHitData and roll from the PhysicalResult - int damage = pr.damage; - final ToHitData toHit = pr.toHit; - int roll = pr.roll; - final boolean targetInBuilding = Compute.isInBuilding( game, te ); - final boolean glancing = (game.getOptions().booleanOption("maxtech_glancing_blows") && (roll == toHit.getValue())); - - // Which building takes the damage? - Building bldg = game.getBoard().getBuildingAt( target.getPosition() ); - - if (lastEntityId != ae.getId()) { - //who is making the attacks - r = new Report(4005); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - } - - r = new Report(4055); - r.subject = ae.getId(); - r.indent(); - r.add(legName); - r.add(target.getDisplayName()); - r.newlines = 0; - addReport(r); - - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - r = new Report(4060); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - game.addPSR(new PilotingRollData(ae.getId(), 0, "missed a kick")); - return; - } else if (toHit.getValue() == ToHitData.AUTOMATIC_SUCCESS) { - r = new Report(4065); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - r.newlines = 0; - addReport(r); - roll = Integer.MAX_VALUE; - } else { - r = new Report(4025); - r.subject = ae.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - if (glancing) { - r = new Report(4030); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - } - } - - // do we hit? - if (roll < toHit.getValue()) { - // miss - r = new Report(4035); - r.subject = ae.getId(); - addReport(r); - game.addPSR(new PilotingRollData(ae.getId(), 0, "missed a kick")); - - // If the target is in a building, the building absorbs the damage. - if ( targetInBuilding && bldg != null ) { - - // Only report if damage was done to the building. - if ( damage > 0 ) { - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - } - - } - return; - } - - // Targeting a building. - if ( target.getTargetType() == Targetable.TYPE_BUILDING ) { - - // The building takes the full brunt of the attack. - r = new Report(4040); - r.subject = ae.getId(); - addReport(r); - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - - // Damage any infantry in the hex. - this.damageInfantryIn( bldg, damage ); - - // And we're done! - return; - } - - HitData hit = te.rollHitLocation(toHit.getHitTable(), toHit.getSideTable()); - r = new Report(4045); - r.subject = ae.getId(); - r.add(toHit.getTableDesc()); - r.add(te.getLocationAbbr(hit)); - r.newlines = 0; - addReport(r); - - // The building shields all units from a certain amount of damage. - // The amount is based upon the building's CF at the phase's start. - if ( targetInBuilding && bldg != null ) { - int bldgAbsorbs = (int) Math.ceil( bldg.getPhaseCF() / 10.0 ); - int toBldg = Math.min( bldgAbsorbs, damage ); - damage -= toBldg; - addNewLines(); - Report buildingReport = damageBuilding( bldg, toBldg ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - } - - // A building may absorb the entire shot. - if ( damage == 0 ) { - r = new Report(4050); - r.subject = ae.getId(); - r.add(te.getShortName()); - r.add(te.getOwner().getName()); - r.newlines = 0; - addReport(r); - } else { - if (glancing) { - damage = (int)Math.floor(damage/2.0); - } - addReport(damageEntity(te, hit, damage, false, 0, false, false, throughFront)); - } - - if (te.getMovementMode() == IEntityMovementMode.BIPED || te.getMovementMode() == IEntityMovementMode.QUAD) { - PilotingRollData kickPRD = new PilotingRollData(te.getId(), getKickPushPSRMod(ae, te, 0), "was kicked"); - kickPRD.setCumulative(false); // see Bug# 811987 for more info - game.addPSR(kickPRD); - } - - addNewLines(); - } - - /** - * Handle a Protomech physicalattack - */ - - private void resolveProtoAttack(PhysicalResult pr, int lastEntityId) { - final ProtomechPhysicalAttackAction ppaa = (ProtomechPhysicalAttackAction)pr.aaa; - final Entity ae = game.getEntity(ppaa.getEntityId()); - // get damage, ToHitData and roll from the PhysicalResult - int damage = pr.damage; - final ToHitData toHit = pr.toHit; - int roll = pr.roll; - final Targetable target = game.getTarget(ppaa.getTargetType(), ppaa.getTargetId()); - Entity te = null; - if (target.getTargetType() == Targetable.TYPE_ENTITY) { - te = (Entity)target; - } - boolean throughFront = true; - if (te!=null) { - throughFront = Compute.isThroughFrontHex(game, ppaa.getEntityId(), te); - } - final boolean targetInBuilding = Compute.isInBuilding( game, te ); - final boolean glancing = (game.getOptions().booleanOption("maxtech_glancing_blows") && (roll == toHit.getValue())); - Report r; - - // Which building takes the damage? - Building bldg = game.getBoard().getBuildingAt( target.getPosition() ); - - if (lastEntityId != ae.getId()) { - //who is making the attacks - r = new Report(4005); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - } - - r = new Report(4070); - r.subject = ae.getId(); - r.indent(); - r.add(target.getDisplayName()); - r.newlines = 0; - addReport(r); - - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - r = new Report(4075); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - return; - } else if (toHit.getValue() == ToHitData.AUTOMATIC_SUCCESS) { - r = new Report(4080); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - r.newlines = 0; - addReport(r); - roll = Integer.MAX_VALUE; - } else { - // report the roll - r = new Report(4025); - r.subject = ae.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - if (glancing) { - r = new Report(4030); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - } - } - - // do we hit? - if (roll < toHit.getValue()) { - // miss - r = new Report(4035); - r.subject = ae.getId(); - addReport(r); - - // If the target is in a building, the building absorbs the damage. - if ( targetInBuilding && bldg != null ) { - - // Only report if damage was done to the building. - if ( damage > 0 ) { - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - } - - } - return; - } - - // Targeting a building. - if ( target.getTargetType() == Targetable.TYPE_BUILDING ) { - - // The building takes the full brunt of the attack. - r = new Report(4040); - r.subject = ae.getId(); - addReport(r); - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - - // Damage any infantry in the hex. - this.damageInfantryIn( bldg, damage ); - - // And we're done! - return; - } - - HitData hit = te.rollHitLocation(toHit.getHitTable(), toHit.getSideTable()); - r = new Report(4045); - r.subject = ae.getId(); - r.add(toHit.getTableDesc()); - r.add(te.getLocationAbbr(hit)); - r.newlines = 0; - addReport(r); - - // The building shields all units from a certain amount of damage. - // The amount is based upon the building's CF at the phase's start. - if ( targetInBuilding && bldg != null ) { - int bldgAbsorbs = (int) Math.ceil( bldg.getPhaseCF() / 10.0 ); - int toBldg = Math.min( bldgAbsorbs, damage ); - damage -= toBldg; - addNewLines(); - Report buildingReport = damageBuilding( bldg, toBldg ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - } - - // A building may absorb the entire shot. - if ( damage == 0 ) { - r = new Report(4050); - r.subject = ae.getId(); - r.add(te.getShortName()); - r.add(te.getOwner().getName()); - r.newlines = 0; - addReport(r); - } else { - if (glancing) { - damage = (int)Math.floor(damage/2.0); - } - addReport(damageEntity(te, hit, damage)); - } - - addNewLines(); - } - - - /** - * Handle a brush off attack - */ - private void resolveBrushOffAttack( PhysicalResult pr, - int lastEntityId ) { - final BrushOffAttackAction baa = (BrushOffAttackAction)pr.aaa; - final Entity ae = game.getEntity(baa.getEntityId()); - // PLEASE NOTE: buildings are *never* the target - // of a "brush off", but iNarc pods **are**. - Targetable target = game.getTarget( baa.getTargetType(), - baa.getTargetId() ); - Entity te = null; - final String armName = baa.getArm() == BrushOffAttackAction.LEFT - ? "Left Arm" : "Right Arm"; - Report r; - - if (target.getTargetType() == Targetable.TYPE_ENTITY) { - te = game.getEntity(baa.getTargetId()); - } - - // get damage, ToHitData and roll from the PhysicalResult - // ASSUMPTION: buildings can't absorb *this* damage. - int damage = baa.getArm() == BrushOffAttackAction.LEFT - ? pr.damage : pr.damageRight; - final ToHitData toHit = baa.getArm() == BrushOffAttackAction.LEFT - ? pr.toHit : pr.toHitRight; - int roll = baa.getArm() == BrushOffAttackAction.LEFT - ? pr.roll : pr.rollRight; - - if (lastEntityId != baa.getEntityId()) { - //who is making the attacks - r = new Report(4005); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - } - - r = new Report(4085); - r.subject = ae.getId(); - r.indent(); - r.add(target.getDisplayName()); - r.newlines = 0; - addReport(r); - - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - r = new Report(4090); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - return; - } - - // report the roll - r = new Report(4025); - r.subject = ae.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - - // do we hit? - if (roll < toHit.getValue()) { - //miss - r = new Report(4035); - r.subject = ae.getId(); - addReport(r); - - // Missed Brush Off attacks cause punch damage to the attacker. - toHit.setHitTable( ToHitData.HIT_PUNCH ); - toHit.setSideTable( ToHitData.SIDE_FRONT ); - HitData hit = ae.rollHitLocation( toHit.getHitTable(), - toHit.getSideTable() ); - r = new Report(4095); - r.subject = ae.getId(); - r.addDesc(ae); - r.add(ae.getLocationAbbr(hit)); - r.newlines = 0; - addReport(r); - addReport( - damageEntity(ae, hit, damage)); - addNewLines(); - return; - } - - // Different target types get different handling. - switch ( target.getTargetType() ) { - case Targetable.TYPE_ENTITY: - // Handle Entity targets. - HitData hit = te.rollHitLocation( toHit.getHitTable(), - toHit.getSideTable() ); - r = new Report(4045); - r.subject = ae.getId(); - r.add(toHit.getTableDesc()); - r.add(te.getLocationAbbr(hit)); - r.newlines = 0; - addReport(r); - addReport( - damageEntity(te, hit, damage)); - addNewLines(); - - // Dislodge the swarming infantry. - ae.setSwarmAttackerId( Entity.NONE ); - te.setSwarmTargetId( Entity.NONE ); - r = new Report(4100); - r.subject = ae.getId(); - r.add(te.getDisplayName()); - addReport(r); - break; - case Targetable.TYPE_INARC_POD: - // Handle iNarc pod targets. - // TODO : check the return code and handle false appropriately. - ae.removeINarcPod( (INarcPod) target ); -// // TODO : confirm that we don't need to update the attacker. //killme -// entityUpdate( ae.getId() ); // killme - r = new Report(4105); - r.subject = ae.getId(); - r.add(target.getDisplayName()); - addReport(r); - break; - // TODO : add a default: case and handle it appropriately. - } - } - - /** - * Handle a thrash attack - */ - private void resolveThrashAttack( PhysicalResult pr, - int lastEntityId ) { - final ThrashAttackAction taa = (ThrashAttackAction)pr.aaa; - final Entity ae = game.getEntity(taa.getEntityId()); - - // get damage, ToHitData and roll from the PhysicalResult - int hits = pr.damage; - final ToHitData toHit = pr.toHit; - int roll = pr.roll; - final boolean glancing = (game.getOptions().booleanOption("maxtech_glancing_blows") && (roll == toHit.getValue())); - - // PLEASE NOTE: buildings are *never* the target of a "thrash". - final Entity te = game.getEntity(taa.getTargetId()); - Report r; - - if (lastEntityId != taa.getEntityId()) { - //who is making the attacks - r = new Report(4005); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - } - - r = new Report(4110); - r.subject = ae.getId(); - r.indent(); - r.addDesc(te); - r.newlines = 0; - addReport(r); - - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - r = new Report(4115); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - return; - } - - // Thrash attack may hit automatically - if ( toHit.getValue() == ToHitData.AUTOMATIC_SUCCESS ) { - r = new Report(4120); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - } else { - // report the roll - r = new Report(4025); - r.subject = ae.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - - // do we hit? - if (roll < toHit.getValue()) { - //miss - r = new Report(4035); - r.subject = ae.getId(); - addReport(r); - return; - } - r = new Report(4125); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - } - - // Standard damage loop in 5 point clusters. - if (glancing) { - hits = (int)Math.floor(hits/2.0); - } - - r = new Report(4130); - r.subject = ae.getId(); - r.add(hits); - r.newlines = 0; - addReport(r); - if (glancing) { - r = new Report(4030); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - } - while ( hits > 0 ) { - int damage = Math.min(5, hits); - hits -= damage; - HitData hit = te.rollHitLocation( toHit.getHitTable(), - toHit.getSideTable() ); - r = new Report(4135); - r.subject = ae.getId(); - r.add(te.getLocationAbbr(hit)); - r.newlines = 0; - addReport(r); - addReport( - damageEntity(te, hit, damage)); - } - - addNewLines(); - - // Thrash attacks cause PSRs. Failed PSRs cause falling damage. - // This fall damage applies even though the Thrashing Mek is prone. - PilotingRollData rollData = ae.getBasePilotingRoll(); - ae.addPilotingModifierForTerrain(rollData); - rollData.addModifier( 0, "thrashing at infantry" ); - r = new Report(4140); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - final int diceRoll = Compute.d6(2); - r = new Report(2190); - r.subject = ae.getId(); - r.addDesc(ae); - r.add(rollData.getValueAsString()); - r.add(rollData.getDesc()); - r.add(diceRoll); - if (diceRoll < rollData.getValue()) { - r.choose(false); - addReport(r); - doEntityFall( ae, rollData ); - } else { - r.choose(true); - addReport(r); - } - - } - - /** - * Handle a club attack - */ - private void resolveClubAttack(PhysicalResult pr, int lastEntityId) { - final ClubAttackAction caa = (ClubAttackAction)pr.aaa; - final Entity ae = game.getEntity(caa.getEntityId()); - // get damage, ToHitData and roll from the PhysicalResult - int damage = pr.damage; - final ToHitData toHit = pr.toHit; - int roll = pr.roll; - final Targetable target = game.getTarget(caa.getTargetType(), caa.getTargetId()); - Entity te = null; - if (target.getTargetType() == Targetable.TYPE_ENTITY) { - te = (Entity)target; - } - boolean throughFront = true; - if (te!=null) { - throughFront = Compute.isThroughFrontHex(game, caa.getEntityId(), te); - } - final boolean targetInBuilding = Compute.isInBuilding( game, te ); - final boolean glancing = (game.getOptions().booleanOption("maxtech_glancing_blows") && (roll == toHit.getValue())); - Report r; - - // Which building takes the damage? - Building bldg = game.getBoard().getBuildingAt( target.getPosition() ); - - // restore club attack - caa.getClub().restore(); - - if (lastEntityId != caa.getEntityId()) { - //who is making the attacks - r = new Report(4005); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - } - - r = new Report(4145); - r.subject = ae.getId(); - r.indent(); - r.add(caa.getClub().getName()); - r.add(target.getDisplayName()); - r.newlines = 0; - addReport(r); - - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - r = new Report(4075); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - if (((MiscType)(caa.getClub().getType())).hasSubType(MiscType.S_MACE_THB)) { - game.addPSR(new PilotingRollData(ae.getId(), 0, "missed a mace attack")); - } - if (((MiscType)(caa.getClub().getType())).hasSubType(MiscType.S_MACE)) { - game.addPSR(new PilotingRollData(ae.getId(), 2, "missed a mace attack")); - } - return; - } else if (toHit.getValue() == ToHitData.AUTOMATIC_SUCCESS) { - r = new Report(4080); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - r.newlines = 0; - addReport(r); - roll = Integer.MAX_VALUE; - } else { - // report the roll - r = new Report(4025); - r.subject = ae.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - if (glancing) { - r = new Report(4030); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - } - } - - // do we hit? - if (roll < toHit.getValue()) { - //miss - r = new Report(4035); - r.subject = ae.getId(); - addReport(r); - if (((MiscType)(caa.getClub().getType())).hasSubType(MiscType.S_MACE_THB)) { - game.addPSR(new PilotingRollData(ae.getId(), 0, "missed a mace attack")); - } - if (((MiscType)(caa.getClub().getType())).hasSubType(MiscType.S_MACE)) { - game.addPSR(new PilotingRollData(ae.getId(), 2, "missed a mace attack")); - } - - // If the target is in a building, the building absorbs the damage. - if ( targetInBuilding && bldg != null ) { - - // Only report if damage was done to the building. - if ( damage > 0 ) { - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - } - - } - return; - } - - // Targeting a building. - if ( target.getTargetType() == Targetable.TYPE_BUILDING ) { - - // The building takes the full brunt of the attack. - r = new Report(4040); - r.subject = ae.getId(); - addReport(r); - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - - // Damage any infantry in the hex. - this.damageInfantryIn( bldg, damage ); - - // And we're done! - return; - } - - HitData hit = te.rollHitLocation(toHit.getHitTable(), toHit.getSideTable()); - r = new Report(4045); - r.subject = ae.getId(); - r.add(toHit.getTableDesc()); - r.add(te.getLocationAbbr(hit)); - r.newlines = 0; - addReport(r); - - // The building shields all units from a certain amount of damage. - // The amount is based upon the building's CF at the phase's start. - if ( targetInBuilding && bldg != null ) { - int bldgAbsorbs = (int) Math.ceil( bldg.getPhaseCF() / 10.0 ); - int toBldg = Math.min( bldgAbsorbs, damage ); - damage -= toBldg; - addNewLines(); - Report buildingReport = damageBuilding( bldg, toBldg ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - } - - // A building may absorb the entire shot. - if ( damage == 0 ) { - r = new Report(4050); - r.subject = ae.getId(); - r.add(te.getShortName()); - r.add(te.getOwner().getName()); - r.newlines = 0; - addReport(r); - } else { - if (glancing) { - damage = (int)Math.floor(damage/2.0); - } - addReport(damageEntity(te, hit, damage, false, 0, false, false, throughFront)); - } - - addNewLines(); - - if (((MiscType)caa.getClub().getType()).hasSubType(MiscType.S_TREE_CLUB)) { - //the club breaks - r = new Report(4150); - r.subject = ae.getId(); - r.add(caa.getClub().getName()); - addReport(r); - ae.removeMisc(caa.getClub().getName()); - } - } - - /** - * Handle a push attack - */ - private void resolvePushAttack(PhysicalResult pr, int lastEntityId) { - final PushAttackAction paa = (PushAttackAction)pr.aaa; - final Entity ae = game.getEntity(paa.getEntityId()); - // PLEASE NOTE: buildings are *never* the target of a "push". - final Entity te = game.getEntity(paa.getTargetId()); - // get roll and ToHitData from the PhysicalResult - int roll = pr.roll; - final ToHitData toHit = pr.toHit; - Report r; - - // was this push resolved earlier? - if (pr.pushBackResolved) { - return; - } - - if (lastEntityId != paa.getEntityId()) { - //who is making the attack - r = new Report(4005); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - } - - r = new Report(4155); - r.subject = ae.getId(); - r.indent(); - r.addDesc(te); - r.newlines = 0; - addReport(r); - - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - r = new Report(4160); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - return; - } - - // report the roll - r = new Report(4025); - r.subject = ae.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - - // check if our target has a push against us, too, and get it - PhysicalResult targetPushResult = null; - for (Enumeration i = physicalResults.elements(); i.hasMoreElements();) { - PhysicalResult tpr = (PhysicalResult)i.nextElement(); - if (tpr.aaa.getEntityId() == te.getId() && - tpr.aaa instanceof PushAttackAction && - tpr.aaa.getTargetId() == ae.getId() ) { - targetPushResult = tpr; - } - } - // if our target has a push against us, we need to resolve both now - if (targetPushResult != null) { - // do both hit? - if (targetPushResult.roll >= targetPushResult.toHit.getValue() && - roll >= toHit.getValue()) { - r = new Report(4165); - r.subject = ae.getId(); - r.addDesc(te); - r.addDesc(te); - r.addDesc(ae); - r.add(toHit.getValue()); - r.add(roll); - r.addDesc(ae); - addReport(r); - PilotingRollData targetPushPRD = new PilotingRollData(te.getId(), getKickPushPSRMod(ae, te, 0), "was pushed"); - targetPushPRD.setCumulative(false); // see Bug# 811987 for more info - PilotingRollData pushPRD = new PilotingRollData(ae.getId(), getKickPushPSRMod(ae, te, 0), "was pushed"); - pushPRD.setCumulative(false); // see Bug# 811987 for more info - game.addPSR(pushPRD); - game.addPSR(targetPushPRD); - targetPushResult.pushBackResolved = true; - return; - } - } - - // do we hit? - if (roll < toHit.getValue()) { - //miss - r = new Report(4035); - r.subject = ae.getId(); - addReport(r); - return; - } - - // we hit... - int direction = ae.getFacing(); - - Coords src = te.getPosition(); - Coords dest = src.translated(direction); - - PilotingRollData pushPRD = new PilotingRollData(te.getId(), getKickPushPSRMod(ae, te, 0), "was pushed"); - pushPRD.setCumulative(false); // see Bug# 811987 for more info - - if (Compute.isValidDisplacement(game, te.getId(), te.getPosition(), direction)) { - r = new Report(4170); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - if (game.getBoard().contains(dest)) { - r = new Report(4175); - r.subject = ae.getId(); - r.add(dest.getBoardNum(), true); - addReport(r); - } else { - //uh-oh, pushed off board - r = new Report(4180); - r.subject = ae.getId(); - addReport(r); - } - - doEntityDisplacement(te, src, dest, pushPRD); - - // if push actually moved the target, attacker follows thru - if (!te.getPosition().equals(src)) { - ae.setPosition(src); - } - } else { - //targe imovable - r = new Report(4185); - r.subject = ae.getId(); - addReport(r); - game.addPSR(pushPRD); - } - - addNewLines(); - } - - /** - * Handle a charge attack - */ - private void resolveChargeAttack(PhysicalResult pr, int lastEntityId) { - final ChargeAttackAction caa = (ChargeAttackAction)pr.aaa; - final Entity ae = game.getEntity(caa.getEntityId()); - final Targetable target = game.getTarget(caa.getTargetType(), caa.getTargetId()); - // get damage, ToHitData and roll from the PhysicalResult - int damage = pr.damage; - final ToHitData toHit = pr.toHit; - int roll = pr.roll; - Entity te = null; - if (target != null && target.getTargetType() == Targetable.TYPE_ENTITY) { - te = (Entity)target; - } - boolean throughFront = true; - if (te!=null) { - throughFront = Compute.isThroughFrontHex(game, caa.getEntityId(), te); - } - final boolean glancing = (game.getOptions().booleanOption("maxtech_glancing_blows") && (roll == toHit.getValue())); - Report r; - - // Which building takes the damage? - Building bldg = game.getBoard().getBuildingAt( caa.getTargetPos() ); - - // is the attacker dead? because that sure messes up the calculations - if (ae == null) { - return; - } - - final int direction = ae.getFacing(); - - // entity isn't charging any more - ae.setDisplacementAttack(null); - - if (lastEntityId != caa.getEntityId()) { - //who is making the attack - r = new Report(4005); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - } - - // should we even bother? - if (target == null || (target.getTargetType() == Targetable.TYPE_ENTITY - && (te.isDestroyed() || te.isDoomed() || te.crew.isDead()))) { - r = new Report(4190); - r.subject = ae.getId(); - r.indent(); - addReport(r); - // doEntityDisplacement(ae, ae.getPosition(), caa.getTargetPos(), null); - // Randall said that if a charge fails because of target destruction, - // the attacker stays in the hex he was in at the end of the movement phase - // See Bug 912094 - return; - } - - // attacker fell down? - if (ae.isProne()) { - r = new Report(4195); - r.subject = ae.getId(); - r.indent(); - addReport(r); - return; - } - - // attacker immobile? - if (ae.isImmobile()) { - r = new Report(4200); - r.subject = ae.getId(); - r.indent(); - addReport(r); - return; - } - - if (te.isProne()) { - r = new Report(4205); - r.subject = ae.getId(); - r.indent(); - addReport(r); - return; - } - - r = new Report(4210); - r.subject = ae.getId(); - r.indent(); - r.add(target.getDisplayName()); - r.newlines = 0; - addReport(r); - - // target still in the same position? - if (!target.getPosition().equals(caa.getTargetPos())) { - r = new Report(4215); - r.subject = ae.getId(); - addReport(r); - doEntityDisplacement(ae, ae.getPosition(), caa.getTargetPos(), null); - return; - } - - // if the attacker's prone, fudge the roll - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - roll = -12; - r = new Report(4220); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - } else if (toHit.getValue() == ToHitData.AUTOMATIC_SUCCESS) { - roll = Integer.MAX_VALUE; - r = new Report(4225); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - } else { - // report the roll - r = new Report(4025); - r.subject = ae.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - if (glancing) { - r = new Report(4030); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - } - } - - // do we hit? - if (roll < toHit.getValue()) { - Coords src = ae.getPosition(); - Coords dest = Compute.getMissedChargeDisplacement(game, ae.getId(), src, direction); - - // TODO: handle movement into/out of/through a building. Do it here? - - //miss - r = new Report(4035); - r.subject = ae.getId(); - addReport(r); - // move attacker to side hex - doEntityDisplacement(ae, src, dest, null); - } - - // Targeting a building. - else if ( target.getTargetType() == Targetable.TYPE_BUILDING ) { - - // The building takes the full brunt of the attack. - r = new Report(4040); - r.subject = ae.getId(); - addReport(r); - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - - // Damage any infantry in the hex. - this.damageInfantryIn( bldg, damage ); - - // Apply damage to the attacker. - int toAttacker = ChargeAttackAction.getDamageTakenBy( ae, bldg ); - HitData hit = ae.rollHitLocation( ToHitData.HIT_NORMAL, - ae.sideTable(target.getPosition()) - ); - addReport( - damageEntity( ae, hit, toAttacker, false, 0, false, false, throughFront)); - addNewLines(); - entityUpdate( ae.getId() ); - - // TODO: Does the attacker enter the building? - // TODO: What if the building collapses? - } - else { - // Resolve the damage. - resolveChargeDamage( ae, te, toHit, direction, glancing, throughFront ); - } - return; - } - - /** - * Handle a charge's damage - */ - private void resolveChargeDamage(Entity ae, Entity te, ToHitData toHit, int direction) { - resolveChargeDamage (ae, te, toHit, direction, false, true); - } - - private void resolveChargeDamage(Entity ae, Entity te, ToHitData toHit, int direction, boolean glancing, boolean throughFront) { - - // we hit... - int damage = ChargeAttackAction.getDamageFor(ae); - int damageTaken = ChargeAttackAction.getDamageTakenBy(ae, te, game.getOptions().booleanOption("maxtech_charge_damage")); - PilotingRollData chargePSR = null; - if (glancing) { - // Glancing Blow rule doesn't state whether damage to attacker on charge - // or DFA is halved as well, assume yes. TODO: Check with PM - damage = (int)Math.floor(damage/2.0); - damageTaken = (int)Math.floor(damageTaken/2.0); - } - // Is the target inside a building? - final boolean targetInBuilding = Compute.isInBuilding( game, te ); - - // Which building takes the damage? - Building bldg = game.getBoard().getBuildingAt( te.getPosition() ); - - // The building shields all units from a certain amount of damage. - // The amount is based upon the building's CF at the phase's start. - int bldgAbsorbs = 0; - if ( targetInBuilding && bldg != null ) { - bldgAbsorbs = (int) Math.ceil( bldg.getPhaseCF() / 10.0 ); - } - - // If we're upright, we may fall down. - if ( !ae.isProne() ) { - chargePSR = new PilotingRollData(ae.getId(), 2, "charging"); - } - - Report r; - - - r = new Report(4230); - r.subject = ae.getId(); - r.add(damage); - r.add(toHit.getTableDesc()); - r.newlines = 0; - addReport(r); - while (damage > 0) { - int cluster = Math.min(5, damage); - damage -= cluster; - if ( bldgAbsorbs > 0 ) { - int toBldg = Math.min( bldgAbsorbs, cluster ); - cluster -= toBldg; - addNewLines(); - Report buildingReport = damageBuilding( bldg, toBldg ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - } - - // A building may absorb the entire shot. - if ( cluster == 0 ) { - r = new Report(4235); - r.subject = ae.getId(); - r.addDesc(te); - r.newlines = 0; - addReport(r); - } else { - HitData hit = te.rollHitLocation(toHit.getHitTable(), toHit.getSideTable()); - addReport( - damageEntity(te, hit, cluster, false, 0, false, false, throughFront)); - } - } - - //damage to attacker - r = new Report(4240); - r.subject = ae.getId(); - r.add(damageTaken); - r.newlines = 0; - addReport(r); - while (damageTaken > 0) { - int cluster = Math.min(5, damageTaken); - HitData hit = ae.rollHitLocation(ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT); - addReport( - damageEntity(ae, hit, cluster)); - damageTaken -= cluster; - } - // move attacker and target, if possible - Coords src = te.getPosition(); - Coords dest = src.translated(direction); - - if (Compute.isValidDisplacement(game, te.getId(), te.getPosition(), direction)) { - addNewLines(); - doEntityDisplacement(te, src, dest, new PilotingRollData(te.getId(), 2, "was charged")); - doEntityDisplacement(ae, ae.getPosition(), src, chargePSR); - } - - addNewLines(); - - } // End private void resolveChargeDamage( Entity, Entity, ToHitData ) - - private void resolveLayExplosivesAttack(PhysicalResult pr, int lastEntityId) { - final LayExplosivesAttackAction laa = (LayExplosivesAttackAction)pr.aaa; - final Entity ae = game.getEntity(laa.getEntityId()); - final Targetable target = game.getTarget(laa.getTargetType(), laa.getTargetId()); - if(ae instanceof Infantry) { - Infantry inf = (Infantry) ae; - if(inf.turnsLayingExplosives < 0) { - inf.turnsLayingExplosives = 0; - Report r = new Report(4270); - r.subject = inf.getId(); - r.addDesc(inf); - addReport(r); - } else { - Building building = game.getBoard().getBuildingAt(ae.getPosition()); - if(building != null) { - building.addDemolitionCharge(ae.getOwner().getId(), pr.damage); - Report r = new Report(4275); - r.subject = inf.getId(); - r.addDesc(inf); - r.add(pr.damage); - addReport(r); - } - inf.turnsLayingExplosives = -1; - } - } - } - - /** - * Handle a death from above attack - */ - private void resolveDfaAttack(PhysicalResult pr, int lastEntityId) { - final DfaAttackAction daa = (DfaAttackAction)pr.aaa; - final Entity ae = game.getEntity(daa.getEntityId()); - final Targetable target = game.getTarget(daa.getTargetType(), daa.getTargetId()); - // get damage, ToHitData and roll from the PhysicalResult - int damage = pr.damage; - final ToHitData toHit = pr.toHit; - int roll = pr.roll; - Entity te = null; - if (target != null && target.getTargetType() == Targetable.TYPE_ENTITY) { - // Lets re-write around that horrible hack that was here before. - // So instead of asking if a specific location is wet and praying - // that it won't cause an NPE... - // We'll check 1) if the hex has water, and 2) if it's deep enough - // to cover the unit in question at its current elevation. - // It's especially important to make sure it's done this way, - // because some units (Sylph, submarines) can be at ANY elevation - // underwater, and VTOLs can be well above the surface. - te = (Entity)target; - IHex hex = game.getBoard().getHex(te.getPosition()); - if (hex.containsTerrain(Terrains.WATER)) { - if (te.absHeight() < hex.getElevation()) - damage = (int)Math.ceil(damage * 0.5f); - } - } - boolean throughFront = true; - if (te!=null) { - throughFront = Compute.isThroughFrontHex(game, daa.getEntityId(), te); - } - final boolean glancing = (game.getOptions().booleanOption("maxtech_glancing_blows") && (roll == toHit.getValue())); - Report r; - - // Which building takes the damage? - Building bldg = game.getBoard().getBuildingAt( daa.getTargetPos() ); - - // is the attacker dead? because that sure messes up the calculations - if (ae == null) { - return; - } - - final int direction = ae.getFacing(); - - if (lastEntityId != daa.getEntityId()) { - //who is making the attack - r = new Report(4005); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - } - - // entity isn't DFAing any more - ae.setDisplacementAttack(null); - - // should we even bother? - if (target == null || (target.getTargetType() == Targetable.TYPE_ENTITY - && (te.isDestroyed() || te.isDoomed() || te.crew.isDead()))) { - r = new Report(4245); - r.subject = ae.getId(); - r.indent(); - addReport(r); - if (ae.isProne()) { - // attacker prone during weapons phase - doEntityFall(ae, daa.getTargetPos(), 2, 3, ae.getBasePilotingRoll()); - - } else { - // same effect as successful DFA - doEntityDisplacement(ae, ae.getPosition(), daa.getTargetPos(), new PilotingRollData(ae.getId(), 4, "executed death from above")); - } - return; - } - - r = new Report(4246); - r.subject = ae.getId(); - r.indent(); - r.add(target.getDisplayName()); - r.newlines = 0; - addReport(r); - - // target still in the same position? - if ( !target.getPosition().equals(daa.getTargetPos()) ) { - r = new Report(4215); - r.subject = ae.getId(); - addReport(r); - doEntityFallsInto(ae, ae.getPosition(), daa.getTargetPos(), ae.getBasePilotingRoll()); - return; - } - - // hack: if the attacker's prone, or incapacitated, fudge the roll - if (ae.isProne() || !ae.isActive()) { - roll = -12; - r = new Report(4250); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - } else if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - roll = -12; - r = new Report(4255); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - } else if (toHit.getValue() == ToHitData.AUTOMATIC_SUCCESS) { - r = new Report(4260); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - roll = Integer.MAX_VALUE; - } else { - // report the roll - r = new Report(4025); - r.subject = ae.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - if (glancing) { - r = new Report(4030); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - } - } - - // do we hit? - if (roll < toHit.getValue()) { - Coords dest = te.getPosition(); - Coords targetDest = Compute.getPreferredDisplacement(game, te.getId(), dest, direction); - //miss - r = new Report(4035); - r.subject = ae.getId(); - addReport(r); - if (targetDest != null) { - // attacker falls into destination hex - r = new Report(4265); - r.subject = ae.getId(); - r.addDesc(ae); - r.add(dest.getBoardNum(), true); - addReport(r); - doEntityFall(ae, dest, 2, 3, ae.getBasePilotingRoll()); - - // move target to preferred hex - doEntityDisplacement(te, dest, targetDest, null); - } else { - // attacker destroyed Tanks - // suffer an ammo/power plant hit. - // TODO : a Mech suffers a Head Blown Off crit. - addReport( - destroyEntity(ae, "impossible displacement", (ae instanceof Mech), (ae instanceof Mech))); - } - return; - } - - // we hit... - // Can't DFA a target inside of a building. - int damageTaken = DfaAttackAction.getDamageTakenBy(ae); - - r = new Report(4040); - r.subject = ae.getId(); - addReport(r); - - // Targeting a building. - if ( target.getTargetType() == Targetable.TYPE_BUILDING ) { - - // The building takes the full brunt of the attack. - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - - // Damage any infantry in the hex. - this.damageInfantryIn( bldg, damage ); - - } - - // Target isn't building. - else { - if (glancing) { - damage = (int)Math.floor(damage/2.0); - } - //damage target - r = new Report(4230); - r.subject = ae.getId(); - r.add(damage); - r.add(toHit.getTableDesc()); - r.newlines = 0; - addReport(r); - while (damage > 0) { - int cluster = Math.min(5, damage); - HitData hit = te.rollHitLocation(toHit.getHitTable(), toHit.getSideTable()); - addReport( - damageEntity(te, hit, cluster, false, 0, false, false, throughFront)); - damage -= cluster; - } - } - - if (glancing) { - // Glancing Blow rule doesn't state whether damage to attacker on charge - // or DFA is halved as well, assume yes. TODO: Check with PM - damageTaken = (int)Math.floor(damageTaken/2.0); - } - - //damage attacker - r = new Report(4240); - r.subject = ae.getId(); - r.add(damageTaken); - r.newlines = 0; - addReport(r); - while (damageTaken > 0) { - int cluster = Math.min(5, damageTaken); - HitData hit = ae.rollHitLocation(ToHitData.HIT_KICK, ToHitData.SIDE_FRONT); - addReport( - damageEntity(ae, hit, cluster)); - damageTaken -= cluster; - } - - addNewLines(); - - // That's it for target buildings. - // TODO: where do I put the attacker?!? - if ( target.getTargetType() == Targetable.TYPE_BUILDING ) { - return; - } - - // Target entities are pushed away or destroyed. - Coords dest = te.getPosition(); - Coords targetDest = Compute.getValidDisplacement(game, te.getId(), dest, direction); - if (targetDest != null) { - doEntityDisplacement(te, dest, targetDest, new PilotingRollData(te.getId(), 2, "hit by death from above")); - } else { - // ack! automatic death! Tanks - // suffer an ammo/power plant hit. - // TODO : a Mech suffers a Head Blown Off crit. - addReport(destroyEntity(te, "impossible displacement", (te instanceof Mech), (te instanceof Mech))); - } - // HACK: to avoid automatic falls, displace from dest to dest - doEntityDisplacement(ae, dest, dest, new PilotingRollData(ae.getId(), 4, "executed death from above")); - } - - /** - * Get the modifier for a Kick or Push PSR - * @param attacker The attacking Entity> - * @param target The target Entity - * @param def The int default modifier - * @return The int modifier to the PSR - */ - private int getKickPushPSRMod(Entity attacker, Entity target, int def) { - int mod = def; - - if ( game.getOptions().booleanOption("maxtech_physical_psr") ) { - int attackerMod = 0; - int targetMod = 0; - - switch ( attacker.getWeightClass() ) { - case EntityWeightClass.WEIGHT_LIGHT: - attackerMod = 1; - break; - case EntityWeightClass.WEIGHT_MEDIUM: - attackerMod = 2; - break; - case EntityWeightClass.WEIGHT_HEAVY: - attackerMod = 3; - break; - case EntityWeightClass.WEIGHT_ASSAULT: - attackerMod = 4; - break; - } - switch ( target.getWeightClass() ) { - case EntityWeightClass.WEIGHT_LIGHT: - targetMod = 1; - break; - case EntityWeightClass.WEIGHT_MEDIUM: - targetMod = 2; - break; - case EntityWeightClass.WEIGHT_HEAVY: - targetMod = 3; - break; - case EntityWeightClass.WEIGHT_ASSAULT: - targetMod = 4; - break; - } - mod = attackerMod - targetMod; - } - return mod; - } - - /** - * Each mech sinks the amount of heat appropriate to its current heat - * capacity. - */ - private void resolveHeat() { - Report r; - //Heat phase header - addReport(new Report(5000, Report.PUBLIC)); - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - Entity entity = (Entity)i.nextElement(); - if ( null == entity.getPosition() ) { - continue; - } - IHex entityHex = game.getBoard().getHex(entity.getPosition()); - - // heat doesn't matter for non-mechs - if (!(entity instanceof Mech)) { - entity.heatBuildup = 0; - - if(game.getOptions().booleanOption("vehicle_fires") - && entity instanceof Tank) { - resolveVehicleFire((Tank)entity, true); - } - // If the unit is hit with an Inferno, do flaming death test. - else if ( entity.infernos.isStillBurning()) { - doFlamingDeath(entity); - } - continue; - } - else { - // Meks gain heat from inferno hits. - if ( entity.infernos.isStillBurning() ) { - int infernoHeat = entity.infernos.getHeat(); - entity.heatBuildup += infernoHeat; - r = new Report(5010); - r.subject = entity.getId(); - r.add(infernoHeat); - addReport(r); - } - } - - // should we even bother? - if ( entity.isDestroyed() || entity.isDoomed() || - entity.crew.isDoomed() || entity.crew.isDead() ) { - continue; - } - - // engine hits add a lot of heat, provided the engine is on - entity.heatBuildup += entity.getEngineCritHeat(); - - // If a Mek had an active Stealth suite, add 10 heat. - if ( entity instanceof Mech && entity.isStealthActive() ) { - entity.heatBuildup += 10; - r = new Report(5015); - r.subject = entity.getId(); - addReport(r); - } - - // If a Mek is in extreme Temperatures, add or subtract one - // heat per 10 degrees (or fraction of 10 degrees) above or - // below 50 or -30 degrees Celsius - if ( entity instanceof Mech && game.getTemperatureDifference() != 0 - && !((Mech)entity).hasLaserHeatSinks()) { - if (game.getOptions().intOption("temperature") > 50) { - entity.heatBuildup += game.getTemperatureDifference(); - r = new Report(5020); - r.subject = entity.getId(); - r.add(game.getTemperatureDifference()); - addReport(r); - } - else { - entity.heatBuildup -= game.getTemperatureDifference(); - r = new Report(5025); - r.subject = entity.getId(); - r.add(game.getTemperatureDifference()); - addReport(r); - } - } - - // Add +5 Heat if the hex you're in is on fire - // and was on fire for the full round. - if (entityHex != null) { - if (entityHex.terrainLevel(Terrains.FIRE) == 2) { - entity.heatBuildup += 5; - r = new Report(5030); - r.subject = entity.getId(); - addReport(r); - } - int magma = entityHex.terrainLevel(Terrains.MAGMA); - if(magma > 0) { - entity.heatBuildup += 5 * magma; - r = new Report(5032); - r.subject = entity.getId(); - r.add(5 * magma); - addReport(r); - } - } - - // if heatbuildup is negative due to temperature, set it to 0 - // for prettier turnreports - if (entity.heatBuildup < 0) { - entity.heatBuildup = 0; - } - - // add the heat we've built up so far. - entity.heat += entity.heatBuildup; - - // how much heat can we sink? - int tosink = entity.getHeatCapacityWithWater(); - - // should we use a coolant pod? - int safeHeat = entity.hasInfernoAmmo() ? 9 : 13; - int possibleSinkage = ((Mech)entity).getNumberOfSinks(); - for(Enumeration equip=entity.getEquipment();equip.hasMoreElements();) { - Mounted m = (Mounted)equip.nextElement(); - if(m.getType() instanceof AmmoType) { - AmmoType at = (AmmoType)(m.getType()); - if(at.getAmmoType() == AmmoType.T_COOLANT_POD && m.isAmmoUsable()) { - EquipmentMode mode = m.curMode(); - if(mode.equals("dump")) { - r = new Report(5260); - r.subject = entity.getId(); - addReport(r); - m.setShotsLeft(0); - tosink += possibleSinkage; - break; - } - if(mode.equals("safe") && entity.heat - tosink > safeHeat) { - r = new Report(5265); - r.subject = entity.getId(); - addReport(r); - m.setShotsLeft(0); - tosink += possibleSinkage; - break; - } - if(mode.equals("efficient") && entity.heat - tosink >= possibleSinkage) { - r = new Report(5270); - r.subject = entity.getId(); - addReport(r); - m.setShotsLeft(0); - tosink += possibleSinkage; - break; - } - } - } - } - - tosink = Math.min( tosink, entity.heat ); - entity.heat -= tosink; - r = new Report(5035); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(entity.heatBuildup); - r.add(tosink); - r.add(entity.heat); - addReport(r); - entity.heatBuildup = 0; - - // Does the unit have inferno ammo? - if( entity.hasInfernoAmmo() ) { - - // Roll for possible inferno ammo explosion. - if (entity.heat >= 10) { - int boom = 4 + (entity.heat >= 14 ? 2 : 0) + - (entity.heat >= 19 ? 2 : 0) + - (entity.heat >= 23 ? 2 : 0) + - (entity.heat >= 28 ? 2 : 0); - int boomroll = Compute.d6(2); - r = new Report(5040); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(boom); - r.add(boomroll); - - if (boomroll >= boom) { - //avoided - r.choose(true); - addReport(r); - } else { - r.choose(false); - addReport(r); - addReport( explodeInfernoAmmoFromHeat(entity)); - } - } - } // End avoid-inferno-explosion - int autoShutDownHeat; - boolean mtHeat; - - if (game.getOptions().booleanOption("maxtech_heat")) { - autoShutDownHeat = 50; - mtHeat = true; - } else { - autoShutDownHeat = 30; - mtHeat = false; - } - // heat effects: start up - if (entity.heat < autoShutDownHeat && entity.isShutDown()) { - if (entity.heat < 14) { - //automatically starts up again - entity.setShutDown(false); - r = new Report(5045); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - } else { - //roll for startup - int startup = 4 + (((entity.heat - 14) / 4) * 2); - if (mtHeat) { - startup = entity.crew.getPiloting() + startup - 8; - } - int suroll = Compute.d6(2); - r = new Report(5050); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(startup); - r.add(suroll); - if (suroll >= startup) { - //start 'er back up - entity.setShutDown(false); - r.choose(true); - } else { - r.choose(false); - } - addReport(r); - } - } - - // heat effects: shutdown! - // 2003-01-26 JAD - Don't shut down if you just restarted. - else if (entity.heat >= 14 && !entity.isShutDown()) { - if (entity.heat >= autoShutDownHeat) { - r = new Report(5055); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - // add a piloting roll and resolve immediately - game.addPSR(new PilotingRollData - ( entity.getId(), 3, "reactor shutdown" )); - resolvePilotingRolls(); - // okay, now mark shut down - entity.setShutDown(true); - } else if (entity.heat >= 14) { - int shutdown = 4 + (((entity.heat - 14) / 4) * 2); - if (mtHeat) { - shutdown = entity.crew.getPiloting() + shutdown - 8; - } - int sdroll = Compute.d6(2); - r = new Report(5060); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(shutdown); - r.add(sdroll); - if (sdroll >= shutdown) { - //avoided - r.choose(true); - addReport(r); - } else { - //shutting down... - r.choose(false); - addReport(r); - // add a piloting roll and resolve immediately - game.addPSR(new PilotingRollData - ( entity.getId(), 3, "reactor shutdown" )); - resolvePilotingRolls(); - // okay, now mark shut down - entity.setShutDown(true); - } - } - } - - // heat effects: ammo explosion! - if (entity.heat >= 19) { - int boom = 4 + (entity.heat >= 23 ? 2 : 0) + - (entity.heat >= 28 ? 2 : 0); - if (mtHeat) { - boom += - (entity.heat >= 35 ? 2 : 0) + - (entity.heat >= 40 ? 2 : 0) + - (entity.heat >= 45 ? 2 : 0); - // Last line is a crutch; 45 heat should be no roll - // but automatic explosion. - } - if(entity instanceof Mech && ((Mech)entity).hasLaserHeatSinks()) - boom--; - int boomroll = Compute.d6(2); - r = new Report(5065); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(boom); - r.add(boomroll); - if (boomroll >= boom) { - //mech is ok - r.choose(true); - addReport(r); - } else { - //boom! - r.choose(false); - addReport(r); - addReport( explodeAmmoFromHeat(entity)); - } - } - - // heat effects: mechwarrior damage - // N.B. The pilot may already be dead. - int lifeSupportCritCount = 0; - boolean torsoMountedCockpit = ((Mech)entity).getCockpitType() == Mech.COCKPIT_TORSO_MOUNTED; - if ((entity instanceof Mech) - && torsoMountedCockpit) { - lifeSupportCritCount = entity.getHitCriticals(CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_LIFE_SUPPORT, - Mech.LOC_RT); - lifeSupportCritCount += entity.getHitCriticals(CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_LIFE_SUPPORT, - Mech.LOC_LT); - } else { - lifeSupportCritCount = entity.getHitCriticals(CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_LIFE_SUPPORT, - Mech.LOC_HEAD); - } - if (lifeSupportCritCount > 0 - && ((entity.heat >= 15) || (torsoMountedCockpit && (entity.heat >= 0))) - && !entity.crew.isDead() && !entity.crew.isDoomed() - && !entity.crew.isEjected()) { - int heatLimitDesc = 1; - int damageToCrew = 0; - if (entity.heat >= 47 && mtHeat) { - // mechwarrior takes 5 damage - heatLimitDesc = 47; - damageToCrew = 5; - } else if (entity.heat >= 39 && mtHeat) { - // mechwarrior takes 4 damage - heatLimitDesc = 39; - damageToCrew = 4; - } else if (entity.heat >= 32 && mtHeat) { - // mechwarrior takes 3 damage - heatLimitDesc = 32; - damageToCrew = 3; - } else if (entity.heat >= 25) { - // mechwarrior takes 2 damage - heatLimitDesc = 25; - damageToCrew = 2; - } else if (entity.heat >= 15) { - // mechwarrior takes 1 damage - heatLimitDesc = 15; - damageToCrew = 1; - } - if (entity.heat > 0 - && (entity instanceof Mech) - && ((Mech)entity).getCockpitType() == Mech.COCKPIT_TORSO_MOUNTED) - damageToCrew += 1; - r = new Report(5070); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(heatLimitDesc); - r.add(damageToCrew); - addReport(r); - damageCrew(entity, damageToCrew); - } else if (mtHeat && entity.heat >= 32 - && !entity.crew.isDead() && !entity.crew.isDoomed() ) { - // Pilot may take damage from heat if MaxTech option is set - int heatroll = Compute.d6(2); - int avoidNumber = -1; - if (entity.heat >= 47) { - avoidNumber = 12; - } else if (entity.heat >= 39) { - avoidNumber = 10; - } else if (entity.heat >= 32) { - avoidNumber = 8; - } - r = new Report(5075); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(avoidNumber); - r.add(heatroll); - if (heatroll >= avoidNumber) { - //damage avoided - r.choose(true); - } else { - damageCrew(entity, 1); - r.choose(false); - } - addReport(r); - } - - // The pilot may have just expired. - if ( (entity.crew.isDead() || entity.crew.isDoomed() ) - && !entity.crew.isEjected() ) { - r = new Report(5080); - r.subject = entity.getId(); - r.addDesc(entity); - r.newlines = 0; - addReport(r); - addReport( destroyEntity(entity, "crew death", true)); - } - - // With MaxTech Heat Scale, there may occur critical damage - if (mtHeat) { - if (entity.heat >= 36) { - int damageroll = Compute.d6(2); - int damageNumber = -1; - if (entity.heat >= 44) { - damageNumber = 10; - } else if (entity.heat >= 36) { - damageNumber = 8; - } - r = new Report(5085); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(damageNumber); - r.add(damageroll); - r.newlines = 0; - if (damageroll >= damageNumber) { - r.choose(true); - addReport(r); - } else { - r.choose(false); - addReport(r); - addReport(oneCriticalEntity(entity, Compute.d6(2))); - //add an empty report, for linebreaking - r = new Report(1210); - addReport(r); - } - } - } - } - if (vPhaseReport.size() == 1) { - //I guess nothing happened... - addReport(new Report(1205, Report.PUBLIC)); - } - } - - /** - * check to see if unarmored infantry is outside in extreme temperatures - * (crude fix because infantry shouldn't be able to be deployed - * outside of vehicles or buildings, but we can't do that because - * we don't know wether the map has buildings or not or wether the - * player has an apc - */ - private void resolveExtremeTempInfantryDeath() { - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - Entity entity = (Entity)i.nextElement(); - if ( null == entity.getPosition() ) { - continue; - } - IHex entityHex = game.getBoard().getHex(entity.getPosition()); - if (entity instanceof Infantry && - !(entity instanceof BattleArmor) && - game.getTemperatureDifference() > 0 && - !(entityHex.containsTerrain(Terrains.BUILDING)) && - (entity.getTransportId() == Entity.NONE) ) { - Report r = new Report(5090); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - addReport(destroyEntity(entity, "heat/cold", false, false)); - } - } - } - - /** - * Resolve Flaming Death for the given Entity - * @param entity The Entity that may experience flaming death. - */ - private void doFlamingDeath(Entity entity) { - Report r; - int boomroll = Compute.d6(2); - // Infantry are unaffected by fire while they're still swarming. - if ( Entity.NONE != entity.getSwarmTargetId() ) { - return; - } - if (entity.getMovementMode() == IEntityMovementMode.VTOL - && !(entity.infernos.isStillBurning())) { - // VTOLs don't check as long as they are flying higher than - // the burning terrain. TODO: Check for rules conformity (ATPM?) - // according to maxtech, elevation 0 or 1 should be affected, - // this makes sense for level 2 as well - Coords c = entity.getPosition(); - IHex h = game.getBoard().getHex(c.x, c.y); - if (entity.getElevation() > 1) { - return; - } - } - // Battle Armor squads equipped with fire protection - // gear automatically avoid flaming death. - for ( Enumeration iter = entity.getMisc(); iter.hasMoreElements(); ) { - Mounted mount = (Mounted) iter.nextElement(); - EquipmentType equip = mount.getType(); - if ( BattleArmor.FIRE_PROTECTION.equals(equip.getInternalName()) ) { - r = new Report(5095); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - return; - } - } - - //Must roll 8+ to survive... - r = new Report(5100); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(boomroll); - if (boomroll >= 8) { - //phew! - r.choose(true); - addReport(r); - } else { - //eek - r.choose(false); - addReport(r); - addReport( destroyEntity(entity, "fire", false, false)); - } - } - - /** - * Checks to see if any entity has takes 20 damage. If so, they need a - * piloting skill roll. - */ - private void checkFor20Damage() { - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - final Entity entity = (Entity)i.nextElement(); - if (entity instanceof Mech) { - // if this mech has 20+ damage, add another roll to the list. - if (entity.damageThisPhase >= 20) { - if ( game.getOptions().booleanOption("maxtech_round_damage") ) { - int damMod = (entity.damageThisPhase / 20); - int weightMod = 0; - StringBuffer reportStr = new StringBuffer(); - reportStr.append(entity.damageThisPhase) - .append(" damage +").append(damMod); - - switch ( entity.getWeightClass() ) { - case EntityWeightClass.WEIGHT_LIGHT: - weightMod = 1; - break; - - case EntityWeightClass.WEIGHT_MEDIUM: - weightMod = 0; - break; - - case EntityWeightClass.WEIGHT_HEAVY: - weightMod = -1; - break; - - case EntityWeightClass.WEIGHT_ASSAULT: - weightMod = -2; - break; - } - - PilotingRollData damPRD = new PilotingRollData(entity.getId(), damMod + weightMod, reportStr.toString()); - damPRD.setCumulative(false); // see Bug# 811987 for more info - game.addPSR(damPRD); - } else { - game.addPSR(new PilotingRollData(entity.getId(), 1, "20+ damage")); - } - } - } - } - } - - /** - * Checks to see if any non-mech units are standing in fire. Called at the - * end of the movement phase - */ - public void checkForFlamingDeath() { - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - final Entity entity = (Entity)i.nextElement(); - if ( null == entity.getPosition() || - entity instanceof Mech || - entity.isDoomed() || - entity.isDestroyed() || - entity.isOffBoard()) { - continue; - } - final IHex curHex = game.getBoard().getHex(entity.getPosition()); - if (curHex.containsTerrain(Terrains.FIRE) - && entity.getElevation() <= 1) { - if(game.getOptions().booleanOption("vehicle_fires") - && entity instanceof Tank) { - checkForVehicleFire((Tank)entity, false); - } else { - doFlamingDeath(entity); - } - } - } - } - - /** - * Check to see if anyone dies due to being in a vacuum. - */ - private void checkForVacuumDeath() { - Report r; - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - final Entity entity = (Entity)i.nextElement(); - if (null == entity.getPosition() || entity.isOffBoard()) { - // If it's not on the board - aboard something else, for example... - continue; - } - if (entity.doomedInVacuum()) { - r = new Report(6015); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - addReport(destroyEntity(entity, "being in a vacuum where it can't survive", true, true)); - } - } - } - - /** - * Checks to see if any entities are underwater with damaged life support. - * Called during the end phase. - */ - private void checkForSuffocation() { - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - final Entity entity = (Entity)i.nextElement(); - if ( null == entity.getPosition() || - entity.isOffBoard()) { - continue; - } - final IHex curHex = game.getBoard().getHex(entity.getPosition()); - if (entity.getElevation()<0 && (curHex.terrainLevel(Terrains.WATER) > 1 - || (curHex.terrainLevel(Terrains.WATER) == 1 && entity.isProne())) - && entity.getHitCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_LIFE_SUPPORT, Mech.LOC_HEAD) > 0) { - Report r = new Report(6020); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - addReport(damageCrew(entity, 1)); - - } - } - } - - /** - * Resolves all built up piloting skill rolls. - * Used at end of weapons, physical phases. - */ - private void resolvePilotingRolls() { - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - resolvePilotingRolls((Entity)i.nextElement()); - } - game.resetPSRs(); - } - - /** - * Resolves and reports all piloting skill rolls for a single mech. - */ - void resolvePilotingRolls(Entity entity) { - resolvePilotingRolls(entity, false, null, null); - } - void resolvePilotingRolls( Entity entity, boolean moving, - Coords src, Coords dest ) { - // dead units don't need to. - if ( entity.isDoomed() || entity.isDestroyed() ) { - return; - } - Report r; - - // first, do extreme gravity PSR, because non-mechs do these, too - PilotingRollData rollTarget = null; - for (Enumeration i = game.getExtremeGravityPSRs();i.hasMoreElements();) { - final PilotingRollData roll = (PilotingRollData)i.nextElement(); - if (roll.getEntityId() != entity.getId()) { - continue; - } - // found a roll, use it (there can be only 1 per entity) - rollTarget = roll; - game.resetExtremeGravityPSRs(entity); - } - if (rollTarget != null && - rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - // okay, print the info - r = new Report(2180); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(rollTarget.getLastPlainDesc()); - addReport(r); - // roll - final int diceRoll = Compute.d6(2); - r = new Report(2190); - r.subject = entity.getId(); - r.add(rollTarget.getValueAsString()); - r.add(rollTarget.getDesc()); - r.add(diceRoll); - if (diceRoll < rollTarget.getValue()) { - r.choose(false); - addReport(r); - // walking and running, 1 damage per MP used more than we would - // have normally - if (entity.moved == IEntityMovementType.MOVE_WALK - || entity.moved == IEntityMovementType.MOVE_VTOL_WALK - || entity.moved == IEntityMovementType.MOVE_RUN - || entity.moved == IEntityMovementType.MOVE_VTOL_RUN) { - if (entity instanceof Mech) { - int j = entity.mpUsed; - int damage = 0; - while (j > entity.getRunMP(false)) { - j--; - damage++; - } - // Wee, direct internal damage - doExtremeGravityDamage(entity, damage); - } else if (entity instanceof Tank) { - // if we got a pavement bonus, take care of it - int k = entity.gotPavementBonus ? 1 : 0; - if (!entity.gotPavementBonus) { - int j = entity.mpUsed; - int damage = 0; - while (j > entity.getRunMP(false) + k) { - j--; - damage++; - } - doExtremeGravityDamage(entity, damage); - } - } - } - // jumping - if (entity.moved == IEntityMovementType.MOVE_JUMP && entity instanceof Mech) { - // low g, 1 damage for each hex jumped further than - // possible normally - if (game.getOptions().floatOption("gravity") < 1) { - int j = entity.mpUsed; - int damage = 0; - while (j > entity.getOriginalJumpMP()) { - j--; - damage++; - } - // Wee, direct internal damage - doExtremeGravityDamage(entity, damage); - } - // high g, 1 damage for each MP we have less than normally - else if (game.getOptions().floatOption("gravity") > 1) { - int damage = entity.getWalkMP(false) - entity.getWalkMP(); - // Wee, direct internal damage - doExtremeGravityDamage(entity, damage); - } - } - } else { - r.choose(true); - addReport(r); - } - } - // non mechs and prone mechs can now return - if ( !(entity instanceof Mech) || entity.isProne()) { - return; - } - // add all cumulative rolls, count all rolls - Vector rolls = new Vector(); - StringBuffer reasons = new StringBuffer(); - PilotingRollData base = entity.getBasePilotingRoll(); - entity.addPilotingModifierForTerrain(base); - for (Enumeration i = game.getPSRs(); i.hasMoreElements();) { - final PilotingRollData modifier = (PilotingRollData)i.nextElement(); - if (modifier.getEntityId() != entity.getId()) { - continue; - } - // found a roll, add it - rolls.addElement(modifier); - if (reasons.length() > 0) { - reasons.append(", "); - } - reasons.append(modifier.getPlainDesc()); - // only cumulative rolls get added to the base roll - if (modifier.isCumulative()) { - base.append(modifier); - } - } - // any rolls needed? - if (rolls.size() == 0) { - return; - } - // is our base roll impossible? - if (base.getValue() == PilotingRollData.AUTOMATIC_FAIL || base.getValue() == PilotingRollData.IMPOSSIBLE) { - r = new Report(2275); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(rolls.size()); - r.add(reasons.toString()); //international issue - r.add(base.getDesc()); //international issue - addReport(r); - if (moving) { - doEntityFallsInto( entity, src, dest, base ); - } else { - doEntityFall(entity, base); - } - return; - } - // loop thru rolls we do have to make... - r = new Report(2280); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(rolls.size()); - r.add(reasons.toString()); //international issue - addReport(r); - r = new Report(2285); - r.subject = entity.getId(); - r.add(base.getValueAsString()); - r.add(base.getDesc()); //international issue - addReport(r); - for (int i = 0; i < rolls.size(); i++) { - PilotingRollData modifier = (PilotingRollData)rolls.elementAt(i); - PilotingRollData target = base; - r = new Report(2290); - r.subject = entity.getId(); - r.indent(); - r.newlines = 0; - r.add(i+1); - r.add(modifier.getPlainDesc()); //international issue - addReport(r); - if (!modifier.isCumulative()) { - // non-cumulative rolls only happen due to weight class adj. - r = new Report(2295); - r.subject = entity.getId(); - r.newlines = 0; - r.add(modifier.getValueAsString()); //international issue - target = new PilotingRollData(entity.getId()); - target.append(base); - target.append(modifier); - } - int diceRoll = Compute.d6(2); - r = new Report(2300); - r.subject = entity.getId(); - r.add(target.getValueAsString()); - r.add(diceRoll); - if (diceRoll < target.getValue()) { - r.choose(false); - addReport(r); - if (moving) { - doEntityFallsInto( entity, src, dest, base ); - } else { - doEntityFall(entity, base); - } - return; - } else { - r.choose(true); - addReport(r); - } - } - } - - /** - * Inflict damage on a pilot - * - * @param en The Entity who's pilot gets damaged. - * @param damage The int amount of damage. - */ - private Vector damageCrew(Entity en, int damage) { - Vector vDesc = new Vector(); - Pilot crew = en.getCrew(); - - if (!crew.isDead() && !crew.isEjected() && !crew.isDoomed()) { - crew.setHits( crew.getHits() + damage ); - Report r = new Report(6025); - r.subject = en.getId(); - r.indent(2); - r.addDesc(en); - r.add(crew.getName()); - r.add(damage); - r.newlines = 0; - vDesc.addElement(r); - if ( Pilot.DEATH > crew.getHits() ) { - crew.setRollsNeeded( crew.getRollsNeeded() + damage ); - } else if ( !crew.isDoomed() ) { - crew.setDoomed(true); - vDesc.addAll( destroyEntity(en, "pilot death", true)); - } - } - - return vDesc; - } - - /** - * This checks if the mech pilot goes unconscious from the damage he has - * taken this phase. - */ - private void resolveCrewDamage() { - boolean anyRolls = false; - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - final Entity e = (Entity)i.nextElement(); - if (resolveCrewDamage(e, anyRolls)) { - anyRolls = true; - } - } - if (anyRolls) { - addNewLines(); - } - } - - /** - * resolves consciousness rolls for one entity - */ - private boolean resolveCrewDamage(Entity e, boolean anyRolls) { - final int totalHits = e.getCrew().getHits(); - final int rollsNeeded = e.getCrew().getRollsNeeded(); - e.crew.setRollsNeeded(0); - if (!e.isTargetable() || !e.getCrew().isActive() || rollsNeeded == 0) { - return false; - } - for (int hit = totalHits - rollsNeeded + 1; hit <= totalHits; hit++) { - int rollTarget = Compute.getConsciousnessNumber( hit ); - boolean edgeUsed = false; - do { - if (edgeUsed) - e.crew.decreaseEdge(); - int roll = Compute.d6(2); - if ( e.getCrew().getOptions().booleanOption("pain_resistance") ) - roll = Math.min(12, roll + 1); - Report r = new Report(6030); - r.subject = e.getId(); - r.addDesc(e); - r.add(e.getCrew().getName()); - r.add(rollTarget); - r.add(roll); - if (roll >= rollTarget) { - e.crew.setKoThisRound(false); - r.choose(true); - } else { - e.crew.setKoThisRound(true); - r.choose(false); - if (e.crew.hasEdgeRemaining() - && e.crew.getOptions().booleanOption("edge_when_ko")) { - edgeUsed = true; - vPhaseReport.addElement(r); - r = new Report(6520); - r.subject = e.getId(); - r.addDesc(e); - r.add(e.getCrew().getName()); - r.add(e.crew.getOptions().intOption("edge")); - } // if - //return true; - } // else - addReport(r); - } while (e.crew.hasEdgeRemaining() && e.crew.isKoThisRound() - && e.crew.getOptions().booleanOption("edge_when_ko")); - // end of do-while - if (e.crew.isKoThisRound()) { - e.crew.setUnconscious(true); - return true; - } - } - return true; - } - - /** - * Make the rolls indicating whether any unconscious crews wake up - */ - private void resolveCrewWakeUp() { - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - final Entity e = (Entity)i.nextElement(); - - // only unconscious pilots of mechs and protos and MechWarrirs - // can roll to wake up - if ( !e.isTargetable() || !e.crew.isUnconscious() || - e.crew.isKoThisRound() || - !(e instanceof Mech || e instanceof Protomech || e instanceof MechWarrior)) { - continue; - } - int roll = Compute.d6(2); - - if ( e.getCrew().getOptions().booleanOption("pain_resistance") ) - roll = Math.min(12, roll + 1); - - int rollTarget = Compute.getConsciousnessNumber( e.crew.getHits() ); - Report r = new Report(6029); - r.subject = e.getId(); - r.addDesc(e); - r.add(e.getCrew().getName()); - r.add(rollTarget); - r.add(roll); - if (roll >= rollTarget) { - r.choose(true); - e.crew.setUnconscious(false); - } else { - r.choose(false); - } - addReport(r); - } - } - - public Vector damageEntity(Entity te, HitData hit, int damage, boolean ammoExplosion) { - return damageEntity(te, hit, damage, ammoExplosion, 0, false, false); - } - - public Vector damageEntity(Entity te, HitData hit, int damage) { - return damageEntity(te, hit, damage, false, 0, false, false); - } - - public Vector damageEntity(Entity te, HitData hit, int damage, - boolean ammoExplosion, int bFrag) { - return damageEntity(te, hit, damage, ammoExplosion, bFrag, - false, false); - } - - public Vector damageEntity(Entity te, HitData hit, int damage, - boolean ammoExplosion, int bFrag, - boolean damageIS) { - return damageEntity(te, hit, damage, ammoExplosion, bFrag, - damageIS, false); - } - - public Vector damageEntity(Entity te, HitData hit, int damage, - boolean ammoExplosion, int bFrag, - boolean damageIS, boolean areaSatArty) { - return damageEntity (te, hit, damage, ammoExplosion, bFrag, damageIS, - false, true); - } - - /** - * Deals the listed damage to an entity. Returns a vector of Reports - * for the phase report - * - * @param te the target entity - * @param hit the hit data for the location hit - * @param damage the damage to apply - * @param ammoExplosion ammo explosion type damage is applied - * directly to the IS, hurts the pilot, causes auto-ejects, - * and can blow the unit to smithereens - * @param bFrag If 0, nothing; if 1, Fragmentation; if 2, Flechette. - * @param damageIS Should the target location's internal structure be - * damaged directly? - * @param areaSatArty Is the damage from an area saturating artillery - * attack? - * @param throughFront Is the damage coming through the hex the unit - * is facing? - * @return a Vector of Reports - */ - private Vector damageEntity(Entity te, HitData hit, int damage, - boolean ammoExplosion, int bFrag, - boolean damageIS, boolean areaSatArty, - boolean throughFront) { - - Vector vDesc = new Vector(); - Report r; - int te_n = te.getId(); - //This is good for shields if a shield absorps the hit it shouldn't - //effect the pilot. - boolean isHeadHit = (te instanceof Mech - && ((Mech)te).getCockpitType() != Mech.COCKPIT_TORSO_MOUNTED - && hit.getLocation() == Mech.LOC_HEAD); - - // show Locations which have rerolled with Edge - HitData undoneLocation = hit.getUndoneLocation(); - while (undoneLocation != null) { - r = new Report(6500); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - r.addDesc(te); - r.add(te.getLocationAbbr(undoneLocation)); - vDesc.addElement(r); - undoneLocation = undoneLocation.getUndoneLocation(); - } // while - // if edge was uses, give at end overview of remainings - if (hit.getUndoneLocation() != null) { - r = new Report(6510); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - r.addDesc(te); - r.add(te.crew.getOptions().intOption("edge")); - vDesc.addElement(r); - } // if - - boolean autoEject = false; - if (ammoExplosion) { - if (te instanceof Mech) { - Mech mech = (Mech)te; - if (mech.isAutoEject()) { - autoEject = true; - vDesc.addAll(ejectEntity(te, true)); - } - } - } - boolean isBattleArmor = (te instanceof BattleArmor); - boolean isPlatoon = !isBattleArmor && (te instanceof Infantry); - boolean isFerroFibrousTarget = false; - boolean wasDamageIS = false; - boolean tookInternalDamage = damageIS; - IHex te_hex = null; - - boolean hardenedArmor = false; - if ((te instanceof Mech) - && (te.getArmorType() == EquipmentType.T_ARMOR_HARDENED)) - hardenedArmor = true; - int crits = ((hit.getEffect() == HitData.EFFECT_CRITICAL) && (!hardenedArmor)) ? 1 : 0; - int specCrits = ((hit.getEffect() == HitData.EFFECT_CRITICAL) && (hardenedArmor)) ? 1 : 0; - HitData nextHit = null; - - // Some "hits" on a Protomech are actually misses. - if( te instanceof Protomech && - hit.getLocation() == Protomech.LOC_NMISS ) { - r = new Report(6035); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - return vDesc; - } - - // check for critical hit/miss vs. a BA - if( crits > 0 && te instanceof BattleArmor) { - //possible critical miss if the rerolled location isn't alive - if(hit.getLocation() >= te.locations() - || te.getInternal(hit.getLocation()) <= 0) { - r = new Report(6037); - r.add(hit.getLocation()); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - return vDesc; - } - //otherwise critical hit - r = new Report(6225); - r.add(te.getLocationAbbr(hit)); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - - crits = 0; - damage = Math.max(te.getInternal(hit.getLocation()) + - te.getArmor(hit.getLocation()), - damage); - } - - if ((te != null) && - (te.getArmor(hit) > 0) && - ((te.getArmorType() == EquipmentType.T_ARMOR_FERRO_FIBROUS) || - (te.getArmorType() == EquipmentType.T_ARMOR_LIGHT_FERRO) || - (te.getArmorType() == EquipmentType.T_ARMOR_HEAVY_FERRO))) { - isFerroFibrousTarget = true; - } - - // Is the infantry in the open? - if ( isPlatoon && !te.isDestroyed() && !te.isDoomed() ) { - te_hex = game.getBoard().getHex( te.getPosition() ); - if ( te_hex != null && - !te_hex.containsTerrain( Terrains.WOODS ) && - !te_hex.containsTerrain( Terrains.JUNGLE ) && - !te_hex.containsTerrain( Terrains.ROUGH ) && - !te_hex.containsTerrain( Terrains.RUBBLE ) && - !te_hex.containsTerrain( Terrains.SWAMP ) && - !te_hex.containsTerrain( Terrains.BUILDING ) && - !te_hex.containsTerrain(Terrains.FORTIFIED)) { - // PBI. Damage is doubled. - damage = damage * 2; - r = new Report(6040); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - } - } - // Is the infantry in vacuum? - if ( (isPlatoon || isBattleArmor ) && !te.isDestroyed() - && !te.isDoomed() && game.getOptions().booleanOption("vacuum")) { - // PBI. Double damage. - damage = damage * 2; - r = new Report(6041); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - } - // If dealing with fragmentation missiles, - // it does double damage to infantry... - // We're actually going to abuse this for AX-head warheads, too, so as to not add another parameter. - switch (bFrag) - { - case 1: - if (isPlatoon) { - damage *= 2; - r = new Report(6045); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - } - else if (te != null) { - damage = 0; - r = new Report(6050); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - } - break; - case 2: - if (isPlatoon) { - damage *= 2; - r = new Report(6055); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - } - else if ((te != null) && (!isBattleArmor)) { - damage /= 2; - r = new Report(6060); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - } - break; - case 3: - if (isFerroFibrousTarget) { - damage = te.getArmor(hit) >=3?3:te.getArmor(hit); - r = new Report(6061); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - r.add(damage); - vDesc.addElement(r); - } else if (te != null) { - r = new Report(6062); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - } - break; - case 4: - //Incendiary AC ammo does +2 damage to unarmoured infantry - if(isPlatoon ) { - damage += 2; - } - break; - - default: - // We can ignore this. - break; - } - - //save EI status, in case sensors crit destroys it - final boolean eiStatus = te.hasActiveEiCockpit(); - // BA using EI implants receive +1 damage from attacks - if (!(te instanceof Mech) && !(te instanceof Protomech) && eiStatus) { - damage += 1; - } - - // Allocate the damage - while (damage > 0) { - - // let's resolve some damage! - r = new Report(6065); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - r.addDesc(te); - r.add(damage); - if (damageIS) r.messageId = 6070; - r.add(te.getLocationAbbr(hit)); - vDesc.addElement(r); - - // was the section destroyed earlier this phase? - if (te.getInternal(hit) == IArmorState.ARMOR_DOOMED) { - // cannot transfer a through armor crit if so - crits = 0; - } - - //here goes the fun :) - //Shields take damage first then cowls then armor whee - //Shield does not protect from ammo explosions or falls. - if ( !ammoExplosion && !hit.isFallDamage() && te.hasShield() ){ - Mech me = (Mech)te; - int damageNew = me.shieldAbsorptionDamage(damage,hit.getLocation(),hit.isRear()); - //if a shield absorbed the damage then lets tell the world about it. - if ( damageNew != damage){ - int damageDiff = damage - damageNew; - damage = damageNew; - - r = new Report (3530); - r.subject = te_n; - r.indent(3); - r.newlines=0; - r.add(damageDiff); - vDesc.addElement(r); - - if ( damage <= 0 ){ - crits = 0; - specCrits = 0; - isHeadHit = false; - } - - } - } - - // Armored Cowl may absorb some damage from hit - if (te instanceof Mech) { - Mech me = (Mech)te; - if (me.hasCowl() && hit.getLocation()==Mech.LOC_HEAD && - !throughFront ) { - int damageNew = me.damageCowl(damage); - int damageDiff = damage-damageNew; - damage = damageNew; - - r = new Report (3520); - r.subject = te_n; - r.indent(3); - r.newlines=0; - r.add(damageDiff); - vDesc.addElement(r); - } - } - - // Destroy searchlights on 7+ (torso hits on mechs) - boolean spotlightHittable = false; - if (te.hasSpotlight()) { - spotlightHittable = true; - int loc = hit.getLocation(); - if (te instanceof Mech) { - if (loc != Mech.LOC_CT && loc != Mech.LOC_LT && loc != Mech.LOC_RT) { - spotlightHittable = false; - } - } else if (te instanceof Tank) { - if (loc != Tank.LOC_FRONT && loc != Tank.LOC_RIGHT && loc != Tank.LOC_LEFT) { - spotlightHittable = false; - } - } - if (spotlightHittable) { - int spotroll = Compute.d6(2); - r = new Report(6072); - r.indent(2); - r.subject = te_n; - r.add(spotroll); - vDesc.addElement(r); - if (spotroll >= 7) { - r = new Report(6071); - r.subject = te_n; - r.indent(2); - vDesc.addElement(r); - te.setSpotlightState(false); - te.setSpotlight(false); - } - } - } - - // Does an exterior passenger absorb some of the damage? - if (!damageIS) { - int nLoc = hit.getLocation(); - Entity passenger = te.getExteriorUnitAt( nLoc, hit.isRear() ); - // Does an exterior passenger absorb some of the damage? - if ( !ammoExplosion && null != passenger - && !passenger.isDoomed() ) { - // Yup. Roll up some hit data for that passenger. - r = new Report(6075); - r.subject = passenger.getId(); - r.indent(3); - r.addDesc(passenger); - vDesc.addElement(r); - - HitData passHit = passenger.getTrooperAtLocation - ( hit, te); - - // How much damage will the passenger absorb? - int absorb = 0; - HitData nextPassHit = passHit; - do { - if ( 0 < passenger.getArmor( nextPassHit ) ) { - absorb += passenger.getArmor( nextPassHit ); - } - if ( 0 < passenger.getInternal( nextPassHit ) ) { - absorb += passenger.getInternal( nextPassHit ); - } - nextPassHit = passenger.getTransferLocation( nextPassHit ); - } while ( damage > absorb && nextPassHit.getLocation() >= 0 ); - - // Damage the passenger. - vDesc.addAll( damageEntity(passenger, passHit, damage)); - - // Did some damage pass on? - if ( damage > absorb ) { - // Yup. Remove the absorbed damage. - damage -= absorb; - r = new Report(6080); - r.subject = te_n; - r.indent(1); - r.add(damage); - r.addDesc(te); - vDesc.addElement(r); - } else { - // Nope. Return our description. - return vDesc; - } - - } // End nLoc-has-exterior-passenger - - // is this a mech dumping ammo being hit in the rear torso? - boolean bTorso = (nLoc == Mech.LOC_CT || nLoc == Mech.LOC_RT || - nLoc == Mech.LOC_LT); - if (te instanceof Mech && hit.isRear() && bTorso) { - for (Enumeration e = te.getAmmo(); e.hasMoreElements(); ) { - Mounted mAmmo = (Mounted)e.nextElement(); - if (mAmmo.isDumping() && !mAmmo.isDestroyed() && - !mAmmo.isHit()) { - // doh. explode it - vDesc.addAll( explodeEquipment(te, mAmmo.getLocation(), mAmmo) ); - mAmmo.setHit(true); - } - } - } - } - - // is there armor in the location hit? - if (!ammoExplosion && te.getArmor(hit) > 0 && !damageIS) { - int tmpDamageHold = -1; - - // If the target has hardened armor, we need to adjust damage. - if (hardenedArmor) { - tmpDamageHold = damage; - damage /= 2; - damage += (tmpDamageHold%2); - } - - if (te.getArmor(hit) > damage) { - // armor absorbs all damage - te.setArmor(te.getArmor(hit) - damage, hit); - if (tmpDamageHold >= 0) - te.damageThisPhase += tmpDamageHold; - else - te.damageThisPhase += damage; - damage = 0; - r = new Report(6085); - r.subject = te_n; - r.newlines = 0; - if(spotlightHittable)r.indent(3); - r.add(te.getArmor(hit)); - vDesc.addElement(r); - } else { - // damage goes on to internal - int absorbed = Math.max(te.getArmor(hit), 0); - te.setArmor(IArmorState.ARMOR_DESTROYED, hit); - if (tmpDamageHold >= 0) - te.damageThisPhase += 2*absorbed; - else - te.damageThisPhase += absorbed; - damage -= absorbed; - r = new Report(6090); - r.subject = te_n; - r.newlines = 0; - if(spotlightHittable)r.indent(3); - vDesc.addElement(r); - if (te instanceof GunEmplacement) { - // gun emplacements have no internal, - // destroy the section - destroyLocation(te, hit.getLocation()); - r = new Report(6115); - r.subject = te_n; - r.newlines = 0; - vDesc.addElement(r); - - if (te.getTransferLocation(hit).getLocation() == - Entity.LOC_DESTROYED) { - vDesc.addAll( - destroyEntity(te, - "damage", - false)); - } - } - } - - // If it has hardened armor, now we need to "correct" any remaining damage. - if (tmpDamageHold > 0) { - if (hardenedArmor) { - damage *= 2; - damage -= (tmpDamageHold%2); - } - } - } - - // is there damage remaining? - if (damage > 0) { - tookInternalDamage = true; - // is there internal structure in the location hit? - if (te.getInternal(hit) > 0) { - // Triggers a critical hit on Vehicles and Mechs. - if ( !isPlatoon && !isBattleArmor ) { - crits++; - } - - // Now we need to consider alternate structure types! - int tmpDamageHold = -1; - if ((te instanceof Mech) && (((Mech)te).hasCompositeStructure())) { - tmpDamageHold = damage; - damage *= 2; - } - if ((te instanceof Mech) && (((Mech)te).hasReinforcedStructure())) { - tmpDamageHold = damage; - damage /= 2; - damage += (tmpDamageHold%2); - } - - if (te.getInternal(hit) > damage) { - // internal structure absorbs all damage - te.setInternal(te.getInternal(hit) - damage, hit); - te.damageThisPhase += damage; - damage = 0; - r = new Report(1210); - r.subject = te_n; - r.newlines = 0; - // Infantry platoons have men not "Internals". - if ( isPlatoon ) { - r.messageId = 6095; - } else { - r.messageId = 6100; - } - r.add(te.getInternal(hit)); - vDesc.addElement(r); - } else { - // damage transfers, maybe - int absorbed = Math.max(te.getInternal(hit), 0); - - // Handle Protomech pilot damage - // due to location destruction - if ( te instanceof Protomech ) { - int hits = Protomech.POSSIBLE_PILOT_DAMAGE[hit.getLocation()] - - ((Protomech)te).getPilotDamageTaken(hit.getLocation()); - if ( hits > 0 ) { - vDesc.addAll( damageCrew( te, hits )); - ((Protomech)te).setPilotDamageTaken - (hit.getLocation(), - Protomech.POSSIBLE_PILOT_DAMAGE[hit.getLocation()]); - } - } - - // Platoon, Trooper, or Section destroyed message - r = new Report(1210); - r.subject = te_n; - r.newlines = 0; - if ( isPlatoon ) { - // Infantry have only one section, and - // are therefore destroyed. - r.messageId = 6105; - } else if ( isBattleArmor ) { - r.messageId = 6110; - } else { - r.messageId = 6115; - } - vDesc.addElement(r); - - // If a sidetorso got destroyed, and the - // corresponding arm is not yet destroyed, add - // it as a club to that hex (p.35 BMRr) - if (te instanceof Mech && - ((hit.getLocation() == Mech.LOC_RT && - te.getInternal(Mech.LOC_RARM) > 0) || - (hit.getLocation() == Mech.LOC_LT && - te.getInternal(Mech.LOC_LARM) > 0))) { - int blownOffLocation = -1; //good initial value? - if (hit.getLocation() == Mech.LOC_RT) { - blownOffLocation = Mech.LOC_RARM; - } else { - blownOffLocation = Mech.LOC_LARM; - } - r = new Report(6120); - r.subject = te_n; - r.add(te.getLocationName(blownOffLocation)); - r.newlines = 0; - vDesc.addElement(r); - IHex h = game.getBoard().getHex(te.getPosition()); - if (te instanceof BipedMech) { - if (!h.containsTerrain( Terrains.ARMS)) { - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.ARMS, 1)); - } - else h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.ARMS, h.terrainLevel(Terrains.ARMS)+1)); - } else if (!h.containsTerrain( Terrains.LEGS)) { - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.LEGS, 1)); - } else h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.LEGS, h.terrainLevel(Terrains.LEGS)+1)); - sendChangedHex(te.getPosition()); - } - - // Level 3 mechanized BA, troopers riding on a location - // all die when the location is destroyed. - if(game.getOptions().booleanOption("maxtech_mechanized_ba") && - te instanceof Mech) { - Entity passenger = te.getExteriorUnitAt( hit.getLocation(), hit.isRear() ); - if(null != passenger && !passenger.isDoomed()) { - HitData passHit = passenger.getTrooperAtLocation( hit, te); - passHit.setEffect(HitData.EFFECT_CRITICAL); //ensures a kill - if(passenger.getInternal(passHit) > 0) { - vDesc.addAll(damageEntity(passenger, passHit, damage)); - } - passHit = new HitData(hit.getLocation(), !(hit.isRear())); - passHit = passenger.getTrooperAtLocation( passHit, te); - passHit.setEffect(HitData.EFFECT_CRITICAL); //ensures a kill - if(passenger.getInternal(passHit) > 0) { - vDesc.addAll(damageEntity(passenger, passHit, damage)); - } - } - } - - // Destroy the location. - destroyLocation(te, hit.getLocation()); - te.damageThisPhase += absorbed; - damage -= absorbed; - - // Now we need to consider alternate structure types! - if (tmpDamageHold > 0) { - if (((Mech)te).hasCompositeStructure()) { - // If there's a remainder, we can actually ignore it. - damage /= 2; - } else if (((Mech)te).hasReinforcedStructure()) { - damage *= 2; - damage -= (tmpDamageHold%2); - } - } - - if (te instanceof Mech && - (hit.getLocation() == Mech.LOC_RT || - hit.getLocation() == Mech.LOC_LT)) { - - boolean engineExploded = false; - - - int numEngineHits = 0; - numEngineHits += - te.getHitCriticals(CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_ENGINE, - Mech.LOC_CT); - numEngineHits += - te.getHitCriticals(CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_ENGINE, - Mech.LOC_RT); - numEngineHits += - te.getHitCriticals(CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_ENGINE, - Mech.LOC_LT); - - engineExploded = checkEngineExplosion(te, vDesc, numEngineHits); - if ( !engineExploded && numEngineHits > 2 ) { - // third engine hit - vDesc.addAll( destroyEntity(te, "engine destruction")); - if ( game.getOptions().booleanOption("auto_abandon_unit") ) - vDesc.addAll(abandonEntity(te)); - - } - } - - if (te instanceof VTOL && hit.getLocation() == VTOL.LOC_ROTOR) { - //if rotor is destroyed, movement goes bleh. - //I think this will work? - hit.setEffect(HitData.EFFECT_VEHICLE_MOVE_DESTROYED); - - } - } - } if (te.getInternal(hit) <= 0) { - // internal structure is gone, what are the transfer potentials? - nextHit = te.getTransferLocation(hit); - if (nextHit.getLocation() == Entity.LOC_DESTROYED) { - if (te instanceof Mech) { - // add all non-destroyed engine crits - te.engineHitsThisRound += te.getGoodCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_ENGINE, hit.getLocation()); - // and substract those that where hit previously this round - // hackish, but works. - te.engineHitsThisRound -= te.getHitCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_ENGINE, hit.getLocation()); - } - - boolean engineExploded = false; - - engineExploded = checkEngineExplosion(te, vDesc, te.engineHitsThisRound); - - if ( !engineExploded && !((te instanceof VTOL) && hit.getLocation() == VTOL.LOC_ROTOR)) { - // Entity destroyed. Ammo explosions are - // neither survivable nor salvagable. - // Only ammo explosions in the CT are devastating. - vDesc.addAll( destroyEntity( te, "damage", - !ammoExplosion, - !( (ammoExplosion || areaSatArty) && - hit.getLocation() == - Mech.LOC_CT ) ) ); - // If the head is destroyed, kill the crew. - if (hit.getLocation() == Mech.LOC_HEAD || - (hit.getLocation() == Mech.LOC_CT && ((ammoExplosion && !autoEject) || areaSatArty))) { - te.getCrew().setDoomed(true); - } - if (game.getOptions().booleanOption("auto_abandon_unit")) { - vDesc.addAll(abandonEntity(te)); - } - } - - // nowhere for further damage to go - damage = 0; - } else if ( nextHit.getLocation() == Entity.LOC_NONE ) { - // Rest of the damage is wasted. - damage = 0; - } else if (ammoExplosion && te.locationHasCase(hit.getLocation())) { - // Remaining damage prevented by CASE - r = new Report(6125); - r.subject = te_n; - r.add(damage); - r.indent(3); - r.newlines = 0; - vDesc.addElement(r); - - // ... but page 21 of the Ask The Precentor Martial FAQ - // www.classicbattletech.com/PDF/AskPMForumArchiveandFAQ.pdf - // says that the damage counts for making PSRs. - te.damageThisPhase += damage; - - // The target takes no more damage from the explosion. - damage = 0; - } else if (damage > 0) { - // remaining damage transfers - r = new Report(6130); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - r.add(damage); - r.add(te.getLocationAbbr(nextHit)); - vDesc.addElement(r); - - // If there are split weapons in this location, mark it as - // destroyed, even if it took no criticals. - for (Enumeration weapons=te.getWeapons(); weapons.hasMoreElements(); ) { - Mounted m = (Mounted)weapons.nextElement(); - if (m.isSplit()) { - if (m.getLocation() == hit.getLocation() || - m.getLocation() == nextHit.getLocation()) { - te.setWeaponDestroyed(m); - } - } - } - } - } - } else if (hit.getSpecCritMod() < 0) { - // If there ISN'T any armor left but we did damage, then there's a chance of a crit, using Armor Piercing. - specCrits++; - } - // check for breaching - vDesc.addAll( breachCheck(te, hit.getLocation(), null)); - - // resolve special results - if (hit.getEffect() == HitData.EFFECT_VEHICLE_MOVE_DAMAGED) { - r = new Report(6135); - r.subject = te_n; - r.indent(3); - vDesc.addElement(r); - int nMP = te.getOriginalWalkMP(); - if (nMP > 0) { - te.setOriginalWalkMP(nMP - 1); - - if (te.getOriginalWalkMP()==0) { - // From http://www.classicbattletech.com/PDF/AskPMForumArchiveandFAQ.pdf - // page 19, tanks are only immobile if they take that critical hit. - // ((Tank)te).immobilize(); - - // Hovercraft reduced to 0MP over water sink - if ( te.getMovementMode() == IEntityMovementMode.HOVER && - game.getBoard().getHex( te.getPosition() ).terrainLevel(Terrains.WATER) > 0 - &&!(game.getBoard().getHex( te.getPosition() ).containsTerrain(Terrains.ICE))) { - vDesc.addAll( destroyEntity(te, "a watery grave", false) ); - } - } - } - } else if (hit.getEffect() == HitData.EFFECT_VEHICLE_MOVE_DESTROYED) { - r = new Report(6140); - r.subject = te_n; - r.indent(3); - vDesc.addElement(r); - ((Tank)te).immobilize(); - // Does the hovercraft sink? - te_hex = game.getBoard().getHex( te.getPosition() ); - if ( te.getMovementMode() == IEntityMovementMode.HOVER && - te_hex.terrainLevel(Terrains.WATER) > 0 && - !(te_hex.containsTerrain(Terrains.ICE))) { - vDesc.addAll( destroyEntity(te, "a watery grave", false) ); - } - if(te instanceof VTOL) { - Report.addNewline(vDesc); - //report problem: add tab - vDesc.addAll( crashVTOL((VTOL)te)); - } - } else if (hit.getEffect() == HitData.EFFECT_VEHICLE_TURRETLOCK) { - r = new Report(6145); - r.subject = te_n; - r.indent(3); - vDesc.addElement(r); - ((Tank)te).lockTurret(); - } - else if (hit.getEffect() == - HitData.EFFECT_GUN_EMPLACEMENT_WEAPONS) { - r = new Report(6146); - r.subject = te_n; - r.indent(3); - vDesc.addElement(r); - Enumeration weapons = te.getWeapons(); - while (weapons.hasMoreElements()) { - ((Mounted) weapons.nextElement()).setDestroyed(true); - } - } - else if (hit.getEffect() == HitData.EFFECT_GUN_EMPLACEMENT_TURRET) { - r = new Report(6147); - r.subject = te_n; - r.indent(3); - vDesc.addElement(r); - ((GunEmplacement)te).setTurretLocked(true); - } - else if (hit.getEffect() == HitData.EFFECT_GUN_EMPLACEMENT_CREW) { - r = new Report(6148); - r.subject = te_n; - r.indent(3); - vDesc.addElement(r); - ((GunEmplacement)te).getCrew().setDoomed(true); - } - // roll all critical hits against this location - // unless the section destroyed in a previous phase? - if (te.getInternal(hit) != IArmorState.ARMOR_DESTROYED) { - for (int i = 0; i < crits; i++) { - ((Report) vDesc.elementAt(vDesc.size() - 1)).newlines++; - vDesc.addAll( criticalEntity(te, hit.getLocation(), hit.glancingMod()) ); - } - crits = 0; - - for (int i = 0; i < specCrits; i++) { - ((Report) vDesc.elementAt(vDesc.size() - 1)).newlines++; - vDesc.addAll( criticalEntity(te, hit.getLocation(), (hardenedArmor?-2:hit.getSpecCritMod())+hit.glancingMod()) ); - } - specCrits = 0; - } - - if (isHeadHit) { - Report.addNewline(vDesc); - vDesc.addAll( damageCrew(te, 1) ); - } - - // loop to next location - hit = nextHit; - if (damageIS) { - wasDamageIS = true; - damageIS = false; - } - } - //Mechs using EI implants take pilot damage each time a hit - //inflicts IS damage - if (tookInternalDamage - && ((te instanceof Mech) || (te instanceof Protomech)) - && te.hasActiveEiCockpit()) { - Report.addNewline(vDesc); - int roll = Compute.d6(2); - r = new Report(5075); - r.subject = te.getId(); - r.addDesc(te); - r.add(7); - r.add(roll); - r.choose(roll>=7); - r.indent(2); - vDesc.add(r); - if(roll < 7) { - vDesc.addAll( damageCrew(te, 1) ); - } - } - - //damage field guns on infantry platoons if there arent enough men left to man it - if(isPlatoon) { - float tons = 0.0f; - for(Enumeration weapons = te.getWeapons();weapons.hasMoreElements();) { - Mounted weap = weapons.nextElement(); - WeaponType wtype = (WeaponType)weap.getType(); - if(!wtype.hasFlag(WeaponType.F_INFANTRY)) { - tons += wtype.getTonnage(te); - if(tons > te.getInternal(Infantry.LOC_INFANTRY)) { - weap.setDestroyed(true); - } - } - } - } - - //This flag indicates the hit was directly to IS - if (wasDamageIS) { - Report.addNewline(vDesc); - } - return vDesc; - } - - /** - * Check to see if the entity's engine explodes. - * Rules for ICE explosions are different to fusion engines. - * @param en - the Entity in question. - * This value must not be null. - * @param vDesc - the Vector that this function should - * add its Reports to. It may be empty, but not - * null. - * @param hits - the number of criticals on the engine - * @return true if the unit's engine exploded, - * false if not. - */ - private boolean checkEngineExplosion(Entity en, Vector vDesc, int hits) { - if (!(en instanceof Mech) - && !(en instanceof QuadMech) - && !(en instanceof BipedMech)) { - return false; - } - if(en.isDoomed() || en.isDestroyed()) - return false; - Mech mech = (Mech)en; - - //ICE can always explode and roll every time hit - if (mech.getEngine().isFusion() - && (!game.getOptions().booleanOption("engine_explosions") - || en.rolledForEngineExplosion - || en.engineHitsThisRound < 2) ) - return false; - int explosionBTH = 12; - if(!mech.getEngine().isFusion()) { - switch (hits) { - case 0: - return false; - case 1: - explosionBTH = 10; - break; - case 2: - explosionBTH = 7; - break; - case 3: - default: - explosionBTH = 4; - break; - } - } - int explosionRoll = Compute.d6(2); - boolean didExplode = explosionRoll >= explosionBTH; - - Report r; - r = new Report(6150); - r.subject = en.getId(); - r.indent(2); - r.addDesc(en); - r.add(en.engineHitsThisRound); - vDesc.addElement(r); - r = new Report(6155); - r.subject = en.getId(); - r.indent(2); - r.add(explosionBTH); - r.add(explosionRoll); - vDesc.addElement(r); - en.rolledForEngineExplosion = true; - - if ( !didExplode ) { - //whew! - r = new Report(6160); - r.subject = en.getId(); - r.indent(2); - vDesc.addElement(r); - } else { - r = new Report(6165, Report.PUBLIC); - r.subject = en.getId(); - r.indent(2); - vDesc.addElement(r); - vDesc.addAll( destroyEntity(en, "engine explosion", false, false)); - //kill the crew - en.getCrew().setDoomed(true); - - //This is a hack so MM.NET marks the mech as not salvageable - if ( en instanceof Mech ) - destroyLocation(en, Mech.LOC_CT); - - //Light our hex on fire - final IHex curHex = game.getBoard().getHex(en.getPosition()); - - if ((null != curHex) - && !curHex.containsTerrain(Terrains.FIRE) - && (curHex.containsTerrain(Terrains.WOODS) - || curHex.containsTerrain(Terrains.JUNGLE))) { - curHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - r = new Report(6170, Report.PUBLIC); - r.subject = en.getId(); - r.indent(2); - r.add(en.getPosition().getBoardNum()); - vDesc.addElement(r); - sendChangedHex(en.getPosition()); - } - - //ICE explosions don't hurt anyone else, but fusion do - if (mech.getEngine().isFusion()) { - //Nuke anyone that is in our hex - Enumeration entitesWithMe = game.getEntities(en.getPosition()); - Hashtable entitesHit = new Hashtable(); - - entitesHit.put(en, en); - - while (entitesWithMe.hasMoreElements()) { - Entity entity = (Entity)entitesWithMe.nextElement(); - if ( entity.equals(en) ) - continue; - vDesc.addAll( destroyEntity(entity, "engine explosion proximity", false, false)); - // Kill the crew - entity.getCrew().setDoomed(true); - entitesHit.put(entity, entity); - } - - //Now we damage people near us - int engineRating = en.getEngine().getRating(); - int[] damages = { 999, (engineRating / 10), (engineRating / 20), (engineRating / 40) }; - Vector entites = game.getEntitiesVector(); - for (int i = 0; i < entites.size(); i++) { - Entity entity = (Entity)entites.elementAt(i); - - if (entitesHit.containsKey(entity)) - continue; - - if ( entity.isDoomed() || entity.isDestroyed() || !entity.isDeployed() ) - continue; - - int range = en.getPosition().distance(entity.getPosition()); - - if ( range > 3 ) - continue; - - int damage = damages[range]; - - r = new Report(6175); - r.subject = entity.getId(); - r.indent(2); - r.addDesc(entity); - r.add(damage); - r.newlines = 0; - vDesc.addElement(r); - - while (damage > 0) { - int cluster = Math.min(5, damage); - HitData hit = entity.rollHitLocation(ToHitData.HIT_NORMAL, Compute.targetSideTable(en, entity)); - vDesc.addAll( damageEntity(entity, hit, cluster)); - damage -= cluster; - } - Report.addNewline(vDesc); - } - } - } - - return didExplode; - } - - /** - * Apply a single critical hit. - * - * The following private member of Server are accessed from this function, - * preventing it from being factored out of the Server class: - * destroyEntity() - * destroyLocation() - * checkEngineExplosion() - * damageCrew() - * explodeEquipment() - * game - * - * @param en the Entity that is being damaged. - * This value may not be null. - * @param loc the int location of critical hit. - * This value may be Entity.NONE for hits - * to Tanks and for hits to a Protomech - * torso weapon. - * @param cs the CriticalSlot being damaged. - * This value may not be null. - * For critical hits on a Tank, the index of - * the slot should be the index of the critical hit table. - * @param secondaryEffects the boolean flag that indicates - * whether to allow critical hits to cause secondary effects (such - * as triggering an ammo explosion, sending hovercraft to watery - * graves, or damaging Protomech torso weapons). This value is - * normally true, but it will be false - * when the hit is being applied from a saved game or scenario. - */ - public Vector applyCriticalHit( Entity en, int loc, CriticalSlot cs, - boolean secondaryEffects ) { - Vector vDesc = new Vector(); - Report r; - - // Handle hits on "critical slots" of tanks. - if ( en instanceof Tank ) { - Tank tank = (Tank)en; - VTOL vtol = null; - if (en instanceof VTOL) - vtol = (VTOL)en; - r = new Report(6180); - r.subject = en.getId(); - r.indent(3); - r.newlines = 0; - vDesc.addElement(r); - switch ( cs.getIndex() ) { - case 1 : //crew stunned, or killed if VTOL - if (vtol == null) { - r = new Report(6185); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - // Carried units can't unload from a stunned transport. - // Units that escape a transport don't need to un-stun. - tank.stunCrew(); - } else { //VTOL's suffer crew death instead - r = new Report(6190); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - vDesc.addAll( - destroyEntity(vtol, "crew death", true)); - en.getCrew().setDoomed(true); - vDesc.addAll( crashVTOL(vtol)); - } - break; - case 2 : //this one's ridiculous. the 'main weapon' jams. - Mounted mWeap = tank.getMainWeapon(); - if (mWeap == null) { //no main weapon, no crit - r = new Report(6195); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - } - else { - r = new Report(6200); - r.subject = en.getId(); - r.add(mWeap.getName()); - int jamTurns = tank.getJammedTurns() + 1; - if ( jamTurns > 1 ) { - r.messageId = 6205; - r.add(jamTurns); - } - r.newlines = 0; - vDesc.addElement(r); - tank.setJammedTurns( jamTurns ); - } - break; - case 3 : //engine destroyed - r = new Report(6210); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - tank.immobilize(); - // Does the hovercraft sink? - // Sinking immobile hovercraft is a secondary effect - // and does not occur when loading from a scenario. - if ( secondaryEffects ) { - IHex te_hex = game.getBoard().getHex( en.getPosition() ); - if (vtol == null) { - if ( en.getMovementMode() == IEntityMovementMode.HOVER - && te_hex.terrainLevel(Terrains.WATER) > 0 - && !(te_hex.containsTerrain(Terrains.ICE))) { - vDesc.addAll( - destroyEntity(en,"a watery grave", false)); - } - } else { //VTOLs may land or crash - //TODO: Nothing if VTOL is landed. If over clear, - // paved, rough, or building, VTOL must make PSR - // to land or crash. Other terrain is automatic - // crash. - Report.addNewline(vDesc); - //report problem: add 3 tabs - vDesc.addAll( crashVTOL(vtol)); - } - } - break; - case 4 : //crew killed - r = new Report(6190); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - vDesc.addAll( - destroyEntity(en, "crew death", true)); - en.getCrew().setDoomed(true); - if (vtol != null) { //VTOL's crash too - Report.addNewline(vDesc); - //report problem: add 3 tabs - vDesc.addAll( crashVTOL(vtol)); - } - break; - case 5 : //fuel tank/engine shielding, vehicle explodes - r = new Report(6215); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - if (vtol == null) { - vDesc.addAll(destroyEntity(en, "fuel tank explosion", false, false)); - } else { //VTOL's explode and scatter burning fuel - Report.addNewline(vDesc); - //report problem: add 3 tabs - vDesc.addAll( explodeVTOL(vtol)); - } - en.getCrew().setDoomed(true); - break; - case 6 : //power plant hit, vehicle explodes - r = new Report(6220); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - boolean hasCASE = en.locationHasCase(Tank.LOC_BODY); - if (vtol == null) { - vDesc.addAll(destroyEntity(en, "power plant destruction", hasCASE, hasCASE)); - } else { //VTOL's explode and scatter burning fuel - Report.addNewline(vDesc); - //report problem: add 3 tabs - vDesc.addAll( explodeVTOL(vtol)); - } - en.getCrew().setDoomed(!hasCASE); - break; - } - - } // End entity-is-tank - - // Handle critical hits on system slots. - else if ( CriticalSlot.TYPE_SYSTEM == cs.getType() ) { - cs.setHit(true); - if (en instanceof Protomech) { - int numHit=((Protomech)en).getCritsHit(loc); - if ( cs.getIndex() != Protomech.SYSTEM_TORSO_WEAPON_A && - cs.getIndex() != Protomech.SYSTEM_TORSO_WEAPON_B ) { - r = new Report(6225); - r.subject = en.getId(); - r.indent(3); - r.newlines = 0; - r.add(Protomech.systemNames[cs.getIndex()]); - vDesc.addElement(r); - } - switch (cs.getIndex()) { - case Protomech.SYSTEM_HEADCRIT: - if (2==numHit) { - r = new Report(6230); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - destroyLocation(en, loc); - } - break; - case Protomech.SYSTEM_ARMCRIT: - if (2==numHit) { - r = new Report(6235); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - destroyLocation(en,loc); - } - break; - case Protomech.SYSTEM_LEGCRIT: - if (3==numHit) { - r = new Report(6240); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - destroyLocation(en,loc); - } - break; - case Protomech.SYSTEM_TORSOCRIT: - if (3==numHit) { - vDesc.addAll( - destroyEntity(en, "torso destruction")); - } - // Torso weapon hits are secondary effects and - // do not occur when loading from a scenario. - else if ( secondaryEffects ) { - int tweapRoll=Compute.d6(1); - CriticalSlot newSlot = null; - switch (tweapRoll) { - case 1: - case 2: - newSlot = new CriticalSlot - ( CriticalSlot.TYPE_SYSTEM, - Protomech.SYSTEM_TORSO_WEAPON_A ); - vDesc.addAll( - applyCriticalHit(en, Entity.NONE, - newSlot, secondaryEffects)); - break; - case 3: - case 4: - newSlot = new CriticalSlot - ( CriticalSlot.TYPE_SYSTEM, - Protomech.SYSTEM_TORSO_WEAPON_B ); - vDesc.addAll( - applyCriticalHit(en, Entity.NONE, - newSlot, secondaryEffects)); - break; - case 5: - case 6: - //no effect - } - } - break; - case Protomech.SYSTEM_TORSO_WEAPON_A: - Mounted weaponA =( (Protomech) en ).getTorsoWeapon(true); - if ( null != weaponA ) { - weaponA.setHit(true); - r = new Report(6245); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - } - break; - case Protomech.SYSTEM_TORSO_WEAPON_B: - Mounted weaponB = ( (Protomech) en ).getTorsoWeapon(false); - if ( null != weaponB ) { - weaponB.setHit(true); - r = new Report(6250); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - } - break; - - - } // End switch( cs.getType() ) - - // Shaded hits cause pilot damage. - if ( ((Protomech)en).shaded(loc, numHit) ) { - // Destroyed Protomech sections have - // already damaged the pilot. - int pHits = - Protomech.POSSIBLE_PILOT_DAMAGE[ loc ] - - ((Protomech)en).getPilotDamageTaken( loc ); - if ( Math.min(1, pHits) > 0 ) { - Report.addNewline(vDesc); - vDesc.addAll( - damageCrew(en, 1)); - pHits = 1 + ((Protomech)en) - .getPilotDamageTaken( loc ); - ((Protomech)en).setPilotDamageTaken - ( loc, pHits ); - } - } // End have-shaded-hit - - } // End entity-is-protomech - else { - r = new Report(6225); - r.subject = en.getId(); - r.indent(3); - r.add(((Mech)en).getSystemName(cs.getIndex())); - r.newlines = 0; - vDesc.addElement(r); - switch(cs.getIndex()) { - case Mech.SYSTEM_COCKPIT : - // Don't kill a pilot multiple times. - if ( Pilot.DEATH > en.getCrew().getHits() ) { - // boink! - en.getCrew().setDoomed(true); - Report.addNewline(vDesc); - vDesc.addAll( - destroyEntity(en, "pilot death", true)); - } - break; - case Mech.SYSTEM_ENGINE : - en.engineHitsThisRound++; - - boolean engineExploded = false; - - int numEngineHits = 0; - numEngineHits += en.getHitCriticals - (CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_ENGINE, Mech.LOC_CT); - numEngineHits += en.getHitCriticals - (CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_ENGINE, Mech.LOC_RT); - numEngineHits += en.getHitCriticals - (CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_ENGINE, Mech.LOC_LT); - - engineExploded = checkEngineExplosion(en, vDesc, numEngineHits); - if ( !engineExploded && numEngineHits > 2 ) { - // third engine hit - vDesc.addAll( - destroyEntity(en, "engine destruction")); - if (game.getOptions().booleanOption("auto_abandon_unit")) { - vDesc.addAll(abandonEntity(en)); - } - } - break; - case Mech.SYSTEM_GYRO : - if (en.getHitCriticals(CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_GYRO, loc) > 1) { - // gyro destroyed - game.addPSR( new PilotingRollData - (en.getId(), PilotingRollData.AUTOMATIC_FAIL, - 3, "gyro destroyed") ); - } else { - // first gyro hit - game.addPSR( new PilotingRollData - (en.getId(), 3, "gyro hit") ); - } - break; - case Mech.ACTUATOR_UPPER_LEG : - case Mech.ACTUATOR_LOWER_LEG : - case Mech.ACTUATOR_FOOT : - // leg/foot actuator piloting roll - game.addPSR( new PilotingRollData - (en.getId(), 1, "leg/foot actuator hit") ); - break; - case Mech.ACTUATOR_HIP : - // hip piloting roll - game.addPSR( new PilotingRollData - (en.getId(), 2, "hip actuator hit") ); - break; - } - - } // End entity-is-mek - - } // End crit-on-system-slot - - // Handle critical hits on equipment slots. - else if ( CriticalSlot.TYPE_EQUIPMENT == cs.getType() ) { - cs.setHit(true); - Mounted mounted = en.getEquipment(cs.getIndex()); - EquipmentType eqType = mounted.getType(); - boolean hitBefore = mounted.isHit(); - - r = new Report(6225); - r.subject = en.getId(); - r.indent(3); - r.add(mounted.getDesc()); - r.newlines = 0; - vDesc.addElement(r); - - //Shield objects are not useless when they take one crit. - //Shields can be critted and still be usable. - if (eqType instanceof MiscType && ((MiscType)eqType).isShield()) - mounted.setHit(false); - else - mounted.setHit(true); - - if (eqType instanceof MiscType && eqType.hasFlag(MiscType.F_HARJEL)) { - r = new Report(6254); - r.subject = en.getId(); - r.indent(2); - breachLocation(en, loc, null, true); - } - - // If the item is the ECM suite of a Mek Stealth system - // then it's destruction turns off the stealth. - if ( !hitBefore && eqType instanceof MiscType && - eqType.hasFlag(MiscType.F_ECM) && - mounted.getLinkedBy() != null ) { - Mounted stealth = mounted.getLinkedBy(); - r = new Report(6255); - r.subject = en.getId(); - r.indent(2); - r.add(stealth.getType().getName()); - r.newlines = 0; - vDesc.addElement(r); - stealth.setMode( "Off" ); - } - - // Handle equipment explosions. - // Equipment explosions are secondary effects and - // do not occur when loading from a scenario. - if ( secondaryEffects && eqType.isExplosive() && !hitBefore ) { - vDesc.addAll(explodeEquipment(en, loc, mounted)); - } - - // Make sure that ammo in this slot is exhaused. - if ( mounted.getShotsLeft() > 0 ) { - mounted.setShotsLeft(0); - } - - } // End crit-on-equipment-slot - // mechs with TSM hit by anti-tsm missiles this round get another crit - if (en instanceof Mech && en.hitThisRoundByAntiTSM) { - Mech mech = (Mech)en; - if (mech.hasTSM()) { - r = new Report(6430); - r.subject = en.getId(); - r.indent(2); - r.addDesc(en); - r.newlines = 0; - vDesc.addElement(r); - vDesc.addAll(oneCriticalEntity(en, Compute.d6(2))); - } - en.hitThisRoundByAntiTSM = false; - } - - // Return the results of the damage. - return vDesc; - } - - /** - * Rolls and resolves critical hits with no die roll modifiers. - */ - private Vector criticalEntity(Entity en, int loc) { - return criticalEntity(en, loc, 0, true); - } - - private Vector criticalEntity(Entity en, int loc, int critMod) { - return criticalEntity(en, loc, critMod, true); - } - - /** - * Rolls one critical hit - */ - private Vector oneCriticalEntity(Entity en, int loc) { - return criticalEntity(en, loc, 0, false); - } - - private Vector crashVTOL(VTOL en,Coords crashPos,int curElevation) { - return crashVTOL(en, false, 0,crashPos,curElevation,0); - } - private Vector crashVTOL(VTOL en) { - return crashVTOL(en, false, 0 , en.getPosition(),en.getElevation(),0); - } - - /** - * Crash a VTOL - * @param en The VTOL to crash - * @param sideSlipCrash A boolean value indicating wether this - * is a sideslip crash or not. - * @param hexesMoved The int number of hexes moved. - * @param crashPos The Coords of the crash - * @param crashElevation The int elevation of the VTOL - * @param impactSide The int describing the side on which - * the VTOL falls - * @return a Vector of Reports. - */ - private Vector crashVTOL(VTOL en, boolean sideSlipCrash, int hexesMoved, Coords crashPos, int crashElevation,int impactSide) { - Vector vDesc = new Vector(); - Report r; - - if(!sideSlipCrash) { - //report lost movement and crashing - r = new Report(6260); - r.subject = en.getId(); - r.newlines = 0; - r.addDesc(en); - vDesc.addElement(r); - int newElevation = 0; - IHex fallHex = game.getBoard().getHex(crashPos); - - //May land on roof of building or bridge - if(fallHex.containsTerrain(Terrains.BLDG_ELEV)) - newElevation = fallHex.terrainLevel(Terrains.BLDG_ELEV); - else if(fallHex.containsTerrain(Terrains.BRIDGE_ELEV)) { - newElevation = fallHex.terrainLevel(Terrains.BRIDGE_ELEV); - if(newElevation > crashElevation) - newElevation = 0; //vtol was under bridge already - } - - int fall = crashElevation - newElevation; - if(fall==0) { - //already on ground, no harm done - r = new Report(6265); - r.subject = en.getId(); - vDesc.addElement(r); - } else { - //set elevation 1st to avoid multiple crashes - en.setElevation(newElevation); - - //plummets to ground - r = new Report(6270); - r.subject = en.getId(); - r.add(fall); - vDesc.addElement(r); - - // facing after fall - String side; - int table; - int facing = Compute.d6(); - switch(facing) { - case 1: - case 2: - side = "right side"; - table = ToHitData.SIDE_RIGHT; - break; - case 3: - side = "rear"; - table = ToHitData.SIDE_REAR; - break; - case 4: - case 5: - side = "left side"; - table = ToHitData.SIDE_LEFT; - break; - case 0: - default: - side = "front"; - table = ToHitData.SIDE_FRONT; - } - - if(newElevation <= 0) { - boolean waterFall= fallHex.containsTerrain(Terrains.WATER); - if(waterFall && fallHex.containsTerrain(Terrains.ICE)) { - int roll = Compute.d6(1); - r = new Report(2118); - r.subject = en.getId(); - r.add(en.getDisplayName(), true); - r.add(roll); - r.subject = en.getId(); - addReport(r); - if(roll == 6) { - resolveIceBroken(crashPos); - } else { - waterFall = false; //saved by ice - } - } - if(waterFall) { - //falls into water and is destroyed - r = new Report(6275); - r.subject = en.getId(); - vDesc.addElement(r); - en.destroy("Fell into water",false, false);//not sure, is this salvagable? - } - } - - // calculate damage for hitting the surface - int damage = (int)Math.round(en.getWeight() / 10.0) * (fall + 1); - - // adjust damage for gravity - damage = Math.round(damage * game.getOptions().floatOption("gravity")); - // report falling - r = new Report(6280); - r.subject = en.getId(); - r.indent(); - r.addDesc(en); - r.add(side); - r.add(damage); - r.newlines = 0; - vDesc.addElement(r); - - en.setFacing((en.getFacing() + (facing - 1)) % 6); - - boolean exploded=false; - - // standard damage loop - while (damage > 0) { - int cluster = Math.min(5, damage); - HitData hit = en.rollHitLocation(ToHitData.HIT_NORMAL, table); - int ISBefore[]={en.getInternal(Tank.LOC_FRONT), en.getInternal(Tank.LOC_RIGHT), en.getInternal(Tank.LOC_LEFT), en.getInternal(Tank.LOC_REAR)};//hack? - vDesc.addAll( - damageEntity(en, hit, cluster)); - int ISAfter[]={en.getInternal(Tank.LOC_FRONT), en.getInternal(Tank.LOC_RIGHT), en.getInternal(Tank.LOC_LEFT), en.getInternal(Tank.LOC_REAR)}; - for(int x=0;x<=3;x++) { - if(ISBefore[x]!=ISAfter[x]) { - exploded=true; - } - } - damage -= cluster; - } - if (exploded) { - r = new Report(6285); - r.subject = en.getId(); - r.addDesc(en); - vDesc.addElement(r); - vDesc.addAll( explodeVTOL(en)); - } - - //check for location exposure - doSetLocationsExposure(en, fallHex, false, newElevation); - - } - } else { - en.setElevation(0);//considered landed in the hex. - //crashes into ground thanks to sideslip - r = new Report(6290); - r.subject = en.getId(); - r.addDesc(en); - vDesc.addElement(r); - int damage = (int)Math.round(en.getWeight() / 10.0) * (hexesMoved + 1); - boolean exploded=false; - - // standard damage loop - while (damage > 0) { - int cluster = Math.min(5, damage); - HitData hit = en.rollHitLocation(ToHitData.HIT_NORMAL, impactSide); - int ISBefore[]={en.getInternal(Tank.LOC_FRONT), en.getInternal(Tank.LOC_RIGHT), en.getInternal(Tank.LOC_LEFT), en.getInternal(Tank.LOC_REAR)};//hack? - vDesc.addAll( damageEntity(en, hit, cluster)); - int ISAfter[]={en.getInternal(Tank.LOC_FRONT), en.getInternal(Tank.LOC_RIGHT), en.getInternal(Tank.LOC_LEFT), en.getInternal(Tank.LOC_REAR)}; - for(int x=0;x<=3;x++) { - if(ISBefore[x]!=ISAfter[x]) { - exploded=true; - } - } - damage -= cluster; - } - if(exploded) { - r = new Report(6295); - r.subject = en.getId(); - r.addDesc(en); - vDesc.addElement(r); - vDesc.addAll( explodeVTOL(en)); - } - - } - return vDesc; - - } - - /** - * Explode a VTOL - * @param en The VTOL to explode. - * @return a Vector of reports - */ - private Vector explodeVTOL(VTOL en) { - Vector vDesc = new Vector(); - Report r; - - if(en.getEngine().isFusion()) { - //fusion engine, no effect - r = new Report(6300); - r.subject = en.getId(); - vDesc.addElement(r); - } else { - Coords pos=en.getPosition(); - IHex hex = game.getBoard().getHex(pos); - if(hex.containsTerrain(Terrains.WOODS) || hex.containsTerrain(Terrains.JUNGLE)) { - hex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - } else { - game.getBoard().addInfernoTo(pos, InfernoTracker.STANDARD_ROUND, 1); - ((InfernoTracker)(game.getBoard().getInfernos().get(pos))).setTurnsLeftToBurn(game.getBoard().getInfernoBurnTurns(pos)-game.getBoard().getInfernoIVBurnTurns(pos)-2); //massive hack - } - } - - return vDesc; - } - - /** - * Rolls and resolves critical hits on mechs or vehicles. - * if rollNumber is false, a single hit is applied - needed for - * MaxTech Heat Scale rule. - */ - private Vector criticalEntity(Entity en, int loc, int critMod, boolean rollNumber) { - CriticalSlot slot = null; - Vector vDesc = new Vector(); - Report r; - Coords coords = en.getPosition(); - IHex hex = null; - int hits; - if (rollNumber) { - if (null != coords) hex = game.getBoard().getHex(coords); - r = new Report(6305); - r.subject = en.getId(); - r.indent(2); - r.add(en.getLocationAbbr(loc)); - r.newlines = 0; - vDesc.addElement(r); - hits = 0; - int roll = Compute.d6(2); - r = new Report(6310); - r.subject = en.getId(); - String rollString = new String(); - if ( critMod != 0 ) { - rollString = "(" + roll; - if ( critMod > 0 ) { - rollString += "+"; - } - rollString += critMod + ") = "; - roll += critMod; - } - rollString += roll; - r.add(rollString); - r.newlines = 0; - vDesc.addElement(r); - if (roll <= 7) { - //no effect - r = new Report(6005); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - return vDesc; - } else if (roll >= 8 && roll <= 9) { - hits = 1; - r = new Report(6315); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - } else if (roll >= 10 && roll <= 11) { - hits = 2; - r = new Report(6320); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - } else if (roll == 12) { - if (en instanceof Tank || en instanceof Protomech) { - hits = 3; - r = new Report(6325); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - } else if (en.locationIsLeg(loc)) { - //limb blown off - r = new Report(6120); - r.subject = en.getId(); - r.add(en.getLocationName(loc)); - r.newlines = 0; - vDesc.addElement(r); - if (en.getInternal(loc) > 0) { - destroyLocation(en, loc); - } - if (null != hex) { - if (!hex.containsTerrain (Terrains.LEGS)) { - hex.addTerrain (Terrains.getTerrainFactory().createTerrain(Terrains.LEGS, 1)); - } - else { - hex.addTerrain (Terrains.getTerrainFactory().createTerrain - (Terrains.LEGS, - hex.terrainLevel(Terrains.LEGS)+1)); - } - } - sendChangedHex(en.getPosition()); - return vDesc; - } else if (loc == Mech.LOC_RARM || loc == Mech.LOC_LARM) { - //limb blown off - r = new Report(6120); - r.subject = en.getId(); - r.add(en.getLocationName(loc)); - r.newlines = 0; - vDesc.addElement(r); - destroyLocation(en, loc); - if (null != hex) { - if (!hex.containsTerrain( Terrains.ARMS)) { - hex.addTerrain (Terrains.getTerrainFactory().createTerrain(Terrains.ARMS, 1)); - } - else { - hex.addTerrain (Terrains.getTerrainFactory().createTerrain - (Terrains.ARMS, - hex.terrainLevel(Terrains.ARMS)+1)); - } - } - sendChangedHex(en.getPosition()); - return vDesc; - } else if (loc == Mech.LOC_HEAD) { - //head blown off - r = new Report(6330); - r.subject = en.getId(); - r.add(en.getLocationName(loc)); - r.newlines = 0; - vDesc.addElement(r); - destroyLocation(en, loc); - // Don't kill a pilot multiple times. - if ( Pilot.DEATH > en.getCrew().getHits() ) { - en.crew.setDoomed(true); - Report.addNewline(vDesc); - vDesc.addAll( destroyEntity(en, "pilot death", true)); - } - return vDesc; - } else { - // torso hit - hits = 3; - r = new Report(6325); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - } - } - } else { - hits = 1; - } - - // vehicle handle crits in their own 'special' way - if (en instanceof Tank) { - Tank tank = (Tank)en; - for (int x = 0; x < hits; x++) { - slot = new CriticalSlot( CriticalSlot.TYPE_SYSTEM, - Compute.d6(1) ); - vDesc.addAll( applyCriticalHit(en, Entity.NONE, slot, true)); - } - } - else { - // transfer criticals, if needed - while (hits > 0 && en.canTransferCriticals(loc) - && en.getTransferLocation(loc) != Entity.LOC_DESTROYED - && en.getTransferLocation(loc) != Entity.LOC_NONE) { - loc = en.getTransferLocation(loc); - r = new Report(6335); - r.subject = en.getId(); - r.indent(3); - r.add(en.getLocationAbbr(loc)); - r.newlines = 0; - vDesc.addElement(r); - } - - // Roll critical hits in this location. - while (hits > 0) { - - // Have we hit all available slots in this location? - if (en.getHittableCriticals(loc) <= 0) { - r = new Report(6340); - r.subject = en.getId(); - r.indent(3); - r.newlines = 0; - vDesc.addElement(r); - break; - } - - // Randomly pick a slot to be hit. - int slotIndex = Compute.randomInt - ( en.getNumberOfCriticals(loc) ); - slot = en.getCritical(loc, slotIndex); - - // Ignore empty or unhitable slots (this - // includes all previously hit slots). - - if (slot != null && slot.isHittable()) { - // if explosive use edge - if ((en instanceof Mech) - && ( en.crew.hasEdgeRemaining() - && en.crew.getOptions().booleanOption("edge_when_explosion")) - && en.getEquipment(slot.getIndex()).getType().isExplosive()) { - en.crew.decreaseEdge(); - r = new Report(6530); - r.subject = en.getId(); - r.indent(3); - r.newlines = 0; - r.add(en.crew.getOptions().intOption("edge")); - vDesc.addElement(r); - continue; - } - vDesc.addAll( applyCriticalHit(en, loc, slot, true)); - hits--; - } - - } // Hit another slot in this location. - } - - return vDesc; - } - - /** - * Checks for location breach and returns phase logging. - *

- * Please note that dependent locations ARE NOT considered breached! - * - * @param entity the Entity that needs to be checked. - * @param loc the int location on the entity that needs - * to be checked for a breach. - * @param hex the IHex the enitity occupies when checking - * This value will be null if the check is the - * result of an attack, and non-null if it occurs during movement. - */ - private Vector breachCheck(Entity entity, int loc, IHex hex) { - Vector vDesc = new Vector(); - Report r; - - // BattleArmor does not breach - if (entity instanceof Infantry) { - return vDesc; - } - - if (entity instanceof VTOL) { - return vDesc; - } - - // functional HarJel prevents breach - if (entity instanceof Mech && ((Mech)entity).hasHarJelIn(loc)) { - r = new Report(6342); - r.subject = entity.getId(); - r.indent(3); - vDesc.addElement(r); - return vDesc; - } - - // This handles both water and vacuum breaches. - if (entity.getLocationStatus(loc) > ILocationExposureStatus.NORMAL) { - // Does the location have armor (check rear armor on Mek) - // and is the check due to damage? - int breachroll = 0; - if (entity.getArmor(loc) > 0 && - (entity instanceof Mech ? (entity.getArmor(loc,true)>0) : true) - && null == hex) { - breachroll = Compute.d6(2); - r = new Report(6345); - r.subject = entity.getId(); - r.indent(3); - r.add(entity.getLocationAbbr(loc)); - r.add(breachroll); - r.newlines = 0; - vDesc.addElement(r); - } - // Breach by damage or lack of armor. - if ( breachroll >= 10 - || !(entity.getArmor(loc) > 0) - || !(entity instanceof Mech ? (entity.getArmor(loc,true)>0) : - true) ) { - vDesc.addAll( breachLocation(entity, loc, hex, false)); - } - } - return vDesc; - } - - /** - * Marks all equipment in a location on an entity as useless. - * - * @param entity the Entity that needs to be checked. - * @param loc the int location on the entity that needs - * to be checked for a breach. - * @param hex the IHex the enitity occupies when checking - * This value will be null if the check is the - * result of an attack, and non-null if it occurs during movement. - * @param harJel a boolean value indicating if the uselessness - * is the cause of a critically hit HarJel system - */ - private Vector breachLocation(Entity entity, int loc, IHex hex, boolean harJel) { - Vector vDesc = new Vector(); - Report r; - - if (entity.getInternal(loc) < 0 || - entity.getLocationStatus(loc) < ILocationExposureStatus.NORMAL) { - //already destroyed or breached? don't bother - return vDesc; - } - - r = new Report(6350); - if (harJel) r.messageId = 6351; - r.subject = entity.getId(); - r.add(entity.getShortName()); - r.add(entity.getLocationAbbr(loc)); - r.newlines = 0; - vDesc.addElement(r); - - if (entity instanceof Tank) { - vDesc.addAll( - destroyEntity(entity, "hull breach", true, true)); - return vDesc; - } - // equipment and crits will be marked in applyDamage? - - // equipment marked missing - for (Enumeration i = entity.getEquipment(); i.hasMoreElements();) { - Mounted mounted = (Mounted)i.nextElement(); - if (mounted.getLocation() == loc) { - mounted.setBreached(true); - } - } - // all critical slots set as useless - for (int i = 0; i < entity.getNumberOfCriticals(loc); i++) { - final CriticalSlot cs = entity.getCritical(loc, i); - if (cs != null) { - // for every undamaged actuator destroyed by breaching, - // we make a PSR (see bug 1040858) - if (entity.locationIsLeg(loc)) { - if (cs.isHittable()) { - switch(cs.getIndex()) { - case Mech.ACTUATOR_UPPER_LEG : - case Mech.ACTUATOR_LOWER_LEG : - case Mech.ACTUATOR_FOOT : - // leg/foot actuator piloting roll - game.addPSR( new PilotingRollData - (entity.getId(), 1, "leg/foot actuator hit") ); - break; - case Mech.ACTUATOR_HIP : - // hip piloting roll (at +0, because we get the +2 - // anyway because the location is breached - // phase report will look a bit weird, but the roll - // is correct - game.addPSR( new PilotingRollData - (entity.getId(), 0, "hip actuator hit") ); - break; - } - } - } - cs.setBreached(true); - } - } - - //Check location for engine/cockpit breach and report accordingly - if (loc == Mech.LOC_CT) { - vDesc.addAll( destroyEntity(entity, "hull breach")); - if (game.getOptions().booleanOption("auto_abandon_unit")) { - vDesc.addAll(abandonEntity(entity)); - } - } - if (loc == Mech.LOC_HEAD) { - entity.crew.setDoomed(true); - vDesc.addAll( destroyEntity(entity, "hull breach")); - if (entity.getLocationStatus(loc) == ILocationExposureStatus.WET) { - r = new Report(6355); - r.subject = entity.getId(); - r.addDesc(entity); - vDesc.addElement(r); - } else { - r = new Report(6360); - r.subject = entity.getId(); - r.addDesc(entity); - vDesc.addElement(r); - } - } - - // Set the status of the location. - // N.B. if we set the status before rolling water PSRs, we get a - // "LEG DESTROYED" modifier; setting the status after gives a hip - // actuator modifier. - entity.setLocationStatus(loc, ILocationExposureStatus.BREACHED); - - // Did the hull breach destroy the engine? - if (entity.getHitCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_ENGINE, - Mech.LOC_LT) + - entity.getHitCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_ENGINE, - Mech.LOC_CT) + - entity.getHitCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_ENGINE, - Mech.LOC_RT) - >= 3) { - vDesc.addAll( destroyEntity(entity, "engine destruction")); - if (game.getOptions().booleanOption("auto_abandon_unit")) { - vDesc.addAll(abandonEntity(entity)); - } - } - - return vDesc; - } - - /** - * Marks all equipment in a location on an entity as destroyed. - */ - void destroyLocation(Entity en, int loc) { - // if it's already marked as destroyed, don't bother - if (en.getInternal(loc) < 0) { - return; - } - // mark armor, internal as doomed - en.setArmor(IArmorState.ARMOR_DOOMED, loc, false); - en.setInternal(IArmorState.ARMOR_DOOMED, loc); - if (en.hasRearArmor(loc)) { - en.setArmor(IArmorState.ARMOR_DOOMED, loc, true); - } - // equipment marked missing - for (Enumeration i = en.getEquipment(); i.hasMoreElements();) { - Mounted mounted = (Mounted)i.nextElement(); - if (mounted.getLocation() == loc) { - mounted.setMissing(true); - } - } - // all critical slots set as missing - for (int i = 0; i < en.getNumberOfCriticals(loc); i++) { - final CriticalSlot cs = en.getCritical(loc, i); - if (cs != null) { - // count engine hits for maxtech engine explosions - if (cs.getType() == CriticalSlot.TYPE_SYSTEM && - cs.getIndex() == Mech.SYSTEM_ENGINE && - !cs.isDamaged()) { - en.engineHitsThisRound++; - } - cs.setMissing(true); - } - } - // if it's a leg, the entity falls - if (en instanceof Mech && en.locationIsLeg(loc)) { - game.addPSR(new PilotingRollData(en.getId(), PilotingRollData.AUTOMATIC_FAIL, 5, "leg destroyed")); - } - // dependent locations destroyed - if (en.getDependentLocation(loc) != Entity.LOC_NONE) { - destroyLocation(en, en.getDependentLocation(loc)); - } - } - - /** - * Mark the unit as destroyed! Units transported in the destroyed unit - * will get a chance to escape. - * - * @param entity - the Entity that has been destroyed. - * @param reason - a String detailing why the entity - * was destroyed. - * @return a Vector of Report objects - * that can be sent to the output log. - */ - private Vector destroyEntity(Entity entity, String reason) { - return destroyEntity( entity, reason, true ); - } - - /** - * Marks a unit as destroyed! Units transported inside the destroyed - * unit will get a chance to escape unless the destruction was not - * survivable. - * - * @param entity - the Entity that has been destroyed. - * @param reason - a String detailing why the entity - * was destroyed. - * @param survivable - a boolean that identifies the - * desctruction as unsurvivable for transported units. - * @return a Vector of Report objects - * that can be sent to the output log. - */ - private Vector destroyEntity(Entity entity, String reason, - boolean survivable) { - // Generally, the entity can still be salvaged. - return this.destroyEntity( entity, reason, survivable, true ); - } - - /** - * Marks a unit as destroyed! Units transported inside the destroyed - * unit will get a chance to escape unless the destruction was not - * survivable. - * - * @param entity - the Entity that has been destroyed. - * @param reason - a String detailing why the entity - * was destroyed. - * @param survivable - a boolean that identifies the - * desctruction as unsurvivable for transported units. - * @param canSalvage - a boolean that indicates if - * the unit can be salvaged (or cannibalized for spare parts). - * If true, salvage operations are possible, if - * false, the unit is too badly damaged. - * @return a Vector of Report objects - * that can be sent to the output log. - */ - private Vector destroyEntity(Entity entity, String reason, - boolean survivable, boolean canSalvage) { - Vector vDesc = new Vector(); - Report r; - - // The unit can suffer an ammo explosion after it has been destroyed. - int condition = IEntityRemovalConditions.REMOVE_SALVAGEABLE; - if ( !canSalvage ) { - entity.setSalvage( canSalvage ); - condition = IEntityRemovalConditions.REMOVE_DEVASTATED; - } - - // Destroy the entity, unless it's already destroyed. - if (!entity.isDoomed() && !entity.isDestroyed()) { - r = new Report(6365); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(reason); - r.newlines=0; - vDesc.addElement(r); - - entity.setDoomed(true); - - // Kill any picked up MechWarriors - Enumeration iter = entity.getPickedUpMechWarriors().elements(); - while (iter.hasMoreElements() ) { - Integer mechWarriorId = (Integer)iter.nextElement(); - Entity mw = game.getEntity(mechWarriorId.intValue()); - mw.setDestroyed(true); - game.removeEntity( mw.getId(), condition ); - this.entityUpdate(mw.getId()); - send( createRemoveEntityPacket(mw.getId(), condition) ); - r = new Report(6370); - r.subject = mw.getId(); - r.addDesc(mw); - vDesc.addElement(r); - } - - // Handle escape of transported units. - iter = entity.getLoadedUnits().elements(); - if ( iter.hasMoreElements() ) { - Entity other = null; - Coords curPos = entity.getPosition(); - IHex entityHex = game.getBoard().getHex( curPos ); - int curFacing = entity.getFacing(); - while ( iter.hasMoreElements() ) { - other = (Entity) iter.nextElement(); - - // Can the other unit survive? - if ( !survivable ) { - - // Nope. - other.setDestroyed(true); - game.moveToGraveyard( other.getId() ); - this.entityUpdate(other.getId()); - send( createRemoveEntityPacket(other.getId(), - condition) ); - r = new Report(6370); - r.subject = other.getId(); - r.addDesc(other); - vDesc.addElement(r); - } - // Can we unload the unit to the current hex? - // TODO : unloading into stacking violation is not - // explicitly prohibited in the BMRr. - else if (null != Compute.stackingViolation(game, other.getId(), curPos) - || other.isHexProhibited(entityHex) ) { - // Nope. - other.setDestroyed(true); - game.moveToGraveyard( other.getId() ); - this.entityUpdate(other.getId()); - send( createRemoveEntityPacket(other.getId(), - condition) ); - r = new Report(6375); - r.subject = other.getId(); - r.addDesc(other); - vDesc.addElement(r); - } // End can-not-unload - else { - // The other unit survives. - this.unloadUnit( entity, other, curPos, curFacing, entity.getElevation() ); - } - - } // Handle the next transported unit. - - } // End has-transported-unit - - // Handle transporting unit. - if ( Entity.NONE != entity.getTransportId() ) { - final Entity transport = game.getEntity - ( entity.getTransportId() ); - Coords curPos = transport.getPosition(); - int curFacing = transport.getFacing(); - this.unloadUnit( transport, entity, curPos, curFacing, transport.getElevation() ); - this.entityUpdate( transport.getId() ); - } // End unit-is-transported - - // Is this unit being swarmed? - final int swarmerId = entity.getSwarmAttackerId(); - if ( Entity.NONE != swarmerId ) { - final Entity swarmer = game.getEntity( swarmerId ); - - // remove the swarmer from the move queue - game.removeTurnFor(swarmer); - send(createTurnVectorPacket()); - - swarmer.setSwarmTargetId( Entity.NONE ); - entity.setSwarmAttackerId( Entity.NONE ); - r = new Report(6380); - r.subject = swarmerId; - r.addDesc(swarmer); - vDesc.addElement(r); - this.entityUpdate( swarmerId ); - } - - // Is this unit swarming somebody? - final int swarmedId = entity.getSwarmTargetId(); - if ( Entity.NONE != swarmedId ) { - final Entity swarmed = game.getEntity( swarmedId ); - swarmed.setSwarmAttackerId( Entity.NONE ); - entity.setSwarmTargetId( Entity.NONE ); - r = new Report(6385); - r.subject = swarmed.getId(); - r.addDesc(swarmed); - vDesc.addElement(r); - this.entityUpdate( swarmedId ); - } - - } // End entity-not-already-destroyed. - - // update our entity, so clients have correct data - // needed for MekWars stuff - this.entityUpdate(entity.getId()); - - return vDesc; - } - - - /** - * Makes a piece of equipment on a mech explode! POW! This expects either - * ammo, or an explosive weapon. Returns a vector of Report objects. - */ - private Vector explodeEquipment(Entity en, int loc, int slot) { - return explodeEquipment(en, loc, en.getEquipment(en.getCritical(loc, slot).getIndex())); - } - - private Vector explodeEquipment(Entity en, int loc, Mounted mounted) { - Vector vDesc = new Vector(); - // is this already destroyed? - if (mounted.isDestroyed()) { - System.err.println("server: explodeEquipment called on destroyed" - + " equipment (" + mounted.getName() + ")"); - return vDesc; - } - - // special-case. RACs only explode when jammed - if (mounted.getType() instanceof WeaponType && - ((WeaponType)mounted.getType()).getAmmoType() == AmmoType.T_AC_ROTARY) { - if (!mounted.isJammed()) { - return vDesc; - } - } - - // special case. ACs only explode when firing incendiary ammo - if (mounted.getType() instanceof WeaponType && - ((WeaponType)mounted.getType()).getAmmoType() == AmmoType.T_AC) { - if (!mounted.isUsedThisRound()) { - return vDesc; - } - Mounted ammo = mounted.getLinked(); - if(ammo == null || !(ammo.getType() instanceof AmmoType) || - ((AmmoType)ammo.getType()).getMunitionType() != AmmoType.M_INCENDIARY_AC ) { - return vDesc; - } - - WeaponType wtype = (WeaponType)mounted.getType(); - if ( ((wtype.getAmmoType() == AmmoType.T_LRM) || - (wtype.getAmmoType() == AmmoType.T_LRM_STREAK) || - (wtype.getAmmoType() == AmmoType.T_LRM_TORPEDO) || - (wtype.getAmmoType() == AmmoType.T_LRM_TORPEDO_COMBO))){ - return vDesc; - } - - } - - // Inferno ammo causes heat buildup as well as the damage - if (mounted.getType() instanceof AmmoType - && ((((AmmoType)mounted.getType()).getAmmoType() == AmmoType.T_SRM) - || (((AmmoType)mounted.getType()).getAmmoType() == AmmoType.T_BA_INFERNO)) - && ((AmmoType)mounted.getType()).getMunitionType() == AmmoType.M_INFERNO - && mounted.getShotsLeft() > 0) { - en.heatBuildup += 30; - } - - // determine and deal damage - int damage = mounted.getExplosionDamage(); - - if (damage <= 0) { - return vDesc; - } - - Report r = new Report(6390); - r.subject = en.getId(); - r.add(mounted.getName()); - r.add(damage); - r.indent(3); - r.newlines = 0; - vDesc.addElement(r); - mounted.setShotsLeft(0); - vDesc.addAll( damageEntity(en, new HitData(loc), damage, true)); - Report.addNewline(vDesc); - - - int pilotDamage = 2; - if (en.getCrew().getOptions().booleanOption("pain_resistance")) pilotDamage = 1; - if (en.getCrew().getOptions().booleanOption("iron_man")) pilotDamage = 1; - vDesc.addAll( damageCrew(en, pilotDamage)); - if ( en.crew.isDoomed() || en.crew.isDead() ) { - vDesc.addAll( destroyEntity(en, "crew death", true) ); - } else { - Report.addNewline(vDesc); - } - - return vDesc; - } - - /** - * Makes one slot of ammo, determined by certain rules, explode on a mech. - */ - private Vector explodeAmmoFromHeat(Entity entity) { - int damage = 0; - int rack = 0; - int boomloc = -1; - int boomslot = -1; - Vector vDesc = new Vector(); - - for (int j = 0; j < entity.locations(); j++) { - for (int k = 0; k < entity.getNumberOfCriticals(j); k++) { - CriticalSlot cs = entity.getCritical(j, k); - if (cs == null || cs.isDestroyed() || cs.isHit() || cs.getType() != CriticalSlot.TYPE_EQUIPMENT) { - continue; - } - Mounted mounted = entity.getEquipment(entity.getCritical(j, k).getIndex()); - if (!(mounted.getType() instanceof AmmoType)) { - continue; - } - AmmoType atype = (AmmoType)mounted.getType(); - if (!atype.isExplosive()) { - continue; - } - //ignore empty bins - if (atype.getShots() == 0) { - continue; - } - // BMRr, pg. 48, compare one rack's - // damage. Ties go to most rounds. - int newRack = atype.getDamagePerShot() * atype.getRackSize(); - int newDamage = mounted.getExplosionDamage(); - if ( !mounted.isHit() && ( rack < newRack || - (rack == newRack && damage < newDamage) ) ) { - rack = newRack; - damage = newDamage; - boomloc = j; - boomslot = k; - } - } - } - if (boomloc != -1 && boomslot != -1) { - CriticalSlot slot = entity.getCritical(boomloc, boomslot); - slot.setHit(true); - entity.getEquipment(slot.getIndex()).setHit(true); - vDesc = explodeEquipment(entity, boomloc, boomslot); - } else { - //Luckily, there is no ammo to explode. - Report r = new Report(5105); - r.subject = entity.getId(); - r.indent(); - vDesc.addElement(r); - } - return vDesc; - } - - /** - * Makes a mech fall. - */ - private void doEntityFall(Entity entity, Coords fallPos, int height, int facing, PilotingRollData roll) { - Report r; - - IHex fallHex = game.getBoard().getHex(fallPos); - - // we don't need to deal damage yet, if the entity is doing DFA - if (entity.isMakingDfa()) { - r = new Report(2305); - r.subject = entity.getId(); - addReport(r); - entity.setProne(true); - return; - } - // facing after fall - String side; - int table; - switch(facing) { - case 1: - case 2: - side = "right side"; - table = ToHitData.SIDE_RIGHT; - break; - case 3: - side = "rear"; - table = ToHitData.SIDE_REAR; - break; - case 4: - case 5: - side = "left side"; - table = ToHitData.SIDE_LEFT; - break; - case 0: - default: - side = "front"; - table = ToHitData.SIDE_FRONT; - } - - int waterDepth = fallHex.terrainLevel(Terrains.WATER); - int damageHeight = height; - - - // HACK: if the dest hex is water, assume that the fall height given is - // to the floor of the hex, and modifiy it so that it's to the surface - if (waterDepth > 0) { - damageHeight = height - waterDepth; - } else { - waterDepth = 0; //because it will be used to set elevation - } - - if(fallHex.containsTerrain(Terrains.ICE)) { - waterDepth = 0; - } - - //Falling into water instantly destroys most non-mechs - if(waterDepth > 0 - && !(entity instanceof Mech) - && !(entity instanceof Protomech) - && (entity.getRunMP() > 0 && entity.getMovementMode() != IEntityMovementMode.HOVER) - && entity.getMovementMode() != IEntityMovementMode.HYDROFOIL - && entity.getMovementMode() != IEntityMovementMode.NAVAL - && entity.getMovementMode() != IEntityMovementMode.SUBMARINE) { - addReport( - destroyEntity(entity, "a watery grave", false)); - return; - } - - // calculate damage for hitting the surface - int damage = (int)Math.round(entity.getWeight() / 10.0) * (damageHeight + 1); - // calculate damage for hitting the ground, but only if we actually fell - // into water - // if we fell onto the water surface, that damage is halved. - int waterDamage = 0; - if (waterDepth > 0) { - damage /= 2; - waterDamage = (int)Math.round(entity.getWeight() / 10.0) * (waterDepth + 1) /2; - } - - // If the waterDepth is larger than the fall height, - // we fell underwater - if (waterDepth > height) { - damage = 0; - waterDamage = (int)Math.round(entity.getWeight() / 10.0) * (height + 1) /2; - } - // adjust damage for gravity - damage = Math.round(damage * game.getOptions().floatOption("gravity")); - waterDamage = Math.round(waterDamage * game.getOptions().floatOption("gravity")); - - // report falling - if (waterDamage == 0) { - r = new Report(2310); - r.subject = entity.getId(); - r.indent(); - r.newlines = 0; - r.addDesc(entity); - r.add(side); //international issue - r.add(damage); - } else if (damage > 0) { - r = new Report(2315); - r.subject = entity.getId(); - r.indent(); - r.newlines = 0; - r.addDesc(entity); - r.add(side); //international issue - r.add(damage); - r.add(waterDamage); - } else { - r = new Report(2310); - r.subject = entity.getId(); - r.indent(); - r.newlines = 0; - r.addDesc(entity); - r.add(side); //international issue - r.add(waterDamage); - } - addReport(r); - damage += waterDamage; - - // Any swarming infantry will be dislodged, but we don't want to - // interrupt the fall's report. We have to get the ID now because - // the fall may kill the entity which will reset the attacker ID. - final int swarmerId = entity.getSwarmAttackerId(); - - // Positioning must be prior to damage for proper handling of breaches - // Only Mechs can fall prone. - if ( entity instanceof Mech ) { - entity.setProne(true); - } - entity.setPosition(fallPos); - entity.setFacing((entity.getFacing() + (facing - 1)) % 6); - entity.setSecondaryFacing(entity.getFacing()); - entity.setElevation(-waterDepth); - if (waterDepth > 0) { - for (int loop=0; loop< entity.locations();loop++){ - entity.setLocationStatus(loop, ILocationExposureStatus.WET); - } - } - - // standard damage loop - while (damage > 0) { - int cluster = Math.min(5, damage); - HitData hit = entity.rollHitLocation(ToHitData.HIT_NORMAL, table); - hit.makeFallDamage(true); - addReport( damageEntity(entity, hit, cluster)); - damage -= cluster; - } - - //check for location exposure - doSetLocationsExposure(entity, fallHex, false, -waterDepth); - - // we want to be able to avoid pilot damage even when it was - // an automatic fall, only unconsciousness should cause auto-damage - roll.removeAutos(); - - if (height > 0) { - roll.addModifier(height, "height of fall"); - } - - entity.addPilotingModifierForTerrain(roll, fallPos); - - if (roll.getValue() == PilotingRollData.IMPOSSIBLE) { - r = new Report(2320); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(entity.crew.getName()); - r.indent(); - addReport(r); - addReport( damageCrew(entity, 1)); - ((Report) vPhaseReport.elementAt(vPhaseReport.size() - 1)).newlines++; - } else { - int diceRoll = Compute.d6(2); - r = new Report(2325); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(entity.crew.getName()); - r.add(roll.getValueAsString()); - r.add(diceRoll); - if (diceRoll >= roll.getValue()) { - r.choose(true); - addReport(r); - } else { - r.choose(false); - addReport(r); - addReport( damageCrew(entity, 1)); - ((Report) vPhaseReport.elementAt(vPhaseReport.size() - 1)).newlines++; - } - } - - // Now dislodge any swarming infantry. - if ( Entity.NONE != swarmerId ) { - final Entity swarmer = game.getEntity( swarmerId ); - entity.setSwarmAttackerId( Entity.NONE ); - swarmer.setSwarmTargetId( Entity.NONE ); - // Did the infantry fall into water? - if ( waterDepth > 0 ) { - // Swarming infantry die. - swarmer.setPosition( fallPos ); - r = new Report(2330); - r.newlines = 0; - r.subject = swarmer.getId(); - r.addDesc(swarmer); - addReport(r); - addReport( destroyEntity(swarmer, "a watery grave", false)); - } else { - // Swarming infantry take an 11 point hit. - // ASSUMPTION : damage should not be doubled. - r = new Report(2335); - r.newlines = 0; - r.subject = swarmer.getId(); - r.addDesc(swarmer); - addReport(r); - addReport( damageEntity(swarmer, swarmer.rollHitLocation(ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT), 11)); - ((Report) vPhaseReport.elementAt(vPhaseReport.size() - 1)).newlines++; - } - swarmer.setPosition( fallPos ); - entityUpdate( swarmerId ); - } // End dislodge-infantry - - // clear all PSRs after a fall -- the Mek has already failed ONE and fallen, it'd be cruel to make it fail some more! - game.resetPSRs(entity); - } - - /** - * The mech falls into an unoccupied hex from the given height above - */ - private void doEntityFall(Entity entity, Coords fallPos, int height, PilotingRollData roll) { - doEntityFall(entity, fallPos, height, Compute.d6(1), roll); - } - - /** - * The mech falls down in place - */ - private void doEntityFall(Entity entity, PilotingRollData roll) { - doEntityFall(entity, entity.getPosition(), 0, roll); - } - - /** - * Report: - * - Any ammo dumps beginning the following round. - * - Any ammo dumps that have ended with the end of this round. - */ - private void resolveAmmoDumps() { - Report r; - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - Entity entity = (Entity)i.nextElement(); - for (Enumeration j = entity.getAmmo(); j.hasMoreElements(); ) { - Mounted m = (Mounted)j.nextElement(); - if (m.isPendingDump()) { - //report dumping next round - r = new Report(5110); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(m.getName()); - addReport(r); - //update status - m.setPendingDump(false); - m.setDumping(true); - } - else if (m.isDumping()) { - //report finished dumping - r = new Report(5115); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(m.getName()); - addReport(r); - //update status - m.setDumping(false); - m.setShotsLeft(0); - } - } - entity.reloadEmptyWeapons(); - } - } - - /** - * Returns true if the hex is set on fire with the specified roll. Of - * course, also checks to see that fire is possible in the specified hex. - * - * @param hex - the IHex to be lit. - * @param roll - the int target number for the ignition roll - * @param bAnyTerrain - true if the fire can be lit in any - * terrain. If this value is false the hex will be - * lit only if it contains Woods,jungle or a Building. - * @param entityId - the entityId responsible for the ignite attempt. - * If the value is Entity.NONE, then the roll attempt will not - * be included in the report. - */ - public boolean ignite( IHex hex, int roll, boolean bAnyTerrain, - int entityId ) { - - // The hex might be null due to spreadFire translation - // goes outside of the board limit. - if ( !game.getOptions().booleanOption("fire") || null == hex ) { - return false; - } - - // The hex may already be on fire. - if ( hex.containsTerrain( Terrains.FIRE ) ) { - return true; - } - - if ( !bAnyTerrain && - !(hex.containsTerrain(Terrains.WOODS)) && - !(hex.containsTerrain(Terrains.JUNGLE)) && - !(hex.containsTerrain(Terrains.BUILDING)) ) { - return false; - } - - int fireRoll = Compute.d6(2); - if (entityId != Entity.NONE) { - Report r = new Report(3430); - r.indent(3); - r.subject = entityId; - r.add(roll); - r.add(fireRoll); - addReport(r); - } - if (fireRoll >= roll) { - hex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - return true; - } else { - return false; - } - } - - /** - * Returns true if the hex is set on fire with the specified roll. Of - * course, also checks to see that fire is possible in the specified hex. - * This version of the method will not report the attempt roll. - * - * @param hex - the IHex to be lit. - * @param roll - the int target number for the ignition roll - * @param bAnyTerrain - true if the fire can be lit in any - * terrain. If this value is false the hex will be - * lit only if it contains Woods, jungle or a Building. - */ - public boolean ignite(IHex hex, int roll, boolean bAnyTerrain) { - return ignite(hex, roll, bAnyTerrain, Entity.NONE); - } - - public boolean ignite(IHex hex, int roll) { - // default signature, assuming only woods can burn - return ignite(hex, roll, false, Entity.NONE); - } - - public void removeFire(int x, int y, IHex hex) { - Coords fireCoords = new Coords(x, y); - hex.removeTerrain(Terrains.FIRE); - sendChangedHex(fireCoords); - if (!game.getOptions().booleanOption("maxtech_fire")) { - // only remove the 3 smoke hexes if under L2 rules! - int windDir = game.getWindDirection(); - removeSmoke(x, y, windDir); - removeSmoke(x, y, (windDir + 1) % 6); - removeSmoke(x, y, (windDir + 5) % 6); - } - //fire goes out due to lack of fuel - Report r = new Report(5170, Report.PUBLIC); - r.add(fireCoords.getBoardNum()); - addReport(r); - } - - /** - * called when a fire is burning. Adds smoke to hex in the direction - * specified. Called 3 times per fire hex - * @param x The int x-coordinate of the hex - * @param y The int y-coordinate of the hex - * @param windDir The int specifying the winddirection - */ - public void addSmoke(int x, int y, int windDir) { - Coords smokeCoords = new Coords(Coords.xInDir(x, y, windDir), Coords.yInDir(x, y, windDir)); - IHex nextHex = game.getBoard().getHex(smokeCoords); - if (nextHex != null && !(nextHex.containsTerrain(Terrains.SMOKE))) { - nextHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.SMOKE, 1)); - sendChangedHex(smokeCoords); - Report r = new Report(5175, Report.PUBLIC); - r.add(smokeCoords.getBoardNum()); - addReport(r); - } - } - - /** - * Add lvl3 smoke to the hex specified by the parameters. Called once. - * @param x The int x-coordinate of the hex - * @param y The int y-coordinate of the hex - */ - public void addL3Smoke(int x, int y) { - IBoard board = game.getBoard(); - Coords smokeCoords = new Coords(x, y); - IHex smokeHex = game.getBoard().getHex(smokeCoords); - boolean infernoBurning = board.isInfernoBurning( smokeCoords ); - Report r; - if (smokeHex == null) { - return; - } - // Have to check if it's inferno smoke or from a heavy/hardened building - heavy smoke from those - if (infernoBurning || Building.MEDIUM < smokeHex.terrainLevel(Terrains.BUILDING)) { - if (smokeHex.terrainLevel(Terrains.SMOKE) == 2){ - //heavy smoke fills hex - r = new Report(5180, Report.PUBLIC); - r.add(smokeCoords.getBoardNum()); - addReport(r); - } else { - if (smokeHex.terrainLevel(Terrains.SMOKE) == 1){ - //heavy smoke overrides light - smokeHex.removeTerrain(Terrains.SMOKE); - } - smokeHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.SMOKE, 2)); - sendChangedHex(smokeCoords); - r = new Report(5185, Report.PUBLIC); - r.add(smokeCoords.getBoardNum()); - addReport(r); - } - } else { - if (smokeHex.terrainLevel(Terrains.SMOKE) == 2){ - //heavy smoke overpowers light - r = new Report(5190, Report.PUBLIC); - r.add(smokeCoords.getBoardNum()); - addReport(r); - } else if (smokeHex.terrainLevel(Terrains.SMOKE) == 1){ - //light smoke continue to fill hex - r = new Report(5195, Report.PUBLIC); - r.add(smokeCoords.getBoardNum()); - addReport(r); - } else { - smokeHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.SMOKE, 1)); - sendChangedHex(smokeCoords); - //light smoke fills hex - r = new Report(5200, Report.PUBLIC); - r.add(smokeCoords.getBoardNum()); - addReport(r); - } - } - } - - public void removeSmoke(int x, int y, int windDir) { // L2 smoke removal - Coords smokeCoords = new Coords(Coords.xInDir(x, y, windDir), Coords.yInDir(x, y, windDir)); - IHex nextHex = game.getBoard().getHex(smokeCoords); - if (nextHex != null && nextHex.containsTerrain(Terrains.SMOKE)) { - nextHex.removeTerrain(Terrains.SMOKE); - sendChangedHex(smokeCoords); - Report r = new Report(5205, Report.PUBLIC); - r.add(smokeCoords.getBoardNum()); - addReport(r); - } - } - - - /** - * Scans the boards directory for map boards of the appropriate size - * and returns them. - */ - private Vector scanForBoardsInDir (File dir, String addPath, int w, int h) { - String fileList[] = dir.list(); - Vector tempList = new Vector(); - Comparator sortComp = StringUtil.stringComparator(); - for (int i = 0; i < fileList.length; i++) { - if (fileList[i].indexOf(".board") == -1) { - continue; - } - if (Board.boardIsSize(addPath.concat("/").concat(fileList[i]), w, h)) { - tempList.addElement(addPath.concat("/").concat(fileList[i].substring(0, fileList[i].lastIndexOf(".board")))); - } - } - return tempList; - } - - private Vector scanForBoards(int boardWidth, int boardHeight) { - return scanForBoards (boardWidth, boardHeight, game.getOptions().booleanOption("maps_include_subdir")); - } - - private Vector scanForBoards(int boardWidth, int boardHeight, boolean subdirs) { - Vector boards = new Vector(); - - File boardDir = new File("data/boards"); - boards.addElement(MapSettings.BOARD_GENERATED); - // just a check... - if (!boardDir.isDirectory()) { - return boards; - } - - // scan files - String[] fileList = boardDir.list(); - Vector tempList = new Vector(); - Comparator sortComp = StringUtil.stringComparator(); - for (int i = 0; i < fileList.length; i++) { - File x = new File (new String("data/boards/").concat(fileList[i])); - if (x.isDirectory() && subdirs) { - tempList.addAll(scanForBoardsInDir(x, fileList[i], boardWidth, boardHeight)); - continue; - } - if (fileList[i].indexOf(".board") == -1) { - continue; - } - if (Board.boardIsSize(fileList[i], boardWidth, boardHeight)) { - tempList.addElement(fileList[i].substring(0, fileList[i].lastIndexOf(".board"))); - } - } - - // if there are any boards, add these: - if (tempList.size() > 0) { - boards.addElement( MapSettings.BOARD_RANDOM ); - boards.addElement( MapSettings.BOARD_SURPRISE ); - Collections.sort(tempList, sortComp); - for ( int loop = 0; loop < tempList.size(); loop++ ) { - boards.addElement( tempList.elementAt(loop) ); - } - } - - //TODO: alphabetize files? - - return boards; - } - - private boolean doBlind() { - return (game.getOptions().booleanOption("double_blind") && - game.getPhase() >= IGame.PHASE_DEPLOYMENT); - } - - /** - * In a double-blind game, update only visible entities. Otherwise, - * update everyone - */ - private void entityUpdate(int nEntityID) { - entityUpdate(nEntityID, new Vector()); - } - - private void entityUpdate(int nEntityID, Vector movePath) { - Entity eTarget = game.getEntity(nEntityID); - if(eTarget == null) { - if(game.getOutOfGameEntity(nEntityID) != null) { - System.err.printf("S: attempted to send entity update for out of game entity, id was %d\n", nEntityID); - } else { - System.err.printf("S: attempted to send entity update for null entity, id was %d\n", nEntityID); - } - return; //do not send the update it will crash the client - } - if (doBlind()) { - Vector vPlayers = game.getPlayersVector(); - Vector vCanSee = whoCanSee(eTarget); - // send an entity update to everyone who can see - Packet pack = createEntityPacket(nEntityID, movePath); - for (int x = 0; x < vCanSee.size(); x++) { - Player p = (Player)vCanSee.elementAt(x); - send(p.getId(), pack); - } - // send an entity delete to everyone else - pack = createRemoveEntityPacket( nEntityID, - eTarget.getRemovalCondition() ); - for (int x = 0; x < vPlayers.size(); x++) { - if (!vCanSee.contains(vPlayers.elementAt(x))) { - Player p = (Player)vPlayers.elementAt(x); - send(p.getId(), pack); - } - } - } - else { - // everyone can see - send(createEntityPacket(nEntityID, movePath)); - } - } - - /** - * Returns a vector of which players can see this entity. - */ - private Vector whoCanSee(Entity entity) { - - //Some times Null entities are sent to this - if ( entity == null ) - return new Vector(); - - boolean bTeamVision = game.getOptions().booleanOption("team_vision"); - Vector vEntities = game.getEntitiesVector(); - - Vector vCanSee = new Vector(); - vCanSee.addElement(entity.getOwner()); - if (bTeamVision) { - addTeammates(vCanSee, entity.getOwner()); - } - - for (Enumeration p = game.getPlayers(); p.hasMoreElements();) { - Player player = (Player)p.nextElement(); - - if (player.canSeeAll() && !vCanSee.contains(p)) - vCanSee.addElement(player); - } - - for (int i = 0; i < vEntities.size(); i++) { - Entity e = (Entity)vEntities.elementAt(i); - if (vCanSee.contains(e.getOwner()) || !e.isActive()) { - continue; - } - if(e.isOffBoard()) { - continue; //Off board units should not spot on board units - } - if (Compute.canSee(game, e, entity)) { - vCanSee.addElement(e.getOwner()); - if (bTeamVision) { - addTeammates(vCanSee, e.getOwner()); - } - } - } - return vCanSee; - } - - private boolean canSee(Player p, Entity e) { - if (e.getOwner().getId() == p.getId()) { - //The owner of an entity should be able to see it, of course. - return true; - } - Vector playersWhoCanSee = whoCanSee(e); - for (int i = 0; i < playersWhoCanSee.size(); i++) { - Player currentPlayer = (Player)playersWhoCanSee.elementAt(i); - if (currentPlayer.equals(p)) { - return true; - } - } - - return false; - } - - /** - * Adds teammates of a player to the Vector. - * Utility function for whoCanSee. - */ - private void addTeammates(Vector vector, Player player) { - Vector vPlayers = game.getPlayersVector(); - for (int j = 0; j < vPlayers.size(); j++) { - Player p = (Player)vPlayers.elementAt(j); - if (!player.isEnemyOf(p) && !vector.contains(p)) { - vector.addElement(p); - } - } - } - - /** - * Send the complete list of entities to the players. - * If double_blind is in effect, enforce it by filtering the entities - */ - private void entityAllUpdate() { - if (doBlind()) { - Vector vPlayers = game.getPlayersVector(); - for (int x = 0; x < vPlayers.size(); x++) { - Player p = (Player)vPlayers.elementAt(x); - send(p.getId(), createFilteredEntitiesPacket(p)); - } - } - else { - send(createEntitiesPacket()); - } - } - - - /** - * Filters an entity vector according to LOS - */ - private Vector filterEntities(Player pViewer, Vector vEntities) { - Vector vCanSee = new Vector(); - Vector vAllEntities = game.getEntitiesVector(); - Vector vMyEntities = new Vector(); - boolean bTeamVision = game.getOptions().booleanOption("team_vision"); - - // If they can see all, return the input list - if (pViewer.canSeeAll()) { - return vEntities; - } - - for (int x = 0; x < vAllEntities.size(); x++) { - Entity e = (Entity)vAllEntities.elementAt(x); - if (e.getOwner() == pViewer || (bTeamVision && !e.getOwner().isEnemyOf(pViewer))) { - vMyEntities.addElement(e); - } - } - - for (int x = 0; x < vEntities.size(); x++) { - Entity e = (Entity)vEntities.elementAt(x); - if (vMyEntities.contains(e)) { - vCanSee.addElement(e); - continue; - } - for (int y = 0; y < vMyEntities.size(); y++) { - Entity e2 = (Entity)vMyEntities.elementAt(y); - if(e2.isOffBoard()) { - continue; - } - if (Compute.canSee(game, e2, e)) { - vCanSee.addElement(e); - break; - } - } - } - return vCanSee; - } - - //optimize and document me - private Vector filterReportVector(Vector originalReportVector, Player p) { - if (!doBlind()) { - //don't bother filtering if double-blind rules aren't in effect - return (Vector)originalReportVector.clone(); - } - Vector filteredReportVector = new Vector(); - Report r; - for (int i = 0; i < originalReportVector.size(); i++) { - r = (Report)originalReportVector.elementAt(i); - filteredReportVector.addElement(filterReport(r, p, false)); - } - - return filteredReportVector; - } - - /** - * Filter a single report so that the correct double-blind - * obscuration takes place. - * - * @param r the Report to filter - * @param p the Player that we are going to send the filtered report to - * @param omitCheck boolean indicating that this report hapened in - * the past, so we no longer have access to the Player - * @return a new Report, which has possibly been obscured - */ - private Report filterReport(Report r, Player p, boolean omitCheck) { - if (r.subject == Entity.NONE && r.type != Report.PUBLIC) { - //Reports that don't have a subject should be public. - System.err.println("Error: Attempting to filter a Report object that is not public yet has no subject.\n\t\tmessageId: " + r.messageId); - return r; - } - if (r.type == Report.PUBLIC || (p == null && !omitCheck)) { - return r; - } - Entity entity = game.getEntity(r.subject); - Player owner = null; - if (entity != null) - owner = entity.getOwner(); - if (!omitCheck && (entity == null || owner == null)) { - System.err.println("Error: Attempting to filter a Report object that is not public but has a subject (" + entity + ") with owner (" + owner + ").\n\tmessageId: " + r.messageId); - return r; - } - //off board (Artillery) units get treated as public messages - if ( entity.isOffBoard() ) - return r; - Report copy = new Report(r); - for (int j = 0; j < copy.dataCount(); j++) { - if (omitCheck || !canSee(p, entity)) { - if (r.isValueObscured(j)) { - copy.hideData(j); - //Mark the original report to indicate which players - // received an obscured version of it. - if (p != null) - r.addObscuredRecipient(p.getName()); - } - //simulate hiding the report for *true* double-blind play - //***DEBUG*** TESTING ONLY - //copy.markForTesting(); - } - } - return copy; - } - - private Vector filterPastReports(Vector pastReports, Player p) { - //This stuff really only needs to be printed for debug reasons. other wise the logs get - //filled to the brim when ever someone connects. --Torren. - System.err.println("filterPastReports() begin"); - System.err.println(" player is " + p.getName()); - if (doBlind()) { - //System.err.println(" pastReports vector is\n" + pastReports); - Vector filteredReports = new Vector(); - Vector filteredRoundReports = new Vector(); - Vector roundReports = new Vector(); - Report r; - for (int i = 0; i < pastReports.size(); i++) { - roundReports = (Vector)pastReports.elementAt(i); - //System.err.println(" roundReports vector is\n" + roundReports); - for (int j = 0; j < roundReports.size(); j++) { - r = (Report)roundReports.elementAt(j); - if (r.isObscuredRecipient(p.getName())) { - //System.err.println(" report is " + r + " -obscuring-"); - filteredRoundReports.addElement(filterReport(r, null, true)); - } else { - //System.err.println(" report is " + r); - filteredRoundReports.addElement(r); - } - } - //System.err.println(" filteredRoundReport is\n" + filteredRoundReports); - filteredReports.addElement(filteredRoundReports.clone()); - filteredRoundReports.removeAllElements(); - } - System.err.println("filterPastReports() end"); - return filteredReports; - } else { - //don't bother filtering if double-blind rules aren't in effect - System.err.println("filterPastReports() end"); - return pastReports; - } - } - - /** - * Updates entities graphical "visibility indications" which are used - * in double-blind games. - */ - private void updateVisibilityIndicator() { - Vector vAllEntities = game.getEntitiesVector(); - for (int x = 0; x < vAllEntities.size(); x++) { - Entity e = (Entity)vAllEntities.elementAt(x); - boolean previousVisibleValue = e.isVisibleToEnemy(); - boolean previousSeenValue = e.isSeenByEnemy(); - e.setVisibleToEnemy(false); - Vector vCanSee = whoCanSee(e); - for (int y = 0; y < vCanSee.size(); y++) { - Player p = (Player)vCanSee.elementAt(y); - if (e.getOwner().isEnemyOf(p) && !p.isObserver()) { - e.setVisibleToEnemy(true); - e.setSeenByEnemy(true); - } - } - if (previousVisibleValue != e.isVisibleToEnemy() - || previousSeenValue != e.isSeenByEnemy()) { - sendVisibilityIndicator(e); - } - } - } - - /** - * Checks if an entity added by the client is valid and if so, adds it to the list - */ - private void receiveEntityAdd(Packet c, int connIndex) { - final Entity entity = (Entity)c.getObject(0); - - //Verify the entity's design - if (Server.entityVerifier == null) - Server.entityVerifier = new EntityVerifier(new File(VERIFIER_CONFIG_FILENAME)); - // we can only test meks and vehicles right now - if (entity instanceof Mech || entity instanceof Tank) { - TestEntity testEntity = null; - entity.restore(); - if (entity instanceof Mech) - testEntity = new TestMech((Mech)entity, Server.entityVerifier.mechOption, null); - if (entity instanceof VTOL) - testEntity = new TestTank((Tank)entity, Server.entityVerifier.tankOption, null);//not implemented yet. - if (entity instanceof Tank) - testEntity = new TestTank((Tank)entity, Server.entityVerifier.tankOption, null); - StringBuffer sb = new StringBuffer(); - if (testEntity.correctEntity(sb, !game.getOptions().booleanOption("is_eq_limits"))) { - entity.setDesignValid(true); - } else { - if (game.getOptions().booleanOption("allow_illegal_units")) { - entity.setDesignValid(false); - } else { - Player cheater = game.getPlayer( connIndex ); - sendServerChat("Player " + cheater.getName() + " attempted to add an illegal unit design (" + entity.getShortNameRaw() + "), the unit was rejected."); - System.err.println(sb); - return; - } - } - } - - // If we're adding a Protomech, calculate it's unit number. - if ( entity instanceof Protomech ) { - - // How many Protomechs does the player already have? - int numPlayerProtos = game.getSelectedEntityCount - ( new EntitySelector() { - private final int ownerId = entity.getOwnerId(); - public boolean accept( Entity entity ) { - if ( entity instanceof Protomech && - ownerId == entity.getOwnerId() ) - return true; - return false; - } - } ); - - // According to page 54 of the BMRr, Protomechs must be - // deployed in full Points of five, unless circumstances have - // reduced the number to less that that. - entity.setUnitNumber( (char) (numPlayerProtos / 5) ); - - } // End added-Protomech - - // Only assign an entity ID when the client hasn't. - if ( Entity.NONE == entity.getId() ) { - entity.setId(getFreeEntityId()); - } - - game.addEntity(entity.getId(), entity); - send(createAddEntityPacket(entity.getId())); - } - - /** - * Updates an entity with the info from the client. Only valid to do this - * during the lounge phase, except for heat sink changing. - */ - private void receiveEntityUpdate(Packet c, int connIndex) { - Entity entity = (Entity)c.getObject(0); - Entity oldEntity = game.getEntity(entity.getId()); - if (oldEntity != null && oldEntity.getOwner() == getPlayer(connIndex)) { - game.setEntity(entity.getId(), entity); - entityUpdate(entity.getId()); - // In the chat lounge, notify players of customizing of unit - if (game.getPhase() == IGame.PHASE_LOUNGE) { - StringBuffer message = new StringBuffer(); - message.append( "Unit " ); - if(game.getOptions().booleanOption("blind_drop") - || game.getOptions().booleanOption("real_blind_drop")) { - if(Entity.NONE != entity.getExternalId()) { - message.append("[").append(entity.getExternalId()).append("] "); - } - message.append(entity.getId()) - .append("(") - .append(entity.getOwner().getName()) - .append(")"); - } else { - message.append( entity.getDisplayName() ); - } - message.append( " has been customized." ); - sendServerChat( message.toString() ); - } - } else { - // hey! - } - } - - private void receiveEntityModeChange(Packet c, int connIndex) { - int entityId = c.getIntValue(0); - int equipId = c.getIntValue(1); - int mode = c.getIntValue(2); - Entity e = game.getEntity(entityId); - if (e.getOwner() != getPlayer(connIndex)) { - return; - } - Mounted m = e.getEquipment(equipId); - - // a mode change for ammo means dumping - if (m.getType() instanceof AmmoType - && !(m.getType().hasInstantModeSwitch())) { - m.setPendingDump(mode == 1); - } - else { - m.setMode(mode); - } - } - - private void receiveEntitySystemModeChange(Packet c, int connIndex) { - int entityId = c.getIntValue(0); - int equipId = c.getIntValue(1); - int mode = c.getIntValue(2); - Entity e = game.getEntity(entityId); - if (e.getOwner() != getPlayer(connIndex)) { - return; - } - if(e instanceof Mech && equipId == Mech.SYSTEM_COCKPIT) { - ((Mech)e).setCockpitStatus(mode); - } - } - - private void receiveEntityAmmoChange(Packet c, int connIndex) { - int entityId = c.getIntValue(0); - int weaponId = c.getIntValue(1); - int ammoId = c.getIntValue(2); - Entity e = game.getEntity(entityId); - - // Did we receive a request for a valid Entity? - if ( null == e ) { - System.err.print - ( "Server.receiveEntityAmmoChange: could not find entity #" ); - System.err.println( entityId ); - return; - } - Player player = getPlayer( connIndex ); - if ( null != player && e.getOwner() != player ) { - System.err.print - ( "Server.receiveEntityAmmoChange: player " ); - System.err.print( player.getName() ); - System.err.print( " does not own the entity " ); - System.err.println( e.getDisplayName() ); - return; - } - - // Make sure that the entity has the given equipment. - Mounted mWeap = e.getEquipment(weaponId); - Mounted mAmmo = e.getEquipment(ammoId); - if ( null == mAmmo ) { - System.err.print - ( "Server.receiveEntityAmmoChange: entity " ); - System.err.print( e.getDisplayName() ); - System.err.print( " does not have ammo #" ); - System.err.println( ammoId ); - return; - } - if ( !(mAmmo.getType() instanceof AmmoType) ) { - System.err.print - ( "Server.receiveEntityAmmoChange: item # " ); - System.err.print( ammoId ); - System.err.print( " of entity " ); - System.err.print( e.getDisplayName() ); - System.err.print( " is a " ); - System.err.print( mAmmo.getName() ); - System.err.println( " and not ammo." ); - return; - } - if ( null == mWeap ) { - System.err.print - ( "Server.receiveEntityAmmoChange: entity " ); - System.err.print( e.getDisplayName() ); - System.err.print( " does not have weapon #" ); - System.err.println( weaponId ); - return; - } - if ( !(mWeap.getType() instanceof WeaponType) ) { - System.err.print - ( "Server.receiveEntityAmmoChange: item # " ); - System.err.print( weaponId ); - System.err.print( " of entity " ); - System.err.print( e.getDisplayName() ); - System.err.print( " is a " ); - System.err.print( mWeap.getName() ); - System.err.println( " and not a weapon." ); - return; - } - if ( ((WeaponType) mWeap.getType()).getAmmoType() == AmmoType.T_NA ) { - System.err.print - ( "Server.receiveEntityAmmoChange: item # " ); - System.err.print( weaponId ); - System.err.print( " of entity " ); - System.err.print( e.getDisplayName() ); - System.err.print( " is a " ); - System.err.print( mWeap.getName() ); - System.err.println( " and does not use ammo." ); - return; - } - if ( ((WeaponType) mWeap.getType()).hasFlag(WeaponType.F_ONESHOT)) { - System.err.print - ( "Server.receiveEntityAmmoChange: item # " ); - System.err.print( weaponId ); - System.err.print( " of entity " ); - System.err.print( e.getDisplayName() ); - System.err.print( " is a " ); - System.err.print( mWeap.getName() ); - System.err.println( " and cannot use external ammo." ); - return; - } - - // Load the weapon. - e.loadWeapon( mWeap, mAmmo ); - } - - /** - * Deletes an entity owned by a certain player from the list - */ - private void receiveEntityDelete(Packet c, int connIndex) { - int entityId = c.getIntValue(0); - final Entity entity = game.getEntity(entityId); - - // Only allow players to delete their *own* entities. - if ( entity != null && entity.getOwner() == getPlayer(connIndex) ) { - - // If we're deleting a Protomech, recalculate unit numbers. - if ( entity instanceof Protomech ) { - - // How many Protomechs does the player have (include this one)? - int numPlayerProtos = game.getSelectedEntityCount - ( new EntitySelector() { - private final int ownerId = entity.getOwnerId(); - public boolean accept( Entity entity ) { - if ( entity instanceof Protomech && - ownerId == entity.getOwnerId() ) - return true; - return false; - } - } ); - - // According to page 54 of the BMRr, Protomechs must be - // deployed in full Points of five, unless "losses" have - // reduced the number to less that that. - final char oldMax = - (char)(Math.ceil( numPlayerProtos / 5.0 )-1); - char newMax = - (char)(Math.ceil( (numPlayerProtos-1)/ 5.0 )-1); - char deletedUnitNum = entity.getUnitNumber(); - - // Do we have to update a Protomech from the last unit? - if ( oldMax != deletedUnitNum && oldMax != newMax ) { - - // Yup. Find a Protomech from the last unit, and - // set it's unit number to the deleted entity. - Enumeration lastUnit = game.getSelectedEntities - ( new EntitySelector() { - private final int ownerId = entity.getOwnerId(); - private final char lastUnitNum = oldMax; - public boolean accept( Entity entity ) { - if ( entity instanceof Protomech && - ownerId == entity.getOwnerId() && - lastUnitNum == entity.getUnitNumber() ) - return true; - return false; - } - } ); - Entity lastUnitMember = (Entity) lastUnit.nextElement(); - lastUnitMember.setUnitNumber( deletedUnitNum ); - this.entityUpdate( lastUnitMember.getId() ); - - } // End update-unit-numbetr - - } // End added-Protomech - - game.removeEntity(entityId, IEntityRemovalConditions.REMOVE_NEVER_JOINED); - send(createRemoveEntityPacket(entityId, IEntityRemovalConditions.REMOVE_NEVER_JOINED)); - } - } - - /** - * Sets a player's ready status - */ - private void receivePlayerDone(Packet pkt, int connIndex) { - boolean ready = pkt.getBooleanValue(0); - Player player = getPlayer(connIndex); - if ( null != player ) { - player.setDone(ready); - } - } - - private void receiveInitiativeRerollRequest(Packet pkt, int connIndex) { - Player player = getPlayer(connIndex); - if ( IGame.PHASE_INITIATIVE_REPORT != game.getPhase() ) { - StringBuffer message = new StringBuffer(); - if ( null == player ) { - message.append( "Player #" ) - .append( connIndex ); - } else { - message.append( player.getName() ); - } - message.append( " is not allowed to ask for a reroll at this time." ); - System.err.println( message.toString() ); - sendServerChat( message.toString() ); - return; - } - if (game.hasTacticalGenius(player)) { - game.addInitiativeRerollRequest(game.getTeamForPlayer(player)); - } - if ( null != player ) { - player.setDone(true); - } - checkReady(); - } - - /** - * Sets game options, providing that the player has specified the password - * correctly. - * - * @return true if any options have been successfully changed. - */ - private boolean receiveGameOptions(Packet packet, int connId) { - Player player = game.getPlayer( connId ); - // Check player - if ( null == player ) { - System.err.print - ( "Server does not recognize player at connection " ); - System.err.println( connId ); - return false; - } - - // check password - if (password != null && password.length() > 0 && !password.equals(packet.getObject(0))) { - sendServerChat(connId, "The password you specified to change game options is incorrect."); - return false; - } - - int changed = 0; - - for (Enumeration i = ((Vector)packet.getObject(1)).elements(); i.hasMoreElements();) { - IBasicOption option = (IBasicOption)i.nextElement(); - IOption originalOption = game.getOptions().getOption(option.getName()); - - if (originalOption == null) { - continue; - } - - StringBuffer message = new StringBuffer(); - message.append( "Player " ) - .append( player.getName() ) - .append( " changed option \"" ) - .append( originalOption.getDisplayableName() ) - .append( "\" to " ) - .append( option.getValue().toString() ) - .append( "." ); - sendServerChat( message.toString() ); - originalOption.setValue(option.getValue()); - changed++; - } - - // Set proper RNG - Compute.setRNG(game.getOptions().intOption("rng_type")); - - return changed > 0; - } - - /** - * Performs the additional processing of the received options after the the - * receiveGameOptions done its job; should be called after - * receiveGameOptions only if the receiveGameOptions - * returned true - * @param packet - * @param connId - */ - private void receiveGameOptionsAux(Packet packet, int connId) { - - for (Enumeration i = ((Vector)packet.getObject(1)).elements(); i.hasMoreElements();) { - IBasicOption option = (IBasicOption)i.nextElement(); - IOption originalOption = game.getOptions().getOption(option.getName()); - if (originalOption != null) { - if ("maps_include_subdir".equals(originalOption.getName())) { - mapSettings.setBoardsAvailableVector(scanForBoards(mapSettings.getBoardWidth(), mapSettings.getBoardHeight())); - mapSettings.removeUnavailable(); - mapSettings.setNullBoards(DEFAULT_BOARD); - send(createMapSettingsPacket()); - } - } - } - - } - - /** - * Sends out all player info to the specified connection - */ - private void transmitAllPlayerConnects(int connId) { - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - final Player player = (Player)i.nextElement(); - - send(connId, createPlayerConnectPacket(player.getId())); - } - } - - - - /** - * Creates a packet informing that the player has connected - */ - private Packet createPlayerConnectPacket(int playerId) { - final Object[] data = new Object[2]; - data[0] = new Integer(playerId); - data[1] = getPlayer(playerId); - return new Packet(Packet.COMMAND_PLAYER_ADD, data); - } - - /** - * Creates a packet containing the player info, for update - */ - private Packet createPlayerUpdatePacket(int playerId) { - final Object[] data = new Object[2]; - data[0] = new Integer(playerId); - data[1] = getPlayer(playerId); - return new Packet(Packet.COMMAND_PLAYER_UPDATE, data); - } - - /** - * Sends out the player info updates for all players to all connections - */ - private void transmitAllPlayerUpdates() { - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - final Player player = (Player)i.nextElement(); - if ( null != player ) { - send(createPlayerUpdatePacket(player.getId())); - } - } - } - - /** - * Sends out the player ready stats for all players to all connections - */ - private void transmitAllPlayerDones() { - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - final Player player = (Player)i.nextElement(); - - send(createPlayerDonePacket(player.getId())); - } - } - - /** - * Creates a packet containing the player ready status - */ - private Packet createPlayerDonePacket(int playerId) { - Object[] data = new Object[2]; - data[0] = new Integer(playerId); - data[1] = new Boolean(getPlayer(playerId).isDone()); - return new Packet(Packet.COMMAND_PLAYER_READY, data); - } - - /** Creates a packet containing the current turn vector */ - private Packet createTurnVectorPacket() { - return new Packet(Packet.COMMAND_SENDING_TURNS, game.getTurnVector()); - } - - /** Creates a packet containing the current turn index */ - private Packet createTurnIndexPacket() { - return new Packet(Packet.COMMAND_TURN, new Integer(game.getTurnIndex())); - } - - /** - * Creates a packet containing the map settings - */ - private Packet createMapSettingsPacket() { - return new Packet(Packet.COMMAND_SENDING_MAP_SETTINGS, mapSettings); - } - - /** - * Creates a packet containing temporary map settings as a response to a - * client query - */ - private Packet createMapQueryPacket(MapSettings temp) { - return new Packet(Packet.COMMAND_QUERY_MAP_SETTINGS, temp); - } - - /** - * Creates a packet containing the game settingss - */ - private Packet createGameSettingsPacket() { - return new Packet(Packet.COMMAND_SENDING_GAME_SETTINGS, game.getOptions()); - } - - /** - * Creates a packet containing the game board - */ - private Packet createBoardPacket() { - return new Packet(Packet.COMMAND_SENDING_BOARD, game.getBoard()); - } - - /** - * Creates a packet containing a single entity, for update - */ - private Packet createEntityPacket(int entityId) { - return createEntityPacket(entityId, new Vector()); - } - private Packet createEntityPacket(int entityId, Vector movePath) { - final Entity entity = game.getEntity(entityId); - final Object[] data = new Object[3]; - data[0] = new Integer(entityId); - data[1] = entity; - data[2] = movePath; - return new Packet(Packet.COMMAND_ENTITY_UPDATE, data); - } - - /** - * Creates a packet containing a Vector of Reports - */ - private Packet createReportPacket(Player p) { - //when the final report is created MM sends a null player to create the - //report so this will handel that issue. - if ( p == null || !doBlind() ) - return new Packet(Packet.COMMAND_SENDING_REPORTS, filterReportVector(vPhaseReport, p)); - else - return new Packet(Packet.COMMAND_SENDING_REPORTS, p.getTurnReport()); - } - - /** - * Creates a packet containing a Vector of special Reports which - * needs to be sent during a phase that is not a report phase. - */ - private Packet createSpecialReportPacket() { - return new Packet(Packet.COMMAND_SENDING_REPORTS_SPECIAL, vPhaseReport.clone()); - } - - /** - * Creates a packet containing a Vector of Reports that represent - * a Tactical Genius re-roll request which needs to update a - * current phase's report. - */ - private Packet createTacticalGeniusReportPacket() { - return new Packet(Packet.COMMAND_SENDING_REPORTS_TACTICAL_GENIUS, vPhaseReport.clone()); - } - - /** - * Creates a packet containing all the round reports - */ - private Packet createAllReportsPacket(Player p) { - return new Packet(Packet.COMMAND_SENDING_REPORTS_ALL, filterPastReports(game.getAllReports(), p)); - } - - /** - * Creates a packet containing all current entities - */ - private Packet createEntitiesPacket() { - return new Packet(Packet.COMMAND_SENDING_ENTITIES, game.getEntitiesVector()); - } - - /** - * Creates a packet containing all current and out-of-game entities - */ - private Packet createFullEntitiesPacket() { - final Object[] data = new Object[2]; - data[0] = game.getEntitiesVector(); - data[1] = game.getOutOfGameEntitiesVector(); - return new Packet(Packet.COMMAND_SENDING_ENTITIES, data); - } - - /** - * Creates a packet containing all entities visible to the player in a blind game - */ - private Packet createFilteredEntitiesPacket(Player p) { - return new Packet(Packet.COMMAND_SENDING_ENTITIES, filterEntities(p, game.getEntitiesVector())); - } - - /** - * Creates a packet containing all entities, including wrecks, visible to the player in a blind game - */ - private Packet createFilteredFullEntitiesPacket(Player p) { - final Object[] data = new Object[2]; - data[0] = filterEntities(p, game.getEntitiesVector()); - data[1] = game.getOutOfGameEntitiesVector(); - return new Packet(Packet.COMMAND_SENDING_ENTITIES, data); - } - - /** - * Creates a packet detailing the addition of an entity - */ - private Packet createAddEntityPacket(int entityId) { - final Entity entity = game.getEntity(entityId); - final Object[] data = new Object[2]; - data[0] = new Integer(entityId); - data[1] = entity; - return new Packet(Packet.COMMAND_ENTITY_ADD, data); - } - - /** - * Creates a packet detailing the removal of an entity. - * Maintained for backwards compatability. - * - * @param entityId - the int ID of the entity being removed. - * @return A Packet to be sent to clients. - */ - private Packet createRemoveEntityPacket(int entityId) { - return this.createRemoveEntityPacket(entityId, IEntityRemovalConditions.REMOVE_SALVAGEABLE); - } - - /** - * Creates a packet detailing the removal of an entity. - * - * @param entityId - the int ID of the entity being removed. - * @param condition - the int condition the unit was in. - * This value must be one of Game.UNIT_IN_RETREAT, - * Game.UNIT_PUSHED, or - * Game.UNIT_SALVAGEABLE, or - * Game.UNIT_EJECTED, or - * Game.UNIT_DEVASTATED or an - * IllegalArgumentException will be thrown. - * @return A Packet to be sent to clients. - */ - private Packet createRemoveEntityPacket(int entityId, int condition) { - if ( condition != IEntityRemovalConditions.REMOVE_UNKNOWN && - condition != IEntityRemovalConditions.REMOVE_IN_RETREAT && - condition != IEntityRemovalConditions.REMOVE_PUSHED && - condition != IEntityRemovalConditions.REMOVE_SALVAGEABLE && - condition != IEntityRemovalConditions.REMOVE_EJECTED && - condition != IEntityRemovalConditions.REMOVE_CAPTURED && - condition != IEntityRemovalConditions.REMOVE_DEVASTATED && - condition != IEntityRemovalConditions.REMOVE_NEVER_JOINED ) { - throw new IllegalArgumentException( "Unknown unit condition: " + - condition ); - } - Object[] array = new Object[2]; - array[0] = new Integer(entityId); - array[1] = new Integer(condition); - return new Packet(Packet.COMMAND_ENTITY_REMOVE, array); - } - - /** - * Creates a packet indicating end of game, including detailed unit status - */ - private Packet createEndOfGamePacket() { - Object[] array = new Object[3]; - array[0] = getDetailedVictoryReport(); - array[1] = new Integer(game.getVictoryPlayerId()); - array[2] = new Integer(game.getVictoryTeam()); - return new Packet(Packet.COMMAND_END_OF_GAME, array); - } - - /** - * Transmits a chat message to all players - */ - private void sendChat(int connId, String origin, String message) { - send(connId, new Packet(Packet.COMMAND_CHAT, origin + ": " + message)); - } - - /** - * Transmits a chat message to all players - */ - private void sendChat(String origin, String message) { - String chat = origin + ": " + message; - send(new Packet(Packet.COMMAND_CHAT, chat)); - } - - public void sendServerChat(int connId, String message) { - sendChat(connId, "***Server", message); - } - - public void sendServerChat(String message) { - sendChat("***Server", message); - } - - /** - * Creates a packet containing a hex, and the coordinates it goes at. - */ - private Packet createHexChangePacket(Coords coords, IHex hex) { - final Object[] data = new Object[2]; - data[0] = coords; - data[1] = hex; - return new Packet(Packet.COMMAND_CHANGE_HEX, data); - } - - /** - * Sends notification to clients that the specified hex has changed. - */ - public void sendChangedHex(Coords coords) { - send(createHexChangePacket(coords, game.getBoard().getHex(coords))); - } - - public void sendVisibilityIndicator(Entity e) { - final Object[] data = new Object[3]; - data[0] = new Integer(e.getId()); - data[1] = new Boolean(e.isSeenByEnemy()); - data[2] = new Boolean(e.isVisibleToEnemy()); - send(new Packet(Packet.COMMAND_ENTITY_VISIBILITY_INDICATOR, data)); - } - - /** - * Creates a packet for an attack - */ - private Packet createAttackPacket(Vector vector, int charges) { - final Object[] data = new Object[2]; - data[0] = vector; - data[1] = new Integer(charges); - return new Packet(Packet.COMMAND_ENTITY_ATTACK, data); - } - - /** - * Creates a packet for an attack - */ - private Packet createAttackPacket(EntityAction ea, int charge) { - Vector vector = new Vector(1); - vector.addElement(ea); - Object[] data = new Object[2]; - data[0] = vector; - data[1] = new Integer(charge); - return new Packet(Packet.COMMAND_ENTITY_ATTACK, data); - } - - /** - * Creates a packet containing offboard artillery attacks - **/ - private Packet createArtilleryPacket(Player p) { - - if(p.getSeeAll()) { - return new Packet(Packet.COMMAND_SENDING_ARTILLERYATTACKS, game.getArtilleryVector()); - } - Vector v = new Vector(); - int team = p.getTeam(); - for(Enumeration i = game.getArtilleryAttacks();i.hasMoreElements();) { - ArtilleryAttackAction aaa = (ArtilleryAttackAction)i.nextElement(); - if(aaa.getPlayerId() == p.getId() || - (team != Player.TEAM_NONE && team == game.getPlayer(aaa.getPlayerId()).getTeam())) { - v.addElement(aaa); - } - } - return new Packet(Packet.COMMAND_SENDING_ARTILLERYATTACKS, v); - } - - /** - * Creates a packet containing flares - **/ - private Packet createFlarePacket() { - - return new Packet(Packet.COMMAND_SENDING_FLARES, game.getFlares()); - } - - /** - * Send a packet to all connected clients. - */ - private void send(Packet packet) { - if (connections == null) { - return; - } - for (Enumeration i = connections.elements(); i.hasMoreElements();) { - final Connection conn = (Connection)i.nextElement(); - conn.send(packet); - } - } - - private void sendReport() { - sendReport(false); - } - - /** - * Send the round report to all connected clients. - */ - private void sendReport(boolean tacticalGeniusReport) { - if (connections == null) { - return; - } - - for (Enumeration i = connections.elements(); i.hasMoreElements();) { - final Connection conn = (Connection)i.nextElement(); - Player p = game.getPlayer(conn.getId()); - Packet packet; - if (tacticalGeniusReport) - packet = createTacticalGeniusReportPacket(); - else - packet = createReportPacket(p); - conn.send(packet); - } - } - - /** - * Send a packet to a specific connection. - */ - private void send(int connId, Packet packet) { - if (getClient(connId) != null) { - getClient(connId).send(packet); - } else { - //What should we do if we've lost this client? - // For now, nothing. - } - } - - /** - * Send a packet to a pending connection - */ - private void sendToPending(int connId, Packet packet) { - if (getPendingConnection(connId) != null) { - getPendingConnection(connId).send(packet); - } else { - //What should we do if we've lost this client? - // For now, nothing. - } - } - - /** - * Process an in-game command - */ - private void processCommand(int connId, String commandString) { - String[] args; - String commandName; - // all tokens are read as strings; if they're numbers, string-ize 'em. - StringTokenizer st = new StringTokenizer(commandString); - args = new String[st.countTokens()]; - for (int i = 0; i < args.length; i++) { - args[i] = st.nextToken(); - } - - // figure out which command this is - commandName = args[0].substring(1); - - // process it - ServerCommand command = getCommand(commandName); - if (command != null) { - command.run(connId, args); - } else { - sendServerChat(connId, "Command not recognized. Type /help for a list of commands."); - } - } - - // Easter eggs. Happy April Fool's Day!! - private static final String DUNE_CALL = "They tried and failed?"; - private static final String DUNE_RESPONSE = "They tried and died!"; - private static final String STAR_WARS_CALL = "I'd just as soon kiss a Wookiee."; - private static final String STAR_WARS_RESPONSE = "I can arrange that!"; - - /** - * Process a packet from a connection. - * - * @param id - the int ID the connection that - * received the packet. - * @param packet - the Packet to be processed. - */ - protected synchronized void handle(int connId, Packet packet) { - Player player = game.getPlayer( connId ); - // Check player. Please note, the connection may be pending. - if ( null == player && null == getPendingConnection(connId) ) { - System.err.print - ( "Server does not recognize player at connection " ); - System.err.println( connId ); - return; - } - - //System.out.println("s(" + cn + "): received command"); - if (packet == null) { - System.out.println("server.connection.handle: got null packet"); - return; - } - // act on it - switch(packet.getCommand()) { - case Packet.COMMAND_CLOSE_CONNECTION : - // We have a client going down! - Connection c = getConnection(connId); - if ( c!= null) { - c.close(); - } - break; - case Packet.COMMAND_CLIENT_NAME : - receivePlayerName(packet, connId); - break; - case Packet.COMMAND_PLAYER_UPDATE : - receivePlayerInfo(packet, connId); - validatePlayerInfo(connId); - send(createPlayerUpdatePacket(connId)); - break; - case Packet.COMMAND_PLAYER_READY : - receivePlayerDone(packet, connId); - send(createPlayerDonePacket(connId)); - checkReady(); - break; - case Packet.COMMAND_REROLL_INITIATIVE : - receiveInitiativeRerollRequest(packet, connId); - send(createPlayerDonePacket(connId)); - break; - case Packet.COMMAND_CHAT : - String chat = (String)packet.getObject(0); - if (chat.startsWith("/")) { - processCommand(connId, chat); - } else { - sendChat(player.getName(), chat); - } - // Easter eggs. Happy April Fool's Day!! - if ( DUNE_CALL.equals(chat) ) { - sendServerChat( DUNE_RESPONSE ); - } - else if ( STAR_WARS_CALL.equals(chat) ) { - sendServerChat( STAR_WARS_RESPONSE ); - } - break; - case Packet.COMMAND_ENTITY_MOVE : - receiveMovement(packet, connId); - break; - case Packet.COMMAND_ENTITY_DEPLOY : - receiveDeployment(packet, connId); - break; - case Packet.COMMAND_DEPLOY_MINEFIELDS : - receiveDeployMinefields(packet, connId); - break; - case Packet.COMMAND_ENTITY_ATTACK : - receiveAttack(packet, connId); - break; - case Packet.COMMAND_ENTITY_ADD : - receiveEntityAdd(packet, connId); - resetPlayersDone(); - transmitAllPlayerDones(); - break; - case Packet.COMMAND_ENTITY_UPDATE : - receiveEntityUpdate(packet, connId); - resetPlayersDone(); - transmitAllPlayerDones(); - break; - case Packet.COMMAND_ENTITY_MODECHANGE : - receiveEntityModeChange(packet, connId); - break; - case Packet.COMMAND_ENTITY_SYSTEMMODECHANGE : - receiveEntitySystemModeChange(packet, connId); - break; - case Packet.COMMAND_ENTITY_AMMOCHANGE : - receiveEntityAmmoChange(packet, connId); - break; - case Packet.COMMAND_ENTITY_REMOVE : - receiveEntityDelete(packet, connId); - resetPlayersDone(); - transmitAllPlayerDones(); - break; - case Packet.COMMAND_SENDING_GAME_SETTINGS : - if (receiveGameOptions(packet, connId)) { - resetPlayersDone(); - transmitAllPlayerDones(); - send(createGameSettingsPacket()); - receiveGameOptionsAux(packet, connId); - } - break; - case Packet.COMMAND_SENDING_MAP_SETTINGS : - MapSettings newSettings=(MapSettings)packet.getObject(0); - if (!mapSettings.equalMapGenParameters(newSettings)) { - sendServerChat("Player " + player.getName() + - " changed mapsettings"); - } - mapSettings = newSettings; - newSettings = null; - mapSettings.replaceBoardWithRandom(MapSettings.BOARD_RANDOM); - resetPlayersDone(); - transmitAllPlayerDones(); - send(createMapSettingsPacket()); - break; - case Packet.COMMAND_QUERY_MAP_SETTINGS : - MapSettings temp = (MapSettings)packet.getObject(0); - temp.setBoardsAvailableVector(scanForBoards(temp.getBoardWidth(), temp.getBoardHeight())); - temp.removeUnavailable(); - temp.setNullBoards(DEFAULT_BOARD); - temp.replaceBoardWithRandom(MapSettings.BOARD_RANDOM); - temp.removeUnavailable(); - send(connId, createMapQueryPacket(temp)); - break; - case Packet.COMMAND_UNLOAD_STRANDED : - receiveUnloadStranded(packet, connId); - break; - case Packet.COMMAND_SET_ARTYAUTOHITHEXES : - receiveArtyAutoHitHexes(packet, connId); - } - } - - - /** - * Listen for incoming clients. - */ - public void run() { - Thread currentThread = Thread.currentThread(); - System.out.println("s: listening for clients..."); - while (connector == currentThread) { - try { - Socket s = serverSocket.accept(); - - int id = getFreeConnectionId(); - System.out.println("s: accepting player connection #" + id + " ..."); - - Connection c = ConnectionFactory.getInstance().createServerConnection(s, id); - c.addConnectionListener(connectionListener); - c.open(); - connectionsPending.addElement(c); - - greeting(id); - } catch(IOException ex) { - - } - } - } - - /** - * Makes one slot of inferno ammo, determined - * by certain rules, explode on a mech. - * - * @param entity The Entity that should suffer an - * inferno ammo explosion. - */ - private Vector explodeInfernoAmmoFromHeat(Entity entity) { - int damage = 0; - int rack = 0; - int boomloc = -1; - int boomslot = -1; - Vector vDesc = new Vector(); - Report r; - - // Find the most destructive Inferno ammo. - for (int j = 0; j < entity.locations(); j++) { - for (int k = 0; k < entity.getNumberOfCriticals(j); k++) { - CriticalSlot cs = entity.getCritical(j, k); - // Ignore empty, destroyed, hit, and structure slots. - if ( cs == null || cs.isDestroyed() || cs.isHit() || - cs.getType() != CriticalSlot.TYPE_EQUIPMENT ) { - continue; - } - // Ignore everything but weapons slots. - Mounted mounted = entity.getEquipment - ( entity.getCritical(j, k).getIndex() ); - if (!(mounted.getType() instanceof AmmoType)) { - continue; - } - // Ignore everything but Inferno ammo. - AmmoType atype = (AmmoType)mounted.getType(); - if ( !atype.isExplosive() || - atype.getMunitionType() != AmmoType.M_INFERNO) { - continue; - } - // Find the most destructive undamaged ammo. - // BMRr, pg. 48, compare one rack's - // damage. Ties go to most rounds. - int newRack = atype.getDamagePerShot() * atype.getRackSize(); - int newDamage = mounted.getExplosionDamage(); - if ( !mounted.isHit() && ( rack < newRack || - (rack == newRack && damage < newDamage) ) ) { - rack = newRack; - damage = newDamage; - boomloc = j; - boomslot = k; - } - } - } - // Did we find anything to explode? - if (boomloc != -1 && boomslot != -1) { - CriticalSlot slot = entity.getCritical(boomloc, boomslot); - slot.setHit(true); - entity.getEquipment(slot.getIndex()).setHit(true); - // We've allocated heatBuildup to heat in resolveHeat(), - // so need to add to the entity's heat instead. - vDesc.addAll( explodeEquipment(entity, boomloc, boomslot)); - entity.heat += 30; - r = new Report(5155); - r.indent(); - r.subject = entity.getId(); - r.add(entity.heat); - vDesc.addElement(r); - entity.heatBuildup = 0; - } else { //no ammo to explode - r = new Report(5160); - r.indent(); - r.subject = entity.getId(); - vDesc.addElement(r); - } - return vDesc; - } - - /** - * Determine the results of an entity moving through a wall of a building - * after having moved a certain distance. This gets called when a Mech - * or a Tank enters a building, leaves a building, or travels from one - * hex to another inside a multi-hex building. - * - * @param entity - the Entity that passed through a wall. - * Don't pass Infantry units to this method. - * @param bldg - the Building the entity is passing through. - * @param lastPos - the Coords of the hex the entity is - * exiting. - * @param curPos - the Coords of the hex the entity is - * entering - * @param distance - the int number of hexes the entity - * has moved already this phase. - * @param why - the String explanatin for this action. - * @return true if the building collapses due to overloading. - */ - private boolean passBuildingWall( Entity entity, - Building bldg, - Coords lastPos, - Coords curPos, - int distance, - String why ) { - - Report r; - - // Need to roll based on building type. - PilotingRollData psr = entity.rollMovementInBuilding(bldg, distance, why); - - // Did the entity make the roll? - if ( !doSkillCheckWhileMoving( entity, lastPos, - curPos, psr, false ) ) { - - // Divide the building's current CF by 10, round up. - int damage = (int) Math.ceil( bldg.getCurrentCF() / 10.0 ); - - // It is possible that the unit takes no damage. - if ( damage == 0 ) { - r = new Report(6440); - r.add(entity.getDisplayName()); - r.subject = entity.getId(); - r.indent(2); - addReport(r); - } else { - // BMRr, pg. 50: The attack direction for this damage is the front. - HitData hit = entity.rollHitLocation( ToHitData.HIT_NORMAL, - ToHitData.SIDE_FRONT ); - addReport( damageEntity(entity, hit, damage)); - } - } - - // Damage the building. The CF can never drop below 0. - int toBldg = (int) Math.ceil( entity.getWeight() / 10.0 ); - int curCF = bldg.getCurrentCF(); - curCF -= Math.min( curCF, toBldg ); - bldg.setCurrentCF( curCF ); - - // Apply the correct amount of damage to infantry in the building. - // ASSUMPTION: We inflict toBldg damage to infantry and - // not the amount to bring building to 0 CF. - this.damageInfantryIn( bldg, toBldg ); - - return checkBuildingCollapseWhileMoving(bldg, entity, curPos); - } - - private boolean checkBuildingCollapseWhileMoving(Building bldg, Entity entity, Coords curPos) { - // Get the position map of all entities in the game. - Hashtable positionMap = game.getPositionMap(); - - // Count the moving entity in its current position, not - // its pre-move postition. Be sure to handle nulls. - Vector entities = null; - if ( entity.getPosition() != null ) { - entities = (Vector) positionMap.get( entity.getPosition() ); - entities.removeElement( entity ); - } - entities = (Vector) positionMap.get( curPos ); - if ( entities == null ) { - entities = new Vector(); - positionMap.put( curPos, entities ); - } - entities.addElement( entity ); - - // Check for collapse of this building due to overloading, and return. - return this.checkForCollapse( bldg, positionMap ); - } - - /** - * Apply the correct amount of damage that passes on to any infantry unit - * in the given building, based upon the amount of damage the building - * just sustained. This amount is a percentage dictated by pg. 52 of BMRr. - * - * @param bldg - the Building that sustained the damage. - * @param damage - the int amount of damage. - */ - private void damageInfantryIn( Building bldg, int damage ) { - // Calculate the amount of damage the infantry will sustain. - float percent = 0.0f; - Report r; - switch( bldg.getType() ) { - case Building.LIGHT: percent = 0.75f; break; - case Building.MEDIUM: percent = 0.5f; break; - case Building.HEAVY: percent = 0.25f; break; - } - - // Round up at .5 points of damage. - int toInf = Math.round( damage * percent ); - - // Record if we find any infantry. - boolean foundInfantry = false; - - // Walk through the entities in the game. - Enumeration entities = game.getEntities(); - while ( entities.hasMoreElements() ) { - Entity entity = (Entity) entities.nextElement(); - final Coords coords = entity.getPosition(); - - // If the entity is infantry in one of the building's hexes? - if ( entity instanceof Infantry && - bldg.isIn( coords ) ) { - - // Is the entity is inside of the building - // (instead of just on top of it)? - if ( Compute.isInBuilding( game, entity, coords ) ) { - - // Report if the infantry receive no points of damage. - if ( toInf == 0 ) { - r = new Report(6445); - addReport(r); - } else { - // Yup. Damage the entity. - // Battle Armor units use 5 point clusters. - r = new Report(6450); - r.indent(2); - r.subject = entity.getId(); - r.add(entity.getDisplayName()); - r.add(toInf); - addReport(r); - int remaining = toInf; - int cluster = toInf; - if ( entity instanceof BattleArmor ) { - cluster = 5; - } - while ( remaining > 0 ) { - int next = Math.min( cluster, remaining ); - HitData hit = entity.rollHitLocation - ( ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT ); - addReport( damageEntity(entity, hit, next) ); - remaining -= next; - } - addReport(new Report(1210)); - } - - } // End infantry-inside-building - - } // End entity-is-infantry-in-building-hex - - } // Handle the next entity - - // If we found any infantry, add a line to the phase report. - if ( foundInfantry ) { - addReport(new Report(1210)); - } - - } // End private void damageInfantryIn( Building, int ) - - /** - * Determine if the given building should collapse. If so, - * inflict the appropriate amount of damage on each entity in - * the building and update the clients. If the building does - * not collapse, determine if any entities crash through its - * floor into its basement. Again, apply appropriate damage. - * - * @param bldg - the Building being checked. - * This value should not be null. - * @param positionMap - a Hashtable that maps - * the Coords positions or each unit - * in the game to a Vector of - * Entitys at that position. - * This value should not be null. - * @return true if the building collapsed. - */ - public boolean checkForCollapse( Building bldg, Hashtable positionMap ) { - - // If the input is meaningless, do nothing and throw no exception. - if ( bldg == null || - positionMap == null || positionMap.isEmpty() ) { - return false; - } - - // Get the building's current CF. - final int currentCF = bldg.getCurrentCF(); - - // Track all units that fall into the building's basement by Coords. - Hashtable basementMap = new Hashtable(); - - // Walk through the hexes in the building, looking for a collapse. - Enumeration bldgCoords = bldg.getCoords(); - boolean collapse = false; - while ( !collapse && bldgCoords.hasMoreElements() ) { - final Coords coords = (Coords) bldgCoords.nextElement(); - - // Get the Vector of Entities at these coordinates. - final Vector vector = (Vector) positionMap.get( coords ); - - // Are there any Entities at these coords? - if ( vector != null ) { - - // How many levels does this building have in this hex? - final IHex curHex = game.getBoard().getHex( coords ); - final int hexElev = curHex.surface(); - final int numFloors = Math.max(0,curHex.terrainLevel( Terrains.BLDG_ELEV )); - final int bridgeEl = curHex.terrainLevel(Terrains.BRIDGE_ELEV); - int numLoads = numFloors; - if(bridgeEl != ITerrain.LEVEL_NONE) { - numLoads ++; - } - if(numLoads < 1) { - System.err.println("Check for collapse: hex "+coords.toString()+" has no bridge or building"); - continue; - } - - // Track the load of each floor (and of the roof) separately. - // Track all units that fall into the basement in this hex. - // N.B. don't track the ground floor, the first floor is at - // index 0, the second is at index 1, etc., and the roof is - // at index (numFloors-1). - // if bridge is present, bridge will be numFloors - int[] loads = new int[numLoads]; - Vector basement = new Vector(); - for ( int loop = 0; loop < numLoads; loop++ ) { - loads[loop] = 0; - } - - // Walk through the entities in this position. - Enumeration entities = vector.elements(); - while ( !collapse && entities.hasMoreElements() ) { - final Entity entity = (Entity) entities.nextElement(); - final int entityElev = entity.getElevation(); - - if(entityElev != bridgeEl) { - // Ignore entities not *inside* the building - if ( entityElev > numFloors) { - continue; - } - } - - if(entity.getMovementMode() == IEntityMovementMode.HYDROFOIL - || entity.getMovementMode() == IEntityMovementMode.NAVAL - || entity.getMovementMode() == IEntityMovementMode.SUBMARINE) { - continue; //under the bridge even at same level - } - - // Add the weight of a Mek or tank to the correct floor. - if ( entity instanceof Mech || entity instanceof Tank ) { - int load = (int) entity.getWeight(); - int floor = entityElev; - if(floor == bridgeEl) { - floor = numLoads; - } - - // Entities on the ground floor may fall into the - // basement, but they won't collapse the building. - if ( numFloors > 0 && floor == 0 && load > currentCF ) { - basement.addElement( entity ); - } else if ( floor > 0 ) { - - // If the load on any floor but the ground floor - // exceeds the building's current CF it collapses. - floor--; - loads[ floor ] += load; - if ( loads[ floor ] > currentCF ) { - collapse = true; - } - - } // End not-ground-floor - - } // End increase-load - - } // Handle the next entity. - - // Track all entities that fell into the basement. - if ( !basement.isEmpty() ) { - basementMap.put( coords, basement ); - } - - } // End have-entities-here - - } // Check the next hex of the building. - - // Collapse the building if the flag is set. - if ( collapse ) { - Report r = new Report(2375); - r.add(bldg.getName()); - addReport(r); - this.collapseBuilding( bldg, positionMap ); - } - - // Otherwise, did any entities fall into the basement? - else if ( !basementMap.isEmpty() ) { - // TODO: implement basements - } - - // Return true if the building collapsed. - return collapse; - - } // End private boolean checkForCollapse( Building, Hashtable ) - - /** - * Collapse the building. Inflict the appropriate amount of damage - * on all entities in the building. Update all clients. - * - * @param bldg - the Building that has collapsed. - * @param positionMap - a Hashtable that maps - * the Coords positions or each unit - * in the game to a Vector of - * Entitys at that position. - * This value should not be null. - */ - public void collapseBuilding( Building bldg, Hashtable positionMap ) { - // Loop through the hexes in the building, and apply - // damage to all entities inside or on top of the building. - Report r; - final int phaseCF = bldg.getPhaseCF(); - Enumeration bldgCoords = bldg.getCoords(); - while ( bldgCoords.hasMoreElements() ) { - final Coords coords = (Coords) bldgCoords.nextElement(); - - // Get the Vector of Entities at these coordinates. - final Vector vector = (Vector) positionMap.get( coords ); - - // Are there any Entities at these coords? - if ( vector != null ) { - - // How many levels does this building have in this hex? - final IHex curHex = game.getBoard().getHex( coords ); - final int hexElev = curHex.surface(); - final int bridgeEl = curHex.terrainLevel(Terrains.BRIDGE_ELEV); - final int numFloors = Math.max(bridgeEl, curHex.terrainLevel( Terrains.BLDG_ELEV )); - - // Sort in elevation order - Collections.sort(vector, new Comparator() { - public int compare(Entity a, Entity b) { - if(a.getElevation() > b.getElevation()) - return -1; - else if(a.getElevation() > b.getElevation()) - return 1; - return 0; - } - }); - // Walk through the entities in this position. - Enumeration entities = vector.elements(); - while ( entities.hasMoreElements() ) { - final Entity entity = (Entity) entities.nextElement(); - //final int entityElev = entity.elevationOccupied( curHex ); - int floor = entity.getElevation(); - - // Ignore units above the building / bridge. - if ( floor > numFloors) { - continue; - } - - // Treat units on the roof like - // they were in the top floor. - if ( floor == numFloors ) { - floor--; - } - - // Calculate collapse damage for this entity. - int damage = (int) Math.ceil - ( phaseCF * (numFloors-floor) / 10.0 ); - - // Infantry suffer triple damage. - if ( entity instanceof Infantry ) { - damage *= 3; - } - - // Apply collapse damage the entity. - // ASSUMPTION: use 5 point clusters. - r = new Report(6455); - r.indent(); - r.subject = entity.getId(); - r.add(entity.getDisplayName()); - r.add(damage); - addReport(r); - int remaining = damage; - int cluster = damage; - if ( entity instanceof BattleArmor || - entity instanceof Mech || - entity instanceof Tank ) { - cluster = 5; - } - while ( remaining > 0 ) { - int next = Math.min( cluster, remaining ); - // In www.classicbattletech.com/PDF/AskPMForumArchiveandFAQ.pdf, - // pg. 18, Randall Bills says that all damage from a - // collapsing building is applied to the front. - - HitData hit = entity.rollHitLocation - (ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT ); - addReport( damageEntity(entity, hit, next) ); - remaining -= next; - } - addReport(new Report(1210)); - // TODO: Why are dead entities showing up on firing phase? - - // Do we need to handle falling Meks? - // BMRr, pg. 53 only mentions falling BattleMechs; - // Tanks can't be above the floor and I guess that - // infantry don't suffer falling damage. - // TODO: implement basements, then fall into it. - // ASSUMPTION: we'll let the Mech fall twice: once - // during damageEntity() above and once here. - floor = entity.getElevation(); - if ( floor > 0 || floor == bridgeEl) { - // ASSUMPTION: PSR to avoid pilot damage - // should use mods for entity damage and - // 20+ points of collapse damage (if any). - PilotingRollData psr = entity.getBasePilotingRoll(); - entity.addPilotingModifierForTerrain(psr, coords); - if ( damage >= 20 ) { - psr.addModifier( 1, "20+ damage" ); - } - this.doEntityFallsInto( entity, coords, coords, psr ); - } - - // Update this entity. - // ASSUMPTION: this is the correct thing to do. - this.entityUpdate( entity.getId() ); - - } // Handle the next entity. - - } // End have-entities-here. - - } // Handle the next hex of the building. - - // Update the building. - bldg.setCurrentCF( 0 ); - bldg.setPhaseCF( 0 ); - send( createCollapseBuildingPacket(bldg) ); - game.getBoard().collapseBuilding( bldg ); - - } // End private void collapseBuilding( Building ) - - /** - * Tell the clients to replace the given building with rubble hexes. - * - * @param bldg - the Building that has collapsed. - * @return a Packet for the command. - */ - private Packet createCollapseBuildingPacket( Building bldg ) { - Vector buildings = new Vector(); - buildings.addElement( bldg ); - return this.createCollapseBuildingPacket( buildings ); - } - - /** - * Tell the clients to replace the given buildings with rubble hexes. - * - * @param buildings - a Vector of Buildings - * that has collapsed. - * @return a Packet for the command. - */ - private Packet createCollapseBuildingPacket( Vector buildings ) { - return new Packet( Packet.COMMAND_BLDG_COLLAPSE, buildings ); - } - - /** - * Tell the clients to update the CFs of the given buildings. - * - * @param buildings - a Vector of Buildings - * that need to be updated. - * @return a Packet for the command. - */ - private Packet createUpdateBuildingCFPacket( Vector buildings ) { - return new Packet( Packet.COMMAND_BLDG_UPDATE_CF, buildings ); - } - - /** - * Apply this phase's damage to all buildings. Buildings may - * collapse due to damage. - */ - private void applyBuildingDamage() { - - // Walk through the buildings in the game. - // Build the collapse and update vectors as you go. - // N.B. never, NEVER, collapse buildings while you are walking through - // the Enumeration from megamek.common.Board#getBuildings. - Vector collapse = new Vector(); - Vector update = new Vector(); - Enumeration buildings = game.getBoard().getBuildings(); - while ( buildings.hasMoreElements() ) { - Building bldg = (Building) buildings.nextElement(); - - // If the CF is zero, the building should fall. - if ( bldg.getCurrentCF() == 0 ) { - collapse.addElement( bldg ); - } - - // If the building took damage this round, update it. - else if ( bldg.getPhaseCF() != bldg.getCurrentCF() ) { - bldg.setPhaseCF( bldg.getCurrentCF() ); - update.addElement( bldg ); - } - - } // Handle the next building - - // If we have any buildings to collapse, collapse them now. - if ( !collapse.isEmpty() ) { - - // Get the position map of all entities in the game. - Hashtable positionMap = game.getPositionMap(); - - // Walk through the buildings that have collapsed. - buildings = collapse.elements(); - while ( buildings.hasMoreElements() ) { - Building bldg = (Building) buildings.nextElement(); - Report r = new Report(6460,Report.PUBLIC); - r.add(bldg.getName()); - addReport(r); - this.collapseBuilding( bldg, positionMap ); - } - - } - - //check for buildings which should collapse due to being overloaded now CF is reduced - if(!update.isEmpty()) { - Hashtable positionMap = game.getPositionMap(); - for(Iterator i=update.iterator();i.hasNext();) { - Building bldg = (Building) i.next(); - if(checkForCollapse(bldg, positionMap)) i.remove(); - } - } - - // If we have any buildings to update, send the message. - if ( !update.isEmpty() ) { - sendChangedCFBuildings( update ); - } - } - - /** - * Apply the given amount of damage to the building. Please note, - * this method does not apply any damage to units inside the - * building, update the clients, or check for the building's collapse. - *

- * A default message will be used to describe why the building - * took the damage. - * - * @param bldg - the Building that has been damaged. - * This value should not be null, but no - * exception will occur. - * @param damage - the int amount of damage. - * @return a Report to be shown to the players. - */ - private Report damageBuilding( Building bldg, int damage ) { - final String defaultWhy = " absorbs "; - return damageBuilding( bldg, damage, defaultWhy ); - } - - /** - * Apply the given amount of damage to the building. Please note, - * this method does not apply any damage to units inside the - * building, update the clients, or check for the building's collapse. - * - * @param bldg - the Building that has been damaged. - * This value should not be null, but no - * exception will occur. - * @param damage - the int amount of damage. - * @param why - the String message that describes - * why the building took the damage. - * @return a Report to be shown to the players. - */ - private Report damageBuilding( Building bldg, int damage, String why ) { - Report r = new Report(1210); - r.newlines = 0; - - // Do nothing if no building or no damage was passed. - if ( bldg != null && damage > 0 ) { - int curCF = bldg.getCurrentCF(); - final int startingCF = curCF; - curCF -= Math.min( curCF, damage ); - bldg.setCurrentCF( curCF ); - r.messageId = 3435; - r.add( bldg.getName() ); - r.add( why ); - r.add( damage ); - - // If the CF is zero, the building should fall. - if ( curCF == 0 && startingCF != 0 ) { - r.messageId = 3440; - } - - } - return r; - } - - public void sendChangedCFBuildings(Vector buildings) { - send(createUpdateBuildingCFPacket(buildings)); - } - - /** - * Receives an packet to unload entityis stranded on immobile transports, - * and queue all valid requests for execution. If all players that have - * stranded entities have answered, executes the pending requests and end - * the current turn. - */ - private void receiveUnloadStranded( Packet packet, int connId ) { - GameTurn.UnloadStrandedTurn turn = null; - final Player player = game.getPlayer( connId ); - int[] entityIds = (int[]) packet.getObject(0); - Vector declared = null; - Player other = null; - Enumeration pending = null; - UnloadStrandedAction action = null; - Entity entity = null; - - // Is this the right phase? - if (game.getPhase() != IGame.PHASE_MOVEMENT) { - System.err.println - ("error: server got unload stranded packet in wrong phase"); - return; - } - - // Are we in an "unload stranded entities" turn? - if ( game.getTurn() instanceof GameTurn.UnloadStrandedTurn ) { - turn = (GameTurn.UnloadStrandedTurn) game.getTurn(); - } else { - System.err.println - ("error: server got unload stranded packet out of sequence"); - StringBuffer message = new StringBuffer(); - message.append( player.getName() ) - .append( " should not be sending 'unload stranded entity' packets at this time." ); - sendServerChat( message.toString() ); - return; - } - - // Can this player act right now? - if (!turn.isValid(connId, game)) { - System.err.println - ("error: server got unload stranded packet from invalid player"); - StringBuffer message = new StringBuffer(); - message.append( player.getName() ) - .append( " should not be sending 'unload stranded entity' packets." ); - sendServerChat( message.toString() ); - return; - } - - // Did the player already send an 'unload' request? - // N.B. we're also building the list of players who - // have declared their "unload stranded" actions. - declared = new Vector(); - pending = game.getActions(); - while ( pending.hasMoreElements() ) { - action = (UnloadStrandedAction) pending.nextElement(); - if ( action.getPlayerId() == connId ) { - System.err.println("error: server got multiple unload stranded packets from player"); - StringBuffer message = new StringBuffer(); - message.append( player.getName() ) - .append( " should not send multiple 'unload stranded entity' packets." ); - sendServerChat( message.toString() ); - return; - } else { - // This player is not from the current connection. - // Record this player to determine if this turn is done. - other = game.getPlayer( action.getPlayerId() ); - if ( !declared.contains( other ) ) { - declared.addElement( other ); - } - } - } // Handle the next "unload stranded" action. - - // Make sure the player selected at least *one* valid entity ID. - boolean foundValid = false; - for ( int index = 0; null != entityIds && index < entityIds.length; - index++ ) { - entity = game.getEntity( entityIds[index] ); - if (!game.getTurn().isValid(connId, entity, game)) { - System.err.println("error: server got unload stranded packet for invalid entity"); - StringBuffer message = new StringBuffer(); - message.append( player.getName() ) - .append( " can not unload stranded entity " ); - if ( null == entity ) { - message.append( "#" ) - .append( entityIds[index] ); - } else { - message.append( entity.getDisplayName() ); - } - message.append( " at this time." ); - sendServerChat( message.toString() ); - } else { - foundValid = true; - game.addAction( new UnloadStrandedAction( connId, - entityIds[index] ) ); - } - } - - // Did the player choose not to unload any valid stranded entity? - if ( !foundValid ) { - game.addAction( new UnloadStrandedAction( connId, Entity.NONE ) ); - } - - // Either way, the connection's player has now declared. - declared.addElement( player ); - - // Are all players who are unloading entities done? Walk - // through the turn's stranded entities, and look to see - // if their player has finished their turn. - entityIds = turn.getEntityIds(); - for ( int index = 0; index < entityIds.length; index++ ) { - entity = game.getEntity( entityIds[index] ); - other = entity.getOwner(); - if ( !declared.contains( other ) ) { - // At least one player still needs to declare. - return; - } - } - - // All players have declared whether they're unloading stranded units. - // Walk the list of pending actions and unload the entities. - pending = game.getActions(); - while ( pending.hasMoreElements() ) { - action = (UnloadStrandedAction) pending.nextElement(); - - // Some players don't want to unload any stranded units. - if ( Entity.NONE != action.getEntityId() ) { - entity = game.getEntity( action.getEntityId() ); - if ( null == entity ) { - // After all this, we couldn't find the entity!!! - System.err.print - ("error: server could not find stranded entity #"); - System.err.print( action.getEntityId() ); - System.err.println( " to unload!!!"); - } else { - // Unload the entity. Get the unit's transporter. - Entity transporter = - game.getEntity( entity.getTransportId() ); - this.unloadUnit( transporter, entity, - transporter.getPosition(), - transporter.getFacing(), - transporter.getElevation()); - } - } - - } // Handle the next pending unload action - - // Clear the list of pending units and move to the next turn. - game.resetActions(); - changeToNextTurn(); - } - /** - * For all current artillery attacks in the air from this entity - * with this weapon, clear the list of spotters. Needed because - * firing another round before first lands voids spotting. - * - * @param entityID int - */ - private void clearArtillerySpotters(int entityID,int weaponID) { - for (Enumeration i = game.getArtilleryAttacks(); i.hasMoreElements();) { - ArtilleryAttackAction aaa = (ArtilleryAttackAction) i.nextElement(); - if ( aaa.getWR().waa.getEntityId()==entityID && - aaa.getWR().waa.getWeaponId()==weaponID ) { - aaa.setSpotterIds(null); - } - - } - } - - /** - * Find the tagged entity for this attack - * - * Each TAG will attract a number of shots up to its priority number (mode setting) - * When all the TAGs are used up, the shots fired are reset. - * So if you leave them all on 1-shot, then homing attacks will be evenly split, however many shots you fire. - * - * Priority setting is to allocate more homing attacks to a more important target as decided by player. - * - * TAGs fired by the enemy aren't eligable, nor are TAGs fired at a target on a different map sheet. - */ - private WeaponResult convertHomingShotToEntityTarget(ArtilleryAttackAction aaa, Entity ae) { - WeaponResult wr = aaa.getWR(); - Targetable target = wr.waa.getTarget(game); - - final Coords tc = target.getPosition(); - Entity entityTarget = null; - - TagInfo info = null; - Entity tagger = null; - - for(int pass=0;pass<2;pass++) { - int bestDistance = Integer.MAX_VALUE; - int bestIndex = -1; - Vector v = game.getTagInfo(); - for(int i=0;i= wr.toHit.getValue()) { - artyAttacker.aTracker.setModifier - ( weapon, - ToHitData.AUTOMATIC_SUCCESS, - targetPos ); - } - // If the shot missed, but was adjusted by a - // spotter, future shots are more likely to hit. - else if (null != bestSpotter) { - artyAttacker.aTracker.setModifier - ( weapon, - artyAttacker.aTracker.getModifier - ( weapon, targetPos ) - 1, - targetPos ); - } - - } // End artyAttacker-alive - } - - // Schedule this attack to be resolved. - results.addElement(wr); - attacks.addElement( aaa ); - - } // End attack-hits-this-turn - - // This attack is one round closer to hitting. - aaa.turnsTilHit--; - - } // Handle the next attack - - // loop through weapon results and resolve - int lastEntityId = Entity.NONE; - for (Enumeration i = results.elements();i.hasMoreElements();) { - WeaponResult wr = (WeaponResult) i.nextElement(); - resolveWeaponAttack(wr, lastEntityId); - lastEntityId = wr.waa.getEntityId(); - } - - // Clear out all resolved attacks. - for (Enumeration i = attacks.elements(); i.hasMoreElements();) { - game.removeArtilleryAttack - ( (ArtilleryAttackAction) i.nextElement() ); - } - for(Enumeration i = game.getPlayers();i.hasMoreElements();) { - Player player = (Player)i.nextElement(); - int connId = player.getId(); - send(connId, createArtilleryPacket(player)); - } - } - - /** - * enqueues any indirect artillery attacks made this turn - */ - private void enqueueIndirectArtilleryAttacks() { - resolveAllButWeaponAttacks(); - ArtilleryAttackAction aaa; - for (Enumeration i = game.getActions();i.hasMoreElements();) { - EntityAction ea = (EntityAction) i.nextElement(); - final Entity firingEntity = game.getEntity(ea.getEntityId()); - if (ea instanceof WeaponAttackAction) { - final WeaponAttackAction waa = (WeaponAttackAction) ea; - WeaponResult wr = preTreatWeaponAttack(waa); - boolean firingAtNewHex = false; - for (Enumeration j = game.getArtilleryAttacks(); - !firingAtNewHex && j.hasMoreElements();) { - ArtilleryAttackAction oaaa = (ArtilleryAttackAction) j.nextElement(); - if ( oaaa.getWR().waa.getEntityId() == wr.waa.getEntityId() && - !oaaa.getWR().waa.getTarget(game).getPosition().equals(wr.waa.getTarget(game).getPosition())) { - firingAtNewHex = true; - } - } - if (firingAtNewHex) { - clearArtillerySpotters( firingEntity.getId(), - waa.getWeaponId() ); - } - Enumeration spotters = game.getSelectedEntities(new EntitySelector() { - public int player = firingEntity.getOwnerId(); - public Targetable target = waa.getTarget(game); - public boolean accept(Entity entity) { - if ( (player == entity.getOwnerId()) && - !((LosEffects.calculateLos(game, entity.getId(), target)).isBlocked()) && entity.isActive()) { - return true; - } else { - return false; - } - - } - } ); - - Vector spotterIds = new Vector(); - while ( spotters.hasMoreElements() ) { - Integer id = new Integer - ( ((Entity) spotters.nextElement() ).getId() ); - spotterIds.addElement( id ); - } - aaa = new ArtilleryAttackAction( wr, game, - firingEntity.getOwnerId(), - spotterIds, firingEntity.getPosition()); - game.addArtilleryAttack(aaa); - } - } - game.resetActions(); - for(Enumeration i = game.getPlayers();i.hasMoreElements();) { - Player player = (Player)i.nextElement(); - int connId = player.getId(); - send(connId, createArtilleryPacket(player)); - } - } - - /** - * Credits a Kill for an entity, if the target got killed. - * - * @param target The Entity that got killed. - * @param attacker The Entity that did the killing. - */ - private void creditKill(Entity target, Entity attacker) { - if (target.isDoomed() && !target.getGaveKillCredit()) { - attacker.addKill(target); - } - } - - /** - * pre-treats a physical attack - * - * @param aaa The AbstractAttackAction of the physical attack - * to pre-treat - * - * @return The PhysicalResult of that action, including - * possible damage. - */ - private PhysicalResult preTreatPhysicalAttack(AbstractAttackAction aaa) { - final Entity ae = game.getEntity(aaa.getEntityId()); - int damage = 0; - PhysicalResult pr = new PhysicalResult(); - ToHitData toHit = new ToHitData(); - pr.roll = Compute.d6(2); - pr.aaa = aaa; - if (aaa instanceof BrushOffAttackAction) { - BrushOffAttackAction baa = (BrushOffAttackAction)aaa; - int arm = baa.getArm(); - baa.setArm(BrushOffAttackAction.LEFT); - toHit = BrushOffAttackAction.toHit(game, aaa.getEntityId(), aaa.getTarget(game), BrushOffAttackAction.LEFT); - baa.setArm(BrushOffAttackAction.RIGHT); - pr.toHitRight = BrushOffAttackAction.toHit(game, aaa.getEntityId(), aaa.getTarget(game), BrushOffAttackAction.RIGHT); - damage = BrushOffAttackAction.getDamageFor(ae, BrushOffAttackAction.LEFT); - pr.damageRight = BrushOffAttackAction.getDamageFor(ae, BrushOffAttackAction.RIGHT); - baa.setArm(arm); - pr.rollRight = Compute.d6(2); - } else if (aaa instanceof ChargeAttackAction) { - ChargeAttackAction caa = (ChargeAttackAction)aaa; - toHit = caa.toHit(game); - damage = ChargeAttackAction.getDamageFor(ae); - } else if (aaa instanceof ClubAttackAction) { - ClubAttackAction caa = (ClubAttackAction)aaa; - toHit = caa.toHit(game); - damage = ClubAttackAction.getDamageFor(ae, caa.getClub()); - } else if (aaa instanceof DfaAttackAction) { - DfaAttackAction daa = (DfaAttackAction)aaa; - toHit = daa.toHit(game); - damage = DfaAttackAction.getDamageFor(ae); - } else if (aaa instanceof KickAttackAction) { - KickAttackAction kaa = (KickAttackAction)aaa; - toHit = kaa.toHit(game); - damage = KickAttackAction.getDamageFor(ae, kaa.getLeg()); - } else if (aaa instanceof ProtomechPhysicalAttackAction) { - ProtomechPhysicalAttackAction paa = (ProtomechPhysicalAttackAction)aaa; - toHit = paa.toHit(game); - damage = ProtomechPhysicalAttackAction.getDamageFor(ae); - } else if (aaa instanceof PunchAttackAction) { - PunchAttackAction paa = (PunchAttackAction)aaa; - int arm = paa.getArm(); - int damageRight = 0; - paa.setArm(PunchAttackAction.LEFT); - toHit = paa.toHit(game); - paa.setArm(PunchAttackAction.RIGHT); - ToHitData toHitRight = paa.toHit(game); - damage = PunchAttackAction.getDamageFor(ae, PunchAttackAction.LEFT); - damageRight = PunchAttackAction.getDamageFor(ae, PunchAttackAction.RIGHT); - paa.setArm(arm); - // If we're punching while prone (at a Tank, - // duh), then we can only use one arm. - if ( ae.isProne() ) { - double oddsLeft = Compute.oddsAbove(toHit.getValue()); - double oddsRight = Compute.oddsAbove(toHitRight.getValue()); - // Use the best attack. - if ( oddsLeft*damage > oddsRight*damageRight ) { - paa.setArm(PunchAttackAction.LEFT); - } else paa.setArm(PunchAttackAction.RIGHT); - } - pr.damageRight = damageRight; - pr.toHitRight = toHitRight; - pr.rollRight = Compute.d6(2); - } else if (aaa instanceof PushAttackAction) { - PushAttackAction paa = (PushAttackAction)aaa; - toHit = paa.toHit(game); - } else if (aaa instanceof LayExplosivesAttackAction) { - LayExplosivesAttackAction leaa = (LayExplosivesAttackAction)aaa; - toHit = leaa.toHit(game); - damage = LayExplosivesAttackAction.getDamageFor(ae); - } else if (aaa instanceof ThrashAttackAction) { - ThrashAttackAction taa = (ThrashAttackAction)aaa; - toHit = taa.toHit(game); - damage = ThrashAttackAction.getDamageFor(ae); - } - pr.toHit = toHit; - pr.damage = damage; - return pr; - } - - /** - * Resolve a Physical Attack - * - * @param pr The PhysicalResult of the physical attack - * @param cen The int Entity Id of the entit's whose - * physical attack was last resolved - */ - private void resolvePhysicalAttack(PhysicalResult pr, int cen) { - AbstractAttackAction aaa = pr.aaa; - if (aaa instanceof PunchAttackAction) { - PunchAttackAction paa = (PunchAttackAction)aaa; - if (paa.getArm() == PunchAttackAction.BOTH) { - paa.setArm(PunchAttackAction.LEFT); - pr.aaa = paa; - resolvePunchAttack(pr, cen); - cen = paa.getEntityId(); - paa.setArm(PunchAttackAction.RIGHT); - pr.aaa = paa; - resolvePunchAttack(pr, cen); - } else { - resolvePunchAttack(pr, cen); - cen = paa.getEntityId(); - } - } else if (aaa instanceof KickAttackAction) { - resolveKickAttack(pr, cen); - cen = aaa.getEntityId(); - } else if (aaa instanceof BrushOffAttackAction) { - BrushOffAttackAction baa = (BrushOffAttackAction)aaa; - if (baa.getArm() == BrushOffAttackAction.BOTH) { - baa.setArm(BrushOffAttackAction.LEFT); - pr.aaa = baa; - resolveBrushOffAttack(pr, cen); - cen = baa.getEntityId(); - baa.setArm(BrushOffAttackAction.RIGHT); - pr.aaa = baa; - resolveBrushOffAttack(pr, cen); - } else { - resolveBrushOffAttack(pr, cen); - cen = baa.getEntityId(); - } - } else if (aaa instanceof ThrashAttackAction) { - resolveThrashAttack(pr, cen); - cen = aaa.getEntityId(); - } else if (aaa instanceof ProtomechPhysicalAttackAction) { - resolveProtoAttack(pr, cen); - cen = aaa.getEntityId(); - } else if (aaa instanceof ClubAttackAction) { - resolveClubAttack(pr, cen); - cen = aaa.getEntityId(); - } else if (aaa instanceof PushAttackAction) { - resolvePushAttack(pr, cen); - cen = aaa.getEntityId(); - } else if (aaa instanceof ChargeAttackAction) { - resolveChargeAttack(pr, cen); - cen = aaa.getEntityId(); - } else if (aaa instanceof DfaAttackAction) { - resolveDfaAttack(pr, cen); - cen = aaa.getEntityId(); - } else if (aaa instanceof LayExplosivesAttackAction) { - resolveLayExplosivesAttack(pr, cen); - cen = aaa.getEntityId(); - } else { - // hmm, error. - } - // Not all targets are Entities. - Targetable target = game.getTarget( aaa.getTargetType(), - aaa.getTargetId() ); - if ( target instanceof Entity ) { - creditKill( (Entity) target, game.getEntity(cen) ); - } - } - - /** - * Add any extreme gravity PSRs the entity gets due to its movement - * - * @param entity The Entity to check. - * @param step The last MoveStep of this entity - * @param curPos The current Coords of this entity - * @param cachedMaxMPExpenditure Server checks run/jump MP at start of move, as appropriate, caches to avoid mid-move change in MP causing erroneous grav check - */ - private void checkExtremeGravityMovement(Entity entity, MoveStep step, Coords curPos, int cachedMaxMPExpenditure) { - PilotingRollData rollTarget; - if (game.getOptions().floatOption("gravity") != 1) { - if (entity instanceof Mech) { - if (step.getMovementType() == IEntityMovementType.MOVE_WALK - || (step.getMovementType() == IEntityMovementType.MOVE_VTOL_WALK) - || step.getMovementType() == IEntityMovementType.MOVE_RUN - || (step.getMovementType() == IEntityMovementType.MOVE_VTOL_RUN)) { - if (step.getMpUsed() > cachedMaxMPExpenditure) { - // We moved too fast, let's make PSR to see if we get damage - game.addExtremeGravityPSR(entity.checkMovedTooFast(step)); - } - } else if (step.getMovementType() == IEntityMovementType.MOVE_JUMP) { - if (step.getMpUsed() > cachedMaxMPExpenditure) { - // We jumped too far, let's make PSR to see if we get damage - game.addExtremeGravityPSR(entity.checkMovedTooFast(step)); - } else if (game.getOptions().floatOption("gravity") > 1) { - // jumping in high g is bad for your legs - rollTarget = entity.getBasePilotingRoll(); - entity.addPilotingModifierForTerrain(rollTarget, step); - rollTarget.append(new PilotingRollData(entity.getId(), 0, "jumped in high gravity")); - game.addExtremeGravityPSR(rollTarget); - } - } - } else if (entity instanceof Tank) { - if (step.getMovementType() == IEntityMovementType.MOVE_WALK - || (step.getMovementType() == IEntityMovementType.MOVE_VTOL_WALK) - || step.getMovementType() == IEntityMovementType.MOVE_RUN - || (step.getMovementType() == IEntityMovementType.MOVE_VTOL_RUN)) { - // For Tanks, we need to check if the tank had - // more MPs because it was moving along a road. - if ((step.getMpUsed() > cachedMaxMPExpenditure) && !step.isOnlyPavement()) { - game.addExtremeGravityPSR(entity.checkMovedTooFast(step)); - } - else if (step.getMpUsed() > cachedMaxMPExpenditure + 1) { - // If the tank was moving on a road, he got a +1 bonus. - // N.B. The Ask Precentor Martial forum said that a 4/6 - // tank on a road can move 5/7, **not** 5/8. - game.addExtremeGravityPSR(entity.checkMovedTooFast(step)); - } // End tank-has-road-bonus - } - } - } - } - - /** - * Damage the inner structure of a mech's leg / a tank's front. - * This only happens when the Entity fails an extreme Gravity PSR. - * @param entity The Entity to damage. - * @param damage The int amount of damage. - */ - private void doExtremeGravityDamage(Entity entity, int damage) { - HitData hit; - if (entity instanceof BipedMech) { - for (int i = 6; i<=7; i++) { - hit = new HitData (i); - addReport( damageEntity(entity, hit, damage, false, 0, true)); - } - } if (entity instanceof QuadMech) { - for (int i = 4; i<=7; i++) { - hit = new HitData (i); - addReport( damageEntity(entity, hit, damage, false, 0, true)); - } - } else if (entity instanceof Tank) { - hit = new HitData (Tank.LOC_FRONT); - addReport( damageEntity(entity, hit, damage, false, 0, true)); - } - } - - /** - * Eject an Entity. - * @param entity The Entity to eject. - * @param autoEject The boolean state of the entity's auto- - * ejection system - * @return a Vector of report objects for the gamelog. - */ - public Vector ejectEntity(Entity entity, boolean autoEject) { - Vector vDesc = new Vector(); - Report r; - - // An entity can only eject it's crew once. - if (entity.getCrew().isEjected()) - return vDesc; - - // If the crew are already dead, don't bother - if(entity.getCrew().isDead() || entity.getCrew().isDoomed()) - return vDesc; - - // Mek pilots may get hurt during ejection, - // and run around the board afterwards. - if (entity instanceof Mech) { - PilotingRollData rollTarget = new PilotingRollData(entity.getId(), entity.getCrew().getPiloting(), "ejecting"); - if (entity.isProne()) { - rollTarget.addModifier(5, "Mech is prone"); - } - if (entity.getCrew().isUnconscious()) { - rollTarget.addModifier(3, "pilot unconscious"); - } - if (autoEject) { - rollTarget.addModifier(1, "automatic ejection"); - } - if (entity.getInternal(Mech.LOC_HEAD) < 3) { - rollTarget.addModifier(Math.min(3 - entity.getInternal(Mech.LOC_HEAD),2), "Head Internal Structure Damage"); - } - int facing = entity.getFacing(); - Coords targetCoords = entity.getPosition().translated((facing + 3)%6); - IHex targetHex = game.getBoard().getHex(targetCoords); - if (targetHex != null) { - if (targetHex.terrainLevel(Terrains.WATER) > 0 && !(targetHex.containsTerrain(Terrains.ICE))) { - rollTarget.addModifier(-1, "landing in water"); - } else if (targetHex.containsTerrain(Terrains.ROUGH)) { - rollTarget.addModifier(0, "landing in rough"); - } else if (targetHex.containsTerrain(Terrains.RUBBLE)) { - rollTarget.addModifier(0, "landing in rubble"); - } else if (targetHex.terrainLevel(Terrains.WOODS) == 1) { - rollTarget.addModifier(2, "landing in light woods"); - } else if (targetHex.terrainLevel(Terrains.WOODS) == 2) { - rollTarget.addModifier(3, "landing in heavy woods"); - } else if (targetHex.terrainLevel(Terrains.WOODS) == 3) { - rollTarget.addModifier(4, "landing in ultra heavy woods"); - } else if (targetHex.terrainLevel(Terrains.JUNGLE) == 1) { - rollTarget.addModifier(3, "landing in light jungle"); - } else if (targetHex.terrainLevel(Terrains.JUNGLE) == 2) { - rollTarget.addModifier(5, "landing in heavy jungle"); - } else if (targetHex.terrainLevel(Terrains.JUNGLE) == 3) { - rollTarget.addModifier(7, "landing in ultra heavy jungle"); - } else if (targetHex.terrainLevel(Terrains.BLDG_ELEV) > 0) { - rollTarget.addModifier(targetHex.terrainLevel(Terrains.BLDG_ELEV), "landing in a building"); - } else rollTarget.addModifier(-2, "landing in clear terrain"); - } else { - rollTarget.addModifier(-2, "landing off the board"); - } - if (autoEject) { - r = new Report(6395); - r.subject = entity.getId(); - r.addDesc(entity); - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - } - // okay, print the info - r = new Report(2180); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(rollTarget.getLastPlainDesc(), true); - r.indent(3); - vDesc.addElement(r); - // roll - final int diceRoll = Compute.d6(2); - r = new Report(2190); - r.subject = entity.getId(); - r.add(rollTarget.getValueAsString()); - r.add(rollTarget.getDesc()); - r.add(diceRoll); - r.indent(4); - r.newlines = 0; - // create the MechWarrior in any case, for campaign tracking - MechWarrior pilot = new MechWarrior(entity); - pilot.setDeployed(true); - pilot.setId(getFreeEntityId()); - game.addEntity(pilot.getId(), pilot); - send(createAddEntityPacket(pilot.getId())); - // make him not get a move this turn - pilot.setDone(true); - if (diceRoll < rollTarget.getValue()) { - r.choose(false); - vDesc.addElement(r); - Report.addNewline(vDesc); - Vector v = damageCrew(pilot, 1); - if(v.size() > 0) { - r = (Report)v.firstElement(); - r.indent(3); - vDesc.addElement(r); - } - } else { - r.choose(true); - vDesc.addElement(r); - } - if (entity.getCrew().isDoomed()) { - vDesc.addAll( - destroyEntity(pilot, "deadly ejection", false, false)); - } - else { - // Add the pilot as an infantry unit on the battlefield. - if (game.getBoard().contains(targetCoords)) { - pilot.setPosition(targetCoords); -/* Can pilots eject into water??? - ASSUMPTION : They can (because they get a -1 mod to the PSR. - // Did the pilot land in water? - if ( game.getBoard().getHex( targetCoords).levelOf - ( Terrain.WATER ) > 0 ) { - //report missing - desc.append("and the pilot ejects, but lands in water!!!\n"); - //report missing - desc.append(destroyEntity( pilot, "a watery grave", false )); - } else { - //report missing - desc.append("and the pilot ejects safely!\n"); - } -*/ - //report safe ejection - r = new Report(6400); - r.subject = entity.getId(); - r.indent(5); - vDesc.addElement(r); - if (game.getOptions().booleanOption("vacuum")) { - //ended up in a vacuum - r = new Report(6405); - r.subject = entity.getId(); - r.indent(3); - vDesc.addElement(r); - vDesc.addAll( - destroyEntity(pilot, "explosive decompression", false, false)); - } - // Update the entity - this.entityUpdate(pilot.getId()); - // check if the pilot lands in a minefield - doEntityDisplacementMinefieldCheck( pilot, - entity.getPosition(), - targetCoords ); - } else { - //ejects safely - r = new Report(6410); - r.subject = entity.getId(); - r.indent(3); - vDesc.addElement(r); - if (game.getOptions().booleanOption("vacuum")) { - //landed in vacuum - r = new Report(6405); - r.subject = entity.getId(); - r.indent(3); - vDesc.addElement(r); - vDesc.addAll( - destroyEntity(pilot, "explosive decompression", false, false)); - } else { - game.removeEntity( pilot.getId(), IEntityRemovalConditions.REMOVE_IN_RETREAT ); - send(createRemoveEntityPacket(pilot.getId(), IEntityRemovalConditions.REMOVE_IN_RETREAT) ); - } - } - if (game.getOptions().booleanOption("ejected_pilots_flee")) { - game.removeEntity(pilot.getId(), IEntityRemovalConditions.REMOVE_IN_RETREAT); - send(createRemoveEntityPacket(pilot.getId(), IEntityRemovalConditions.REMOVE_IN_RETREAT)); - } - } // Pilot safely ejects. - - } // End entity-is-Mek - - // Mark the entity's crew as "ejected". - entity.getCrew().setEjected( true ); - vDesc.addAll( - destroyEntity(entity, "ejection", true, true)); - - // only remove the unit that ejected manually - if (!autoEject) { - game.removeEntity( entity.getId(), IEntityRemovalConditions.REMOVE_EJECTED ); - send(createRemoveEntityPacket(entity.getId(), IEntityRemovalConditions.REMOVE_EJECTED)); - } - return vDesc; - } - - /** - * Abandon an Entity. - * @param entity The Entity to abandon. - * - * @return a Vector of report objects for the gamelog. - */ - public Vector abandonEntity(Entity entity) { - Vector vDesc = new Vector(); - Report r; - - // An entity can only eject it's crew once. - if (entity.getCrew().isEjected()) - return vDesc; - - if (entity.getCrew().isDoomed()) - return vDesc; - - //Don't make them abandon into vacuum - if (game.getOptions().booleanOption("vacuum")) - return vDesc; - - Coords targetCoords = entity.getPosition(); - - if (entity instanceof Mech) { - // okay, print the info - r = new Report(2027); - r.subject = entity.getId(); - r.add(entity.getCrew().getName()); - r.addDesc(entity); - r.indent(3); - vDesc.addElement(r); - - // create the MechWarrior in any case, for campaign tracking - MechWarrior pilot = new MechWarrior(entity); - pilot.getCrew().setUnconscious(entity.getCrew().isUnconscious()); - pilot.setDeployed(true); - pilot.setId(getFreeEntityId()); - game.addEntity(pilot.getId(), pilot); - send(createAddEntityPacket(pilot.getId())); - // make him not get a move this turn - pilot.setDone(true); - // Add the pilot as an infantry unit on the battlefield. - if (game.getBoard().contains(targetCoords)) - pilot.setPosition(targetCoords); - // Update the entity - this.entityUpdate(pilot.getId()); - // check if the pilot lands in a minefield - doEntityDisplacementMinefieldCheck( pilot, - entity.getPosition(), - targetCoords ); - if (game.getOptions().booleanOption("ejected_pilots_flee")) { - game.removeEntity(pilot.getId(), IEntityRemovalConditions.REMOVE_IN_RETREAT); - send(createRemoveEntityPacket(pilot.getId(), IEntityRemovalConditions.REMOVE_IN_RETREAT)); - } - } // End entity-is-Mek - - // Mark the entity's crew as "ejected". - entity.getCrew().setEjected( true ); - - return vDesc; - } - - /** - * Checks if ejected Mechwarriors are eligible to be picked up, - * and if so, captures them or picks them up - */ - private void resolveMechWarriorPickUp() { - Report r; - - // fetch all mechWarriors that are not picked up - Enumeration mechWarriors = - game.getSelectedEntities( new EntitySelector() { - public boolean accept(Entity entity) { - if (entity instanceof MechWarrior) { - MechWarrior mw = (MechWarrior)entity; - if (mw.getPickedUpById() == Entity.NONE && - !mw.isDoomed() && (mw.getTransportId() == Entity.NONE) ) { - return true; - } - } - return false; - } - } ); - // loop through them, check if they are in a hex occupied by another - // unit - while ( mechWarriors.hasMoreElements() ) { - boolean pickedUp = false; - MechWarrior e = (MechWarrior) mechWarriors.nextElement(); - Enumeration pickupEntities = game.getEntities(e.getPosition()); - while (pickupEntities.hasMoreElements() ) { - Entity pe = (Entity) pickupEntities.nextElement(); - if (pe.isDoomed() || pe.isShutDown() || pe.getCrew().isUnconscious()) { - continue; - } - if (!pickedUp && pe.getOwnerId() == e.getOwnerId() && pe.getId() != e.getId()) { - if (pe instanceof MechWarrior) { - //picked up by friendlies - r = new Report(6415, Report.PUBLIC); //no subject we can use... - r.add(pe.getDisplayName()); - addReport(r); - continue; - } - // Pick up the unit. - pe.pickUp(e); - // The picked unit is being carried by the loader. - e.setPickedUpById(pe.getId()); - e.setPickedUpByExternalId(pe.getExternalId()); - pickedUp = true; - r = new Report(6420, Report.PUBLIC); - r.add(e.getDisplayName()); - r.addDesc(pe); - addReport(r); - } - } - if (!pickedUp) { - Enumeration pickupEnemyEntities = game.getEnemyEntities(e.getPosition(), e); - while (pickupEnemyEntities.hasMoreElements() ) { - Entity pe = (Entity) pickupEnemyEntities.nextElement(); - if (pe.isDoomed() || pe.isShutDown() || - pe.getCrew().isUnconscious()) { - continue; - } - if (pe instanceof MechWarrior) { - //picked up by friendlies - r = new Report(6415, Report.PUBLIC); //no subject we can use... - r.add(pe.getDisplayName()); - addReport(r); - continue; - } - // Capture the unit. - pe.pickUp(e); - // The captured unit is being carried by the loader. - e.setCaptured( true ); - e.setPickedUpById(pe.getId()); - e.setPickedUpByExternalId(pe.getExternalId()); - pickedUp = true; - r = new Report(6420, Report.PUBLIC); - r.add(e.getDisplayName()); - r.addDesc(pe); - addReport(r); - } - } - if (pickedUp) { - // Remove the picked-up unit from the screen. - e.setPosition( null ); - // Update the loaded unit. - this.entityUpdate( e.getId() ); - } - } - } - - /** - * destroy all wheeled and tracked Tanks that got displaced into water - */ - private void resolveSinkVees() { - Enumeration sinkableTanks = - game.getSelectedEntities( new EntitySelector() { - public boolean accept(Entity entity) { - if (entity.isOffBoard()) { - return false; - } - - if (entity instanceof Tank - && (entity.getPosition() != null) - && (entity.getMovementMode() == IEntityMovementMode.TRACKED - || entity.getMovementMode() == IEntityMovementMode.WHEELED ) - && game.getBoard().getHex(entity.getPosition()).terrainLevel(Terrains.WATER) > 0 - && entity.getElevation() < 0) { - return true; - } - return false; - } - }); - while (sinkableTanks.hasMoreElements()) { - Entity e = (Entity)sinkableTanks.nextElement(); - addReport( - destroyEntity(e, "a watery grave", false)); - } - } - - /** - * let all Entities make their "break-free-of-swamp-stickyness" PSR - */ - private void doTryUnstuck() { - if (game.getPhase() != IGame.PHASE_MOVEMENT) - return; - - Report r; - - Enumeration stuckEntities = - game.getSelectedEntities( new EntitySelector() { - public boolean accept(Entity entity) { - if (entity.isStuck()) { - return true; - } - return false; - } - }); - PilotingRollData rollTarget; - while (stuckEntities.hasMoreElements()) { - Entity entity = (Entity)stuckEntities.nextElement(); - rollTarget = entity.getBasePilotingRoll(); - entity.addPilotingModifierForTerrain(rollTarget); - // apart from swamp & liquid magma, -1 modifier - IHex hex = game.getBoard().getHex(entity.getPosition()); - if(!(hex.containsTerrain(Terrains.SWAMP)) - && !(hex.terrainLevel(Terrains.MAGMA) == 2)) { - rollTarget.addModifier(-1, "bogged down"); - } - // okay, print the info - r = new Report(2340); - r.addDesc(entity); - addReport(r); - - // roll - final int diceRoll = Compute.d6(2); - r = new Report(2190); - r.add(rollTarget.getValueAsString()); - r.add(rollTarget.getDesc()); - r.add(diceRoll); - if (diceRoll < rollTarget.getValue()) { - r.choose(false); - } else { - r.choose(true); - entity.setStuck(false); - entity.setCanUnstickByJumping(false); - } - addReport(r); - } - } - - /** - * Remove all iNarc pods from all vehicles that did not - * move and shoot this round - * NOTE: this is not quite what the rules say, the player - * should be able to choose whether or not to remove all iNarc Pods - * that are attached. - */ - private void resolveVeeINarcPodRemoval() { - Enumeration vees = - game.getSelectedEntities( new EntitySelector() { - public boolean accept(Entity entity) { - if (entity instanceof Tank && - entity.mpUsed == 0) { - return true; - } - return false; - } - }); - boolean canSwipePods; - while (vees.hasMoreElements()) { - canSwipePods = true; - Entity entity = (Entity)vees.nextElement(); - for (int i=0;i<=5;i++) { - if ( entity.weaponFiredFrom(i) ) { - canSwipePods = false; - } - } - if (canSwipePods && entity.hasINarcPodsAttached() && - entity.getCrew().isActive()) { - entity.removeAllINarcPods(); - Report r = new Report(2345); - r.addDesc(entity); - addReport(r); - } - } - } - - private void deadEntitiesCleanup() { - //See note above where knownDeadEntities variable is declared - /* - Entity en = null; - for(Enumeration k = game.getGraveyardEntities(); k.hasMoreElements(); en = (Entity) k.nextElement()) { - if (en != null) { - if (!knownDeadEntities.contains(en)) { - knownDeadEntities.add(en); - } - } - } - */ - } - - private void resolveIceBroken(Coords c) { - game.getBoard().getHex(c).removeTerrain(Terrains.ICE); - sendChangedHex(c); - //drop entities on the surface into the water - for(Enumeration entities = game.getEntities(c);entities.hasMoreElements();) { - Entity e = (Entity)entities.nextElement(); - if(e.getElevation() == 0) { - doEntityFall(e, new PilotingRollData(TargetRoll.AUTOMATIC_FAIL)); - } - } - } - - private void checkForVehicleFire(Tank tank, boolean inferno) { - int boomroll = Compute.d6(2); - int penalty = 0; - switch(tank.getMovementMode()) { - case IEntityMovementMode.HOVER: - penalty = 4; - break; - case IEntityMovementMode.VTOL: - case IEntityMovementMode.WHEELED: - penalty = 2; - break; - } - if(inferno) { - boomroll = 12; - } - Report r = new Report(5250); - r.subject = tank.getId(); - r.addDesc(tank); - r.add(8-penalty); - r.add(boomroll); - if (boomroll + penalty < 8) { - //phew! - r.choose(true); - addReport(r); - } else { - //eek - if(!inferno) { - r.choose(false); - addReport(r); - } - if(boomroll + penalty < 10) { - vehicleMotiveDamage(tank, penalty - 1); - } else { - resolveVehicleFire(tank, false); - if(boomroll + penalty >= 12) { - r = new Report(5255); - r.subject = tank.getId(); - r.indent(3); - addReport(r); - tank.setOnFire(); - } - } - } - } - - private void resolveVehicleFire(Tank tank, boolean existingStatus) { - if(existingStatus && !tank.isOnFire()) - return; - for(int i=0;i 0) { - te.setOriginalWalkMP(nMP - 1); - - if (te.getOriginalWalkMP()==0) { - // Hovercraft reduced to 0MP over water sink - if ( te.getMovementMode() == IEntityMovementMode.HOVER && - game.getBoard().getHex( te.getPosition() ).terrainLevel(Terrains.WATER) > 0 && - !(game.getBoard().getHex( te.getPosition() ).containsTerrain(Terrains.ICE))) { - vDesc.addAll( destroyEntity(te, "a watery grave", false) ); - } - } - } - } else { - r = new Report(6140); - r.subject = te.getId(); - vDesc.addElement(r); - te.immobilize(); - // Does the hovercraft sink? - IHex te_hex = game.getBoard().getHex( te.getPosition() ); - if ( te.getMovementMode() == IEntityMovementMode.HOVER && - te_hex.terrainLevel(Terrains.WATER) > 0 && - !(te_hex.containsTerrain(Terrains.ICE))) { - vDesc.addAll( destroyEntity(te, "a watery grave", false) ); - } - if(te instanceof VTOL) { - Report.addNewline(vDesc); - //report problem: add tab - vDesc.addAll( crashVTOL((VTOL)te)); - } - } - addReport(vDesc); - } - - - /** - * Add a whole lotta Reports to the players report queues - * as well as the Master report queue vPhaseReport. - */ - private void addReport(Vector reports){ - //Only bother with player reports if doing double blind. - if ( doBlind()) - for (Enumeration i = connections.elements(); i.hasMoreElements();) { - final Connection conn = (Connection)i.nextElement(); - Player p = game.getPlayer(conn.getId()); - - p.getTurnReport().addAll(filterReportVector(reports,p)); - } - vPhaseReport.addAll(reports); - } - - /** - * Add a single report to the report queue of all players and the master - * vPhaseReport queue - */ - private void addReport(Report report){ - //Only bother with player reports if doing double blind. - if ( doBlind()) - for (Enumeration i = connections.elements(); i.hasMoreElements();) { - final Connection conn = (Connection)i.nextElement(); - Player p = game.getPlayer(conn.getId()); - - p.getTurnReport().addElement(filterReport(report,p,false)); - } - vPhaseReport.addElement(report); - } - - /** - * New Round has started clear everyones report queue - */ - private void clearReports(){ - //Only bother with player reports if doing double blind. - if ( doBlind()) - for (Enumeration i = connections.elements(); i.hasMoreElements();) { - final Connection conn = (Connection)i.nextElement(); - Player p = game.getPlayer(conn.getId()); - - p.getTurnReport().removeAllElements(); - } - vPhaseReport.removeAllElements(); - } - - /** - * make sure all teh new lines that where added to the old vPhaseReport - * get added to all of the players filters - */ - private void addNewLines(){ - //Only bother with player reports if doing double blind. - if ( doBlind()) - for (Enumeration i = connections.elements(); i.hasMoreElements();) { - final Connection conn = (Connection)i.nextElement(); - Player p = game.getPlayer(conn.getId()); - - Report.addNewline(p.getTurnReport()); - } - Report.addNewline(vPhaseReport); - } - - public void doAssaultDrop(Entity entity) { - PilotingRollData psr; - if(entity instanceof Mech) { - psr=entity.getBasePilotingRoll(); - } else { - psr=new PilotingRollData(entity.getId(),4,"landing assault drop"); - } - int roll = Compute.d6(2); - //check for a safe landing - Report r = new Report(2380); - r.subject = entity.getId(); - r.add(entity.getDisplayName(), true); - r.add(psr.getValueAsString()); - r.add(roll); - r.choose(roll >= psr.getValue()); - addReport(r); - if(roll < psr.getValue()) { - int fallHeight = psr.getValue() - roll; - //determine where we really land - int distance = Compute.d6(fallHeight); - Coords c = Compute.scatter(entity.getPosition(), distance); - r = new Report(2385); - r.subject = entity.getId(); - r.add(distance); - r.indent(3); - r.newlines = 0; - addReport(r); - if(fallHeight >=5 || !game.getBoard().contains(c)) { - r = new Report(2386); - addReport(r); - game.removeEntity(entity.getId(),IEntityRemovalConditions.REMOVE_NEVER_JOINED); - return; - } - entity.setPosition(c); - - //do fall damage - if(entity instanceof Mech || entity instanceof Protomech) { - entity.setElevation(fallHeight); - doEntityFallsInto(entity, c, c, psr, true); - } - else if(entity instanceof BattleArmor) { - for(int i=1;i 0 && !eruption)) - && !(en.isImmobile())) { - return; - } - Report r; - boolean isMech = en instanceof Mech; - if(isMech) - r = new Report(2405); - else - r = new Report(2400); - r.addDesc(en); - r.subject = en.getId(); - addReport(r); - if(isMech) { - HitData h; - for(int i=0;i hex.terrainLevel(Terrains.BLDG_ELEV))) { - bldgAbsorbs = bldg.getPhaseCF() / 10; - if(!(ammo != null && ammo.getMunitionType() == AmmoType.M_FLECHETTE)) { - //damage the building - r = damageBuilding( bldg, damage ); - r.subject = subjectId; - addReport(r); - addNewLines(); - } - } - - if(flak - && (flakElevation <= 0 - || flakElevation <= hex.terrainLevel(Terrains.BLDG_ELEV) - || flakElevation == hex.terrainLevel(Terrains.BRIDGE_ELEV))) { - //Flak in this hex would only hit landed units - return; - } - - // get units in hex - for (Enumeration impactHexHits = game.getEntities(coords);impactHexHits.hasMoreElements();) { - Entity entity = (Entity)impactHexHits.nextElement(); - int hits = damage; - ToHitData toHit = new ToHitData(); - int cluster = 5; - - //Check: is entity excluded? - if(entity == exclude) - continue; - - //Check: is entity inside building? - if(bldg != null && - bldgAbsorbs > 0 && - entity.getElevation() < hex.terrainLevel(Terrains.BLDG_ELEV)) { - cluster -= bldgAbsorbs; - if(entity instanceof Infantry) { - continue; //took its damage already from building damage - } - else if(cluster <= 0) { - //entity takes no damage - r = new Report(6426); - r.subject = subjectId; - r.addDesc(entity); - addReport(r); - continue; - } else { - r = new Report(6425); - r.subject = subjectId; - r.add(bldgAbsorbs); - addReport(r); - } - } - - if(flak) { - //Check: is entity not a VTOL in flight - if (!(entity instanceof VTOL || - entity.getMovementMode()==IEntityMovementMode.VTOL)) { - continue; - } - //Check: is entity at correct elevation? - if(entity.getElevation() != flakElevation) - continue; - } else { - //Check: is entity a VTOL in flight? - if (entity instanceof VTOL || - entity.getMovementMode()==IEntityMovementMode.VTOL) { - // VTOLs take no damage from normal artillery unless landed - if (entity.getElevation()!=0 - && entity.getElevation()!=hex.terrainLevel(Terrains.BLDG_ELEV) - && entity.getElevation()!=hex.terrainLevel(Terrains.BRIDGE_ELEV)) { - continue; - } - } - } - - //Work out hit table to use - if (attackSource!=null) { - toHit.setSideTable(entity.sideTable(attackSource)); - if(ammo != null - && entity instanceof Mech - && ammo.getMunitionType() == AmmoType.M_CLUSTER - && attackSource.equals(coords)) { - toHit.setHitTable(ToHitData.HIT_ABOVE); - } - } - - //Entity/ammo specific damage modifiers - if(ammo != null) { - if(ammo.getMunitionType() == AmmoType.M_CLUSTER) { - if(hex.containsTerrain(Terrains.FORTIFIED) - && entity instanceof Infantry - && !(entity instanceof BattleArmor)) { - hits *= 2; - } - if(hex.containsTerrain(Terrains.WOODS) - || hex.containsTerrain(Terrains.JUNGLE)) { - hits = (hits + 1) / 2; - } - } - else if(ammo.getMunitionType() == AmmoType.M_FLECHETTE) { - //wheeled and hover tanks take movement critical - if(entity instanceof Tank && - (entity.getMovementMode() == IEntityMovementMode.WHEELED || - entity.getMovementMode() == IEntityMovementMode.HOVER)) { - r = new Report(6480); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(toHit.getTableDesc()); - r.add(0); - addReport(r); - vehicleMotiveDamage((Tank)entity, 0); - continue; - } - //non infantry are immune - if(entity instanceof BattleArmor || - !(entity instanceof Infantry)) { - continue; - } - if(hex.containsTerrain(Terrains.WOODS) - || hex.containsTerrain(Terrains.JUNGLE)) { - hits = (hits + 1) / 2; - } - } - } - - //Do the damage - addNewLines(); - r = new Report(6480); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(toHit.getTableDesc()); - r.add(hits); - addReport(r); - while(hits>0) { - HitData hit = entity.rollHitLocation(toHit.getHitTable(), toHit.getSideTable()); - - addReport( damageEntity(entity, hit, Math.min(cluster, hits), false, 0, false, true, false)); - hits -= Math.min(5,hits); - } - if(killer != null) { - creditKill(entity, killer); - } - addNewLines(); - } - } - - /** - * deal area saturation damage to the map, used for artillery - * @param centre The hex on which damage is centred - * @param attackSource The position the attack came from - * @param ammo The ammo type doing the damage - * @param subjectId Subject for reports - * @param killer Who should be credited with kills - * @param flak Flak, hits flying units only, instead of flyers being immune - * @param altitude Absolute altitude for flak attack - */ - void artilleryDamageArea(Coords centre, Coords attackSource, AmmoType ammo, int subjectId, Entity killer, boolean flak, int altitude) { - int damage; - int falloff=5; - if(ammo.getMunitionType() == AmmoType.M_FLECHETTE) { - damage = ammo.getRackSize() + 10; - } - else if(ammo.getMunitionType() == AmmoType.M_CLUSTER) { - if(ammo.getAmmoType() == AmmoType.T_SNIPER) - damage = 15; - else - damage = ammo.getRackSize(); - attackSource = centre; - } - else if(game.getOptions().booleanOption("maxtech_artillery")) { - //"standard" mutates into high explosive - if(ammo.getAmmoType() == AmmoType.T_LONG_TOM) - damage = 25; - else - damage = ammo.getRackSize() + 10; - falloff = 10; - } - else { - //level 2 ammo - damage = ammo.getRackSize(); - falloff = (damage + 1) / 2; - } - artilleryDamageArea(centre, attackSource, ammo, subjectId, killer, damage, falloff, flak, altitude); - } - - /** - * Deals area-saturation damage to an area of the board. - * Used for artillery, bombs, or anything else with linear decreas in damage - * @param centre The hex on which damage is centred - * @param attackSource The position the attack came from - * @param ammo The ammo type doing the damage - * @param subjectId Subject for reports - * @param killer Who should be credited with kills - * @param damage Damage at ground zero - * @param falloff Reduction in damage for each hex of distance - * @param flak Flak, hits flying units only, instead of flyers being immune - * @param altitude Absolute altitude for flak attack - */ - void artilleryDamageArea(Coords centre, Coords attackSource, AmmoType ammo, int subjectId, Entity killer, int damage, int falloff, boolean flak, int altitude) { - for(int ring=0;damage > 0;ring++,damage-=falloff) { - ArrayList hexes = Compute.coordsAtRange(centre, ring); - for(Coords c : hexes) { - artilleryDamageHex(c, attackSource, damage, ammo, subjectId, killer, null, flak, altitude); - } - attackSource = centre; // all splash comes from ground zero - } - } -} - diff --git a/java/cvsvintage/Server_1.925_1.926_v1.java b/java/cvsvintage/Server_1.925_1.926_v1.java deleted file mode 100644 index 271da48..0000000 --- a/java/cvsvintage/Server_1.925_1.926_v1.java +++ /dev/null @@ -1,18151 +0,0 @@ -/* - * MegaMek - - * Copyright (C) 2000,2001,2002,2003,2004,2005 Ben Mazur (bmazur@sev.org) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -package megamek.server; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.UnknownHostException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.StringTokenizer; -import java.util.Vector; - -import megamek.*; -import megamek.common.*; -import megamek.common.actions.*; -import megamek.server.commands.*; -import megamek.common.net.*; -import megamek.common.options.*; -import megamek.common.util.BoardUtilities; -import megamek.common.util.StringUtil; -import megamek.common.verifier.EntityVerifier; -import megamek.common.verifier.TestEntity; -import megamek.common.verifier.TestMech; -import megamek.common.verifier.TestTank; -import megamek.common.TagInfo; -import megamek.common.preference.PreferenceManager; - -/** - * @author Ben Mazur - */ -public class Server implements Runnable { - // public final static String LEGAL_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.-"; - public final static String DEFAULT_BOARD = MapSettings.BOARD_SURPRISE; - private final static String VERIFIER_CONFIG_FILENAME = - "data/mechfiles/UnitVerifierOptions.xml"; - - // server setup - private String password; - private ServerSocket serverSocket; - private String motd; - - // game info - private Vector connections = new Vector(4); - private Vector connectionsPending = new Vector(4); - private Hashtable connectionIds = new Hashtable(); - - private int connectionCounter = 0; - private int entityCounter = 0; - - private IGame game = new Game(); - - private Vector vPhaseReport = new Vector(); - - private MapSettings mapSettings = new MapSettings(); - - // commands - private Hashtable commandsHash = new Hashtable(); - - // listens for and connects players - private Thread connector; - - // Track buildings that are affected by an entity's movement. - private Hashtable affectedBldgs = new Hashtable(); - - // Track Physical Action results, HACK to deal with opposing pushes - // canceling each other - private Vector physicalResults = new Vector(); - - private Vector terrainProcessors = new Vector(); - - /* Tracks entities which have been destroyed recently. Allows refactoring of the - * damage and kill logic from Server, where it is now, to the Entity subclasses eventually. - * This has not been implemented yet -- I am just starting to build the groundwork into Server. - * It isn't in the execution path and shouldn't cause any bugs */ - //Note from another coder - I have commented out your groundwork - //for now because it is using HashSet, which isn't available in - //Java 1.1 unless you import the collections classes. Since the - //Server class isn't using any other collecitons classes, there - //might be a reason we're avoiding them here...if not, feel free - //to add the import. - //private HashSet knownDeadEntities = new HashSet(); - - private static EntityVerifier entityVerifier = null; - - private ConnectionListenerAdapter connectionListener = new ConnectionListenerAdapter() { - - /** - * Called when it is sensed that a connection has terminated. - */ - public void disconnected(DisconnectedEvent e) { - Connection conn = e.getConnection(); - - // write something in the log - System.out.println("s: connection " + conn.getId()+ " disconnected"); - - connections.removeElement(conn); - connectionsPending.removeElement(conn); - connectionIds.remove(new Integer(conn.getId())); - - // if there's a player for this connection, remove it too - Player player = getPlayer(conn.getId()); - if (null != player) { - Server.this.disconnected( player ); - } - - } - - public void packetReceived(PacketReceivedEvent e) { - Server.this.handle(e.getConnection().getId(),e.getPacket()); - } - - }; - - /** - * Construct a new GameHost and begin listening for - * incoming clients. - * @param password the String that is set as a password - * @param port the int value that specifies the port that - * is used - */ - public Server(String password, int port) { - this.password = password.length() > 0 ? password : null; - // initialize server socket - try { - serverSocket = new ServerSocket(port); - } catch(IOException ex) { - System.err.println("could not create server socket on port "+port); - } - - motd = createMotd(); - - game.getOptions().initialize(); - - changePhase(IGame.PHASE_LOUNGE); - - // display server start text - System.out.println("s: starting a new server..."); - - try { - String host = InetAddress.getLocalHost().getHostName(); - System.out.print("s: hostname = '" ); - System.out.print( host ); - System.out.print( "' port = " ); - System.out.println( serverSocket.getLocalPort() ); - InetAddress[] addresses = InetAddress.getAllByName(host); - for (int i = 0; i < addresses.length; i++) { - System.out.println("s: hosting on address = " - + addresses[i].getHostAddress()); - } - } catch (UnknownHostException e) { - // oh well. - } - - System.out.println("s: password = " + this.password); - - connector = new Thread(this, "Connection Listener"); - connector.start(); - - // register commands - registerCommand(new DefeatCommand(this)); - registerCommand(new HelpCommand(this)); - registerCommand(new KickCommand(this)); - registerCommand(new ResetCommand(this)); - registerCommand(new RollCommand(this)); - registerCommand(new SaveGameCommand(this)); - registerCommand(new SkipCommand(this)); - registerCommand(new VictoryCommand(this)); - registerCommand(new WhoCommand(this)); - registerCommand(new SeeAllCommand(this)); - registerCommand(new LocalSaveGameCommand(this)); - registerCommand(new FixElevationCommand(this)); - - //register terrain processors - terrainProcessors.add(new FireProcessor(this)); - terrainProcessors.add(new GeyserProcessor(this)); - terrainProcessors.add(new ElevatorProcessor(this)); - } - - /** - * Sets the game for this server. Restores any transient fields, and sets - * all players as ghosts. - * This should only be called during server initialization before any - * players have connected. - */ - public void setGame(IGame g) { - this.game = g; - - // reattach the transient fields and ghost the players - for (Enumeration e = game.getEntities(); e.hasMoreElements(); ) { - Entity ent = (Entity)e.nextElement(); - ent.setGame(game); - } - game.setOutOfGameEntitiesVector(game.getOutOfGameEntitiesVector()); - for (Enumeration e = game.getPlayers(); e.hasMoreElements(); ) { - Player p = (Player)e.nextElement(); - p.setGame(game); - p.setGhost(true); - } - - } - - /** Returns the current game object */ - public IGame getGame() { - return game; - } - - /** - * Make a default message o' the day containing the version string, and - * if it was found, the build timestamp - */ - private String createMotd() { - StringBuffer buf = new StringBuffer(); - buf.append("Welcome to MegaMek. Server is running version "); - buf.append(MegaMek.VERSION); - buf.append(", build date "); - if (MegaMek.TIMESTAMP > 0L) { - buf.append(new Date(MegaMek.TIMESTAMP).toString()); - } else { - buf.append("unknown"); - } - buf.append("."); - - return buf.toString(); - } - - /** - * @return true if the server has a password - */ - public boolean isPassworded() { - return password != null; - } - - /** - * @return true if the password matches - */ - public boolean isPassword(Object guess) { - return password.equals(guess); - } - - /** - * Registers a new command in the server command table - */ - private void registerCommand(ServerCommand command) { - commandsHash.put(command.getName(), command); - } - - /** - * Returns the command associated with the specified name - */ - public ServerCommand getCommand(String name) { - return (ServerCommand)commandsHash.get(name); - } - - /** - * Shuts down the server. - */ - public void die() { - // kill thread accepting new connections - connector = null; - - // close socket - try { - serverSocket.close(); - } catch(IOException ex) {} - - // kill pending connnections - for (Enumeration i=connectionsPending.elements();i.hasMoreElements();){ - final Connection conn = (Connection)i.nextElement(); - conn.close(); - } - connectionsPending.removeAllElements(); - - // Send "kill" commands to all connections - // N.B. I may be starting a race here. - for (Enumeration i = connections.elements(); i.hasMoreElements();) { - final Connection conn = (Connection)i.nextElement(); - send(conn.getId(), new Packet(Packet.COMMAND_CLOSE_CONNECTION)); - } - - // kill active connnections - for (Enumeration i = connections.elements(); i.hasMoreElements();) { - final Connection conn = (Connection)i.nextElement(); - conn.close(); - } - connections.removeAllElements(); - connectionIds.clear(); - } - - /** - * Returns an enumeration of all the command names - */ - public Enumeration getAllCommandNames() { - return commandsHash.keys(); - } - - /** - * Sent when a client attempts to connect. - */ - private void greeting(int cn) { - // send server greeting -- client should reply with client info. - sendToPending(cn, new Packet(Packet.COMMAND_SERVER_GREETING)); - } - - /** - * Returns a free connection id. - */ - public int getFreeConnectionId() { - while (getPendingConnection(connectionCounter) != null - || getConnection(connectionCounter) != null - || getPlayer(connectionCounter) != null) { - connectionCounter++; - } - return connectionCounter; - } - - /** - * Returns a free entity id. Perhaps this should be in Game instead. - */ - public int getFreeEntityId() { - return game.getNextEntityId(); - } - - /** - * Allow the player to set whatever parameters he is able to - */ - private void receivePlayerInfo(Packet packet, int connId) { - Player player = (Player)packet.getObject(0); - Player connPlayer = game.getPlayer( connId ); - if ( null != connPlayer ) { - connPlayer.setColorIndex(player.getColorIndex()); - connPlayer.setStartingPos(player.getStartingPos()); - connPlayer.setTeam(player.getTeam()); - connPlayer.setCamoCategory(player.getCamoCategory()); - connPlayer.setCamoFileName(player.getCamoFileName()); - connPlayer.setNbrMFConventional(player.getNbrMFConventional()); - connPlayer.setNbrMFCommand(player.getNbrMFCommand()); - connPlayer.setNbrMFVibra(player.getNbrMFVibra()); - } - } - - private String correctDupeName(String oldName) { - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - Player player = (Player)i.nextElement(); - if (player.getName().equals(oldName)) { - // We need to correct it. - String newName = oldName; - int dupNum = 2; - try { - dupNum = Integer.parseInt(oldName.substring(oldName.lastIndexOf(".")+1)); - dupNum++; - newName = oldName.substring(0,oldName.lastIndexOf(".")); - } catch (Exception e) { - // If this fails, we don't care much. - // Just assume it's the first time for this name. - dupNum = 2; - } - newName = newName.concat(".").concat(Integer.toString(dupNum)); - return correctDupeName(newName); - } - } - return oldName; - } - - /** - * Recieves a player name, sent from a pending connection, and connects - * that connection. - */ - private void receivePlayerName(Packet packet, int connId) { - final Connection conn = getPendingConnection(connId); - String name = (String)packet.getObject(0); - boolean returning = false; - - // this had better be from a pending connection - if (conn == null) { - System.out.println("server: got a client name from a non-pending" + - " connection"); - return; - } - - // check if they're connecting with the same name as a ghost player - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - Player player = (Player)i.nextElement(); - if (player.getName().equals(name)) { - if (player.isGhost()) { - returning = true; - player.setGhost(false); - // switch id - connId = player.getId(); - conn.setId(connId); - } - } - } - - if (!returning) { - // Check to avoid duplicate names... - name = correctDupeName(name); - send(connId, new Packet(Packet.COMMAND_SERVER_CORRECT_NAME, name)); - } - - // right, switch the connection into the "active" bin - connectionsPending.removeElement(conn); - connections.addElement(conn); - connectionIds.put(new Integer(conn.getId()), conn); - - // add and validate the player info - if (!returning) { - game.addPlayer(connId, new Player(connId, name)); - validatePlayerInfo(connId); - } - - // if it is not the lounge phase, this player becomes an observer - Player player = getPlayer( connId ); - if ( game.getPhase() != IGame.PHASE_LOUNGE - && null != player - && game.getEntitiesOwnedBy(player) < 1) { - player.setObserver(true); - } - - // send the player the motd - sendServerChat(connId, motd); - - // send info that the player has connected - send(createPlayerConnectPacket(connId)); - - // tell them their local playerId - send(connId, new Packet(Packet.COMMAND_LOCAL_PN, new Integer(connId))); - - // send current game info - sendCurrentInfo(connId); - - try { - InetAddress[] addresses = InetAddress.getAllByName(InetAddress - .getLocalHost() - .getHostName()); - for (int i = 0; i < addresses.length; i++) { - sendServerChat(connId, "Machine IP is " + - addresses[i].getHostAddress()); - } - } catch (UnknownHostException e) { - // oh well. - } - - // Send the port we're listening on. Only useful for the player - // on the server machine to check. - sendServerChat(connId, "Listening on port " + serverSocket - .getLocalPort()); - - // Get the player *again*, because they may have disconnected. - player = getPlayer( connId ); - if ( null != player ) { - StringBuffer buff = new StringBuffer(); - buff.append( player.getName() ) - .append( " connected from " ) - .append( getClient(connId).getInetAddress() ); - String who = buff.toString(); - System.out.print( "s: player #" ); - System.out.print( connId ); - System.out.print( ", " ); - System.out.println( who ); - - sendServerChat( who ); - - } // Found the player - } - - /** - * Sends a player the info they need to look at the current phase. - * This is triggered when a player first connects to the server. - */ - private void sendCurrentInfo(int connId) { - //why are these two outside the player != null check below? - transmitAllPlayerConnects(connId); - send(connId, createGameSettingsPacket()); - - Player player = game.getPlayer(connId); - if ( null != player ) { - send(connId, new Packet(Packet.COMMAND_SENDING_MINEFIELDS, - player.getMinefields())); - - switch (game.getPhase()) { - case IGame.PHASE_LOUNGE : - send(connId, createMapSettingsPacket()); - // Send Entities *after* the Lounge Phase Change - send(connId, new Packet(Packet.COMMAND_PHASE_CHANGE, - new Integer(game.getPhase()))); - if (doBlind()) { - send(connId, createFilteredFullEntitiesPacket(player)); - } - else { - send(connId, createFullEntitiesPacket()); - } - break; - default : - send(connId, new Packet(Packet.COMMAND_ROUND_UPDATE, new Integer(game.getRoundCount()))); - //send(connId, createReportPacket(player)); - send(connId, createAllReportsPacket(player)); - - // Send Entites *before* other phase changes. - if (doBlind()) { - send(connId, createFilteredFullEntitiesPacket(player)); - } - else { - send(connId, createFullEntitiesPacket()); - } - player.setDone( game.getEntitiesOwnedBy(player) <= 0 ); - send(connId, createBoardPacket()); - send(connId, new Packet(Packet.COMMAND_PHASE_CHANGE, - new Integer(game.getPhase()))); - break; - } - if (game.getPhase() == IGame.PHASE_FIRING || - game.getPhase() == IGame.PHASE_TARGETING || - game.getPhase() == IGame.PHASE_OFFBOARD || - game.getPhase() == IGame.PHASE_PHYSICAL) { - // can't go above, need board to have been sent - send(connId,createAttackPacket(game.getActionsVector(),0)); - send(connId,createAttackPacket(game.getChargesVector(),1)); - send(connId,createAttackPacket(game.getLayMinefieldActionsVector(),2)); - } - if (game.phaseHasTurns(game.getPhase())) { - send(connId, createTurnVectorPacket()); - send(connId, createTurnIndexPacket()); - } - - send(connId, createArtilleryPacket(player)); - send(connId, createFlarePacket()); - - } // Found the player. - - } - - /** - * Validates the player info. - */ - public void validatePlayerInfo(int playerId) { - final Player player = getPlayer(playerId); - - // maybe this isn't actually useful - // // replace characters we don't like with "X" - // StringBuffer nameBuff = new StringBuffer(player.getName()); - // for (int i = 0; i < nameBuff.length(); i++) { - // int chr = nameBuff.charAt(i); - // if (LEGAL_CHARS.indexOf(chr) == -1) { - // nameBuff.setCharAt(i, 'X'); - // } - // } - // player.setName(nameBuff.toString()); - - //TODO: check for duplicate or reserved names - - // make sure colorIndex is unique - boolean[] colorUsed = new boolean[Player.colorNames.length]; - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - final Player otherPlayer = (Player)i.nextElement(); - if (otherPlayer.getId() != playerId) { - colorUsed[otherPlayer.getColorIndex()] = true; - } - } - if (null != player && colorUsed[player.getColorIndex()]) { - // find a replacement color; - for (int i = 0; i < colorUsed.length; i++) { - if (!colorUsed[i]) { - player.setColorIndex(i); - break; - } - } - } - - } - - /** - * Called when it's been determined that an actual player - * disconnected. Notifies the other players and does the appropriate - * housekeeping. - */ - void disconnected(Player player) { - int phase = game.getPhase(); - - // in the lounge, just remove all entities for that player - if (phase == IGame.PHASE_LOUNGE) { - removeAllEntitesOwnedBy(player); - } - - // if a player has active entities, he becomes a ghost - // except the VICTORY_PHASE when the dosconnected - // player is most likely the Bot disconnected after receiving - // the COMMAND_END_OF_GAME command - // see the Bug 1225949. - // TODO Perhaps there is a better solution to handle the Bot disconnect - if (game.getEntitiesOwnedBy(player) > 0 && phase != IGame.PHASE_VICTORY) { - player.setGhost(true); - player.setDone(true); - send(createPlayerUpdatePacket(player.getId())); - } else { - game.removePlayer(player.getId()); - send(new Packet(Packet.COMMAND_PLAYER_REMOVE, - new Integer(player.getId()))); - } - - // make sure the game advances - if ( game.phaseHasTurns(game.getPhase()) && null != game.getTurn() ) { - if ( game.getTurn().isValid( player.getId(), game ) ) { - sendGhostSkipMessage( player ); - } - } else { - checkReady(); - } - - // notify other players - sendServerChat(player.getName() + " disconnected."); - - // log it - System.out.println("s: removed player " + player.getName()); - - // Reset the game after Elvis has left the building. - if ( 0 == game.getNoOfPlayers() ) { - resetGame(); - } - } - - /** - * Checks each player to see if he has no entities, and if true, sets the - * observer flag for that player. An exception is that there are no - * observers during the lounge phase. - */ - public void checkForObservers() { - for (Enumeration e = game.getPlayers(); e.hasMoreElements(); ) { - Player p = (Player)e.nextElement(); - p.setObserver(game.getEntitiesOwnedBy(p) < 1 && - game.getPhase() != IGame.PHASE_LOUNGE); - } - } - - /** - * Reset the game back to the lounge. - * - * TODO: couldn't this be a hazard if there are other things executing at - * the same time? - */ - public void resetGame() { - // remove all entities - game.reset(); - send(createEntitiesPacket()); - send(new Packet(Packet.COMMAND_SENDING_MINEFIELDS, new Vector())); - - //TODO: remove ghosts - - // reset all players - resetPlayersDone(); - transmitAllPlayerDones(); - - // Write end of game to stdout so controlling scripts can rotate logs. - SimpleDateFormat format = new SimpleDateFormat - ( "yyyy-MM-dd HH:mm:ss z" ); - System.out.print( format.format(new Date()) ); - System.out.println( " END OF GAME" ); - - changePhase(IGame.PHASE_LOUNGE); - } - - - /** - * automatically save the game - */ - public void autoSave() { - String fileName = "autosave"; - if (PreferenceManager.getClientPreferences().stampFilenames()) { - fileName = StringUtil.addDateTimeStamp(fileName); - } - saveGame(fileName,game.getOptions().booleanOption("autosave_msg")); - } - - /** - * save the game and send it to the sepecified connection - * @param connId The int connection id to send to - * @param sFile The String filename to use - */ - public void sendSaveGame (int connId, String sFile) { - saveGame(sFile, false); - String sFinalFile = sFile; - if (!sFinalFile.endsWith(".sav")) { - sFinalFile = sFile + ".sav"; - } - sFinalFile = "savegames" + File.separator + sFinalFile; - File f = new File(sFinalFile); - try { - ObjectInputStream ois = new ObjectInputStream( - new FileInputStream(f)); - send(connId,new Packet(Packet.COMMAND_SEND_SAVEGAME, new Object[] {sFinalFile, ois.readObject()})); - sendChat(connId,"***Server","Savegame has been sent to you."); - ois.close(); - } catch (Exception e) { - System.err.println("Unable to load file: " + f); - e.printStackTrace(); - } - } - - /** - * save the game - * @param sFile The String filename to use - * @param sendChat A boolean value wether or not to announce - * the saving to the server chat. - */ - public void saveGame(String sFile, boolean sendChat) { - String sFinalFile = sFile; - if (!sFinalFile.endsWith(".sav")) { - sFinalFile = sFile + ".sav"; - } - try { - File sDir = new File("savegames"); - if (!sDir.exists()) { - sDir.mkdir(); - } - sFinalFile = sDir + File.separator + sFinalFile; - ObjectOutputStream oos = new ObjectOutputStream( - new FileOutputStream(sFinalFile)); - oos.writeObject(game); - oos.flush(); - oos.close(); - } catch (Exception e) { - System.err.println("Unable to save file: " + sFinalFile); - e.printStackTrace(); - } - - if (sendChat) sendChat("MegaMek", "Game saved to " + sFinalFile); - } - - /** - * save the game - * @param sFile The String filename to use - */ - public void saveGame(String sFile) { - saveGame(sFile,true); - } - - /** - * load the game - * @param f The File to load - * @return A boolean value wether or not the loading was successfull - */ - public boolean loadGame(File f) { - System.out.println("s: loading saved game file '"+f+"'"); - try { - ObjectInputStream ois = new ObjectInputStream( - new FileInputStream(f)); - game = (IGame)ois.readObject(); - ois.close(); - } catch (Exception e) { - System.err.println("Unable to load file: " + f); - e.printStackTrace(); - return false; - } - - // a bit redundant, but there's some initialization code there - setGame(game); - - return true; - } - - /** - * Shortcut to game.getPlayer(id) - */ - public Player getPlayer(int id) { - return game.getPlayer(id); - } - - /** - * Removes all entities owned by a player. Should only be called when it - * won't cause trouble (the lounge, for instance, or between phases.) - * @param the Player whose entites are to be removed - */ - private void removeAllEntitesOwnedBy(Player player) { - Vector toRemove = new Vector(); - - for (Enumeration e = game.getEntities(); e.hasMoreElements();) { - final Entity entity = (Entity)e.nextElement(); - - if (entity.getOwner().equals(player)) { - toRemove.addElement(entity); - } - } - - for (Enumeration e = toRemove.elements(); e.hasMoreElements();) { - final Entity entity = (Entity)e.nextElement(); - int id = entity.getId(); - game.removeEntity(id, IEntityRemovalConditions.REMOVE_NEVER_JOINED); - send(createRemoveEntityPacket(id, IEntityRemovalConditions.REMOVE_NEVER_JOINED)); - } - } - - /** - * a shorter name for getConnection() - */ - private Connection getClient(int connId) { - return getConnection(connId); - } - - /** - * Returns a connection, indexed by id - */ - public Enumeration getConnections() { - return connections.elements(); - } - - /** - * Returns a connection, indexed by id - */ - public Connection getConnection(int connId) { - return (Connection)connectionIds.get(new Integer(connId)); - } - - /** - * Returns a pending connection - */ - private Connection getPendingConnection(int connId) { - for (Enumeration i=connectionsPending.elements();i.hasMoreElements();){ - final Connection conn = (Connection)i.nextElement(); - - if (conn.getId() == connId) { - return conn; - } - } - return null; - } - - /** - * Called at the beginning of each game round to reset values on this - * entity that are reset every round - */ - private void resetEntityRound() { - for (Enumeration e = game.getEntities(); e.hasMoreElements();) { - Entity entity = (Entity)e.nextElement(); - - entity.newRound(game.getRoundCount()); - } - } - - /** - * Called at the beginning of each phase. Sets and resets - * any entity parameters that need to be reset. - */ - private void resetEntityPhase(int phase) { - // first, mark doomed entities as destroyed and flag them - Vector toRemove = new Vector(0, 10); - for (Enumeration e = game.getEntities(); e.hasMoreElements();) { - final Entity entity = (Entity)e.nextElement(); - - if (entity.crew.isDoomed()) { - entity.crew.setDead(true); - entity.setDestroyed(true); - } - - if (entity.isDoomed()) { - entity.setDestroyed(true); - - // Is this unit swarming somebody? Better let go before - // it's too late. - final int swarmedId = entity.getSwarmTargetId(); - if ( Entity.NONE != swarmedId ) { - final Entity swarmed = game.getEntity( swarmedId ); - swarmed.setSwarmAttackerId( Entity.NONE ); - entity.setSwarmTargetId( Entity.NONE ); - Report r = new Report(5165); - r.subject = swarmedId; - r.addDesc(swarmed); - addReport(r); - this.entityUpdate( swarmedId ); - } - } - - if (entity.isDestroyed() || entity.getCrew().isDead()) { - toRemove.addElement(entity); - } - } - - // actually remove all flagged entities - for (Enumeration e = toRemove.elements(); e.hasMoreElements();) { - final Entity entity = (Entity)e.nextElement(); - int condition = IEntityRemovalConditions.REMOVE_SALVAGEABLE; - if ( !entity.isSalvage() ) { - condition = IEntityRemovalConditions.REMOVE_DEVASTATED; - } - - this.entityUpdate(entity.getId()); - game.removeEntity(entity.getId(), condition); - send( createRemoveEntityPacket(entity.getId(), condition) ); - } - - // do some housekeeping on all the remaining - for (Enumeration e = game.getEntities(); e.hasMoreElements();) { - final Entity entity = (Entity)e.nextElement(); - - entity.applyDamage(); - - entity.reloadEmptyWeapons(); - - // reset damage this phase - entity.damageThisPhase = 0; - entity.engineHitsThisRound = 0; - entity.rolledForEngineExplosion = false; - entity.dodging = false; - - // reset done to false - - if ( phase == IGame.PHASE_DEPLOYMENT ) { - entity.setDone(!entity.shouldDeploy(game.getRoundCount())); - } else { - entity.setDone(false); - } - - // reset spotlights - entity.setIlluminated(false); - entity.setUsedSearchlight(false); - } - } - - /** - * Called at the beginning of certain phases to make - * every player not ready. - */ - private void resetPlayersDone() { - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - final Player player = (Player)i.nextElement(); - player.setDone(false); - } - } - - /** - * Called at the beginning of certain phases to make - * every active player not ready. - */ - private void resetActivePlayersDone() { - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - final Player player = (Player)i.nextElement(); - - player.setDone(game.getEntitiesOwnedBy(player) <= 0); - - } - transmitAllPlayerDones(); - } - - /** - * Writes the victory report - */ - private void prepareVictoryReport() { - Report r; - - addReport(new Report(7000, Report.PUBLIC)); - - //Declare the victor - r = new Report(1210); - r.type = Report.PUBLIC; - if (game.getVictoryTeam() == Player.TEAM_NONE) { - Player player = getPlayer( game.getVictoryPlayerId() ); - if ( null == player ) { - r.messageId = 7005; - } else { - r.messageId = 7010; - r.add(player.getName()); - } - } else { - //Team victory - r.messageId = 7015; - r.add(game.getVictoryTeam()); - } - addReport(r); - - //List the survivors - Enumeration survivors = game.getEntities(); - if ( survivors.hasMoreElements() ) { - addReport(new Report(7020, Report.PUBLIC)); - while ( survivors.hasMoreElements() ) { - Entity entity = (Entity) survivors.nextElement(); - - if ( !entity.isDeployed() ) - continue; - - addReport( entity.victoryReport()); - } - } - //List units that never deployed - Enumeration undeployed = game.getEntities(); - if ( undeployed.hasMoreElements() ) { - boolean wroteHeader = false; - - while ( undeployed.hasMoreElements() ) { - Entity entity = (Entity) undeployed.nextElement(); - - if ( entity.isDeployed() ) - continue; - - if ( !wroteHeader ) { - addReport(new Report(7075, Report.PUBLIC)); - wroteHeader = true; - } - - addReport( entity.victoryReport()); - } - } - //List units that retreated - Enumeration retreat = game.getRetreatedEntities(); - if ( retreat.hasMoreElements() ) { - addReport(new Report(7080, Report.PUBLIC)); - while ( retreat.hasMoreElements() ) { - Entity entity = (Entity) retreat.nextElement(); - addReport( entity.victoryReport()); - } - } - //List destroyed units - Enumeration graveyard = game.getGraveyardEntities(); - if ( graveyard.hasMoreElements() ) { - addReport(new Report(7085, Report.PUBLIC)); - while ( graveyard.hasMoreElements() ) { - Entity entity = (Entity) graveyard.nextElement(); - addReport( entity.victoryReport()); - } - } - //List devastated units (not salvagable) - Enumeration devastated = game.getDevastatedEntities(); - if ( devastated.hasMoreElements() ) { - addReport(new Report(7090, Report.PUBLIC)); - - while ( devastated.hasMoreElements() ) { - Entity entity = (Entity) devastated.nextElement(); - addReport( entity.victoryReport()); - } - } - //Let player know about entitystatus.txt file - addReport(new Report(7095, Report.PUBLIC)); - } - - /** - * Generates a detailed report for campaign use - */ - private String getDetailedVictoryReport() { - StringBuffer sb = new StringBuffer(); - - Vector vAllUnits = new Vector(); - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - vAllUnits.addElement(i.nextElement()); - } - - for ( Enumeration i = game.getRetreatedEntities(); - i.hasMoreElements(); ) { - vAllUnits.addElement(i.nextElement()); - } - - for ( Enumeration i = game.getGraveyardEntities(); - i.hasMoreElements(); ) { - vAllUnits.addElement(i.nextElement()); - } - - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - - // Record the player. - Player p = (Player)i.nextElement(); - sb.append("++++++++++ " ) - .append( p.getName() ) - .append( " ++++++++++"); - sb.append( CommonConstants.NL ); - - // Record the player's alive, retreated, or salvageable units. - for (int x = 0; x < vAllUnits.size(); x++) { - Entity e = (Entity)vAllUnits.elementAt(x); - if (e.getOwner() == p) { - sb.append(UnitStatusFormatter.format(e)); - } - } - - // Record the player's devastated units. - Enumeration devastated = game.getDevastatedEntities(); - if ( devastated.hasMoreElements() ) { - sb.append("============================================================="); - sb.append( CommonConstants.NL ); - sb.append("The following utterly destroyed units are not available for salvage:"); - sb.append( CommonConstants.NL ); - while ( devastated.hasMoreElements() ) { - Entity e = (Entity) devastated.nextElement(); - if (e.getOwner() == p) { - sb.append( e.getShortName() ) - .append( ", Pilot: " ) - .append( e.getCrew().getName() ) - .append( " (" ) - .append( e.getCrew().getGunnery() ) - .append( "/" ) - .append( e.getCrew().getPiloting() ) - .append( ")" ); - sb.append( CommonConstants.NL ); - } - } // Handle the next unsalvageable unit for the player - sb.append("============================================================="); - sb.append( CommonConstants.NL ); - } - - } // Handle the next player - - return sb.toString(); - } - - /** - * Forces victory for the specified player, or his/her team at the end of - * the round. - */ - public void forceVictory(Player victor) { - game.setForceVictory(true); - if (victor.getTeam() == Player.TEAM_NONE) { - game.setVictoryPlayerId(victor.getId()); - game.setVictoryTeam(Player.TEAM_NONE); - } else { - game.setVictoryPlayerId(Player.PLAYER_NONE); - game.setVictoryTeam(victor.getTeam()); - } - - Vector players = game.getPlayersVector(); - for (int i = 0; i < players.size(); i++) { - Player player = (Player) players.elementAt(i); - player.setAdmitsDefeat(false); - } - } - - /** Cancels the force victory */ - public void cancelVictory() { - game.setForceVictory(false); - game.setVictoryPlayerId(Player.PLAYER_NONE); - game.setVictoryTeam(Player.TEAM_NONE); - } - - /** - * Called when a player declares that he is "done." Checks to see if all - * players are done, and if so, moves on to the next phase. - */ - private void checkReady() { - // check if all active players are done - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - final Player player = (Player)i.nextElement(); - if (!player.isGhost() && !player.isObserver() && !player.isDone()) { - return; - } - } - - // Tactical Genius pilot special ability (lvl 3) - if (game.getNoOfInitiativeRerollRequests() > 0) { - resetActivePlayersDone(); - game.rollInitAndResolveTies(); - - determineTurnOrder(IGame.PHASE_INITIATIVE); - clearReports(); - writeInitiativeReport(true); - sendReport(true); - return; // don't end the phase yet, players need to see new report - } - - // need at least one entity in the game for the lounge phase to end - if (!game.phaseHasTurns(game.getPhase()) && - (game.getPhase() != IGame.PHASE_LOUNGE || game.getNoOfEntities() > 0)) { - endCurrentPhase(); - } - } - - /** - * Called when the current player has done his current turn and the turn - * counter needs to be advanced. - * Also enforces the "protos_move_multi" and the "protos_move_multi" - * option. If the player has just moved infantry/protos with a "normal" - * turn, adds up to Game.INF_AND_PROTOS_MOVE_MULTI - 1 more - * infantry/proto-specific turns after the current turn. - */ - private void endCurrentTurn(Entity entityUsed) { - - // Enforce "inf_move_multi" and "protos_move_multi" options. - // The "isNormalTurn" flag is checking to see if any non-Infantry - // or non-Protomech units can move during the current turn. - boolean turnsChanged = false; - GameTurn turn = game.getTurn(); - final int playerId = (null == entityUsed) ? - Player.PLAYER_NONE : entityUsed.getOwnerId(); - boolean infMoved = entityUsed instanceof Infantry; - boolean infMoveMulti = - game.getOptions().booleanOption("inf_move_multi") - && (game.getPhase() == IGame.PHASE_MOVEMENT - || game.getPhase() == IGame.PHASE_INITIATIVE); - boolean protosMoved = entityUsed instanceof Protomech; - boolean protosMoveMulti = - game.getOptions().booleanOption("protos_move_multi"); - - // If infantry or protos move multi see if any - // other unit types can move in the current turn. - int multiMask = 0; - if ( infMoveMulti ) { - multiMask += GameTurn.CLASS_INFANTRY; - } - if ( protosMoveMulti ) { - multiMask += GameTurn.CLASS_PROTOMECH; - } - - // If a proto declared fire and protos don't move - // multi, ignore whether infantry move or not. - else if ( protosMoved && game.getPhase() == IGame.PHASE_FIRING ) { - multiMask = 0; - } - - // Is this a general move turn? - boolean isGeneralMoveTurn = - ( !(turn instanceof GameTurn.SpecificEntityTurn) && - !(turn instanceof GameTurn.UnitNumberTurn) && - !(turn instanceof GameTurn.UnloadStrandedTurn) && - ( !(turn instanceof GameTurn.EntityClassTurn) || - ( (turn instanceof GameTurn.EntityClassTurn) && - ( (GameTurn.EntityClassTurn) turn ).isValidClass(~multiMask) - ) - ) - ); - - // Unless overridden by the "protos_move_multi" option, all Protomechs - // in a unit declare fire, and they don't mix with infantry. - if ( protosMoved && !protosMoveMulti && isGeneralMoveTurn && - game.getPhase() == IGame.PHASE_FIRING ) { - - // What's the unit number and ID of the entity used? - final char movingUnit = entityUsed.getUnitNumber(); - final int movingId = entityUsed.getId(); - - // How many other Protomechs are in the unit that can fire? - int protoTurns = game.getSelectedEntityCount - ( new EntitySelector() { - private final int ownerId = playerId; - private final int entityId = movingId; - private final char unitNum = movingUnit; - public boolean accept( Entity entity ) { - if ( entity instanceof Protomech && - entity.isSelectableThisTurn() && - ownerId == entity.getOwnerId() && - entityId != entity.getId() && - unitNum == entity.getUnitNumber() ) - return true; - return false; - } - } ); - - // Add the correct number of turns for the Protomech unit number. - for (int i = 0; i < protoTurns; i++) { - GameTurn newTurn = new GameTurn.UnitNumberTurn - ( playerId, movingUnit ); - game.insertNextTurn(newTurn); - turnsChanged = true; - } - } - - // Otherwise, we may need to add turns for the "*_move_multi" options. - else if ( ( (infMoved && infMoveMulti) || - (protosMoved && protosMoveMulti) ) && - isGeneralMoveTurn ) { - int remaining = 0; - - // Calculate the number of EntityClassTurns need to be added. - if ( infMoveMulti ) { - remaining += game.getInfantryLeft(playerId); - } - if ( protosMoveMulti ) { - remaining += game.getProtomechsLeft(playerId); - } - int moreInfAndProtoTurns = - Math.min(game.getOptions().intOption("inf_proto_move_multi") - 1, remaining); - - // Add the correct number of turns for the right unit classes. - for (int i = 0; i < moreInfAndProtoTurns; i++) { - GameTurn newTurn = - new GameTurn.EntityClassTurn( playerId, multiMask ); - game.insertNextTurn(newTurn); - turnsChanged = true; - } - } - // brief everybody on the turn update, if they changed - if (turnsChanged) { - send(createTurnVectorPacket()); - } - - // move along - changeToNextTurn(); - } - - /** - * Changes the current phase, does some bookkeeping and - * then tells the players. - * @param phase the int id of the phase to change to - */ - private void changePhase(int phase) { - game.setLastPhase(game.getPhase()); - game.setPhase(phase); - - // prepare for the phase - prepareForPhase(phase); - - if (isPhasePlayable(phase)) { - // tell the players about the new phase - send(new Packet(Packet.COMMAND_PHASE_CHANGE, new Integer(phase))); - - // post phase change stuff - executePhase(phase); - } else { - endCurrentPhase(); - } - } - - /** - * Prepares for, presumably, the next phase. This typically involves - * resetting the states of entities in the game and making sure the client - * has the information it needs for the new phase. - * @param phase the int id of the phase to prepare for - */ - private void prepareForPhase(int phase) { - switch (phase) { - case IGame.PHASE_LOUNGE : - clearReports(); - mapSettings.setBoardsAvailableVector - ( scanForBoards(mapSettings.getBoardWidth(), - mapSettings.getBoardHeight()) ); - mapSettings.setNullBoards(DEFAULT_BOARD); - send(createMapSettingsPacket()); - break; - case IGame.PHASE_INITIATIVE : - // remove the last traces of last round - game.resetActions(); - game.resetTagInfo(); - clearReports(); - resetEntityRound(); - resetEntityPhase(phase); - checkForObservers(); - // roll 'em - resetActivePlayersDone(); - rollInitiative(); - - if ( !game.shouldDeployThisRound() ) - incrementAndSendGameRound(); - - //setIneligible(phase); - determineTurnOrder(phase); - writeInitiativeReport(false); - System.out.println("Round " + game.getRoundCount() + " memory usage: " + MegaMek.getMemoryUsed()); - break; - case IGame.PHASE_DEPLOY_MINEFIELDS : - checkForObservers(); - resetActivePlayersDone(); - setIneligible(phase); - - Enumeration e = game.getPlayers(); - Vector turns = new Vector(); - while (e.hasMoreElements()) { - Player p = (Player) e.nextElement(); - if (p.hasMinefields()) { - GameTurn gt = new GameTurn(p.getId()); - turns.addElement(gt); - } - } - game.setTurnVector(turns); - game.resetTurnIndex(); - - // send turns to all players - send(createTurnVectorPacket()); - break; - case IGame.PHASE_SET_ARTYAUTOHITHEXES : - // place off board entities actually off-board - Enumeration i = game.getEntities(); - while (i.hasMoreElements()) { - Entity en = (Entity) i.nextElement(); - en.deployOffBoard(); - } - checkForObservers(); - resetActivePlayersDone(); - setIneligible(phase); - - i = game.getPlayers(); - Vector turn = new Vector(); - - // Walk through the players of the game, and add - // a turn for all players with artillery weapons. - while (i.hasMoreElements()) { - - // Get the next player. - final Player p = (Player) i.nextElement(); - - // Does the player have any artillery-equipped units? - EntitySelector playerArtySelector = new EntitySelector() { - private Player owner = p; - public boolean accept (Entity entity) { - if ( owner.equals( entity.getOwner() ) && - entity.isEligibleForTargetingPhase() ) - return true; - return false; - } - }; - if ( game.getSelectedEntities( playerArtySelector ) - .hasMoreElements() ) { - - // Yes, the player has arty-equipped units. - GameTurn gt = new GameTurn(p.getId()); - turn.addElement(gt); - } - } - game.setTurnVector(turn); - game.resetTurnIndex(); - - // send turns to all players - send(createTurnVectorPacket()); - break; - case IGame.PHASE_MOVEMENT : - case IGame.PHASE_DEPLOYMENT : - case IGame.PHASE_FIRING : - case IGame.PHASE_PHYSICAL : - case IGame.PHASE_TARGETING: - case IGame.PHASE_OFFBOARD: - resetEntityPhase(phase); - checkForObservers(); - setIneligible(phase); - determineTurnOrder(phase); - resetActivePlayersDone(); - //send(createEntitiesPacket()); - entityAllUpdate(); - clearReports(); - doTryUnstuck(); - break; - case IGame.PHASE_END : - resetEntityPhase(phase); - clearReports(); - resolveHeat(); - //write End Phase header - addReport(new Report(5005, Report.PUBLIC)); - checkForSuffocation(); - if (game.getOptions().booleanOption("vacuum")) { - checkForVacuumDeath(); - } - for(Enumeration tps=terrainProcessors.elements();tps.hasMoreElements();) { - DynamicTerrainProcessor tp = tps.nextElement(); - tp.DoEndPhaseChanges(vPhaseReport); - } - addReport( game.ageFlares()); - send(createFlarePacket()); - resolveExtremeTempInfantryDeath(); - resolveAmmoDumps(); - resolveCrewDamage(); - resolveCrewWakeUp(); - resolveMechWarriorPickUp(); - resolveVeeINarcPodRemoval(); - checkForObservers(); - entityAllUpdate(); - break; - case IGame.PHASE_INITIATIVE_REPORT : - autoSave(); - case IGame.PHASE_MOVEMENT_REPORT : - case IGame.PHASE_OFFBOARD_REPORT : - case IGame.PHASE_FIRING_REPORT : - case IGame.PHASE_PHYSICAL_REPORT : - case IGame.PHASE_END_REPORT : - resetActivePlayersDone(); - sendReport(); - if (game.getOptions().booleanOption("paranoid_autosave")) autoSave(); - break; - case IGame.PHASE_VICTORY : - resetPlayersDone(); - clearReports(); - prepareVictoryReport(); - game.addReports(vPhaseReport); - send(createFullEntitiesPacket()); - send(createReportPacket(null)); - send(createEndOfGamePacket()); - break; - } - } - - /** - * Should we play this phase or skip it? - */ - private boolean isPhasePlayable(int phase) { - switch (phase) { - case IGame.PHASE_INITIATIVE : - case IGame.PHASE_END : - return false; - case IGame.PHASE_SET_ARTYAUTOHITHEXES : - case IGame.PHASE_DEPLOY_MINEFIELDS : - case IGame.PHASE_DEPLOYMENT : - case IGame.PHASE_MOVEMENT : - case IGame.PHASE_FIRING : - case IGame.PHASE_PHYSICAL : - case IGame.PHASE_TARGETING: - case IGame.PHASE_OFFBOARD : - return game.hasMoreTurns(); - default : - return true; - } - } - - /** - * Do anything we seed to start the new phase, such as give a turn to - * the first player to play. - */ - private void executePhase(int phase) { - switch (phase) { - case IGame.PHASE_EXCHANGE : - resetPlayersDone(); - // Build teams vector - game.setupTeams(); - applyBoardSettings(); - game.setupRoundDeployment(); - game.determineWind(); - // If we add transporters for any Magnetic Clamp - // equiped squads, then update the clients' entities. - if ( game.checkForMagneticClamp() ) { - entityAllUpdate(); - } - // transmit the board to everybody - send(createBoardPacket()); - break; - case IGame.PHASE_MOVEMENT : - //write Movement Phase header to report - addReport(new Report(2000, Report.PUBLIC)); - case IGame.PHASE_SET_ARTYAUTOHITHEXES : - case IGame.PHASE_DEPLOY_MINEFIELDS : - case IGame.PHASE_DEPLOYMENT : - case IGame.PHASE_FIRING : - case IGame.PHASE_PHYSICAL : - case IGame.PHASE_TARGETING : - case IGame.PHASE_OFFBOARD : - changeToNextTurn(); - if (game.getOptions().booleanOption("paranoid_autosave")) autoSave(); - break; - } - } - - /** - * Ends this phase and moves on to the next. - */ - private void endCurrentPhase() { - switch (game.getPhase()) { - case IGame.PHASE_LOUNGE : - changePhase(IGame.PHASE_EXCHANGE); - break; - case IGame.PHASE_EXCHANGE : - changePhase(IGame.PHASE_SET_ARTYAUTOHITHEXES); - break; - case IGame.PHASE_STARTING_SCENARIO : - changePhase(IGame.PHASE_SET_ARTYAUTOHITHEXES); - break; - case IGame.PHASE_SET_ARTYAUTOHITHEXES : - Enumeration e = game.getPlayers(); - boolean mines = false; - while (e.hasMoreElements()) { - Player p = (Player) e.nextElement(); - if (p.hasMinefields()) { - mines = true; - } - } - if (mines) { - changePhase(IGame.PHASE_DEPLOY_MINEFIELDS); - } else { - changePhase(IGame.PHASE_INITIATIVE); - } - break; - case IGame.PHASE_DEPLOY_MINEFIELDS : - changePhase(IGame.PHASE_INITIATIVE); - break; - case IGame.PHASE_DEPLOYMENT : - game.clearDeploymentThisRound(); - game.checkForCompleteDeployment(); - Enumeration pls = game.getPlayers(); - while (pls.hasMoreElements()) { - Player p = (Player) pls.nextElement(); - p.adjustStartingPosForReinforcements(); - } - - changePhase(IGame.PHASE_INITIATIVE); - break; - case IGame.PHASE_INITIATIVE : - game.addReports(vPhaseReport); - changePhase(IGame.PHASE_INITIATIVE_REPORT); - break; - case IGame.PHASE_INITIATIVE_REPORT : - //boolean doDeploy = game.shouldDeployThisRound() && (game.getLastPhase() != IGame.PHASE_DEPLOYMENT); - if ( game.shouldDeployThisRound() ) { - changePhase(IGame.PHASE_DEPLOYMENT); - } else { - changePhase(IGame.PHASE_TARGETING); - } - break; - case IGame.PHASE_MOVEMENT : - doAllAssaultDrops(); - addMovementHeat(); - applyBuildingDamage(); - checkFor20Damage(); - resolveCrewDamage(); - resolvePilotingRolls(); // Skids cause damage in movement phase - resolveCrewDamage(); // again, I guess - checkForFlamingDeath(); - // check phase report - if (vPhaseReport.size() > 1) { - game.addReports(vPhaseReport); - changePhase(IGame.PHASE_MOVEMENT_REPORT); - } else { - //just the header, so we'll add the label - addReport(new Report(1205, Report.PUBLIC)); - game.addReports(vPhaseReport); - sendReport(); - changePhase(IGame.PHASE_OFFBOARD); - } - break; - case IGame.PHASE_MOVEMENT_REPORT : - changePhase(IGame.PHASE_OFFBOARD); - break; - case IGame.PHASE_FIRING : - resolveAllButWeaponAttacks(); - assignAMS(); - resolveOnlyWeaponAttacks(); - applyBuildingDamage(); - checkFor20Damage(); - resolveCrewDamage(); - resolvePilotingRolls(); - resolveCrewDamage(); // again, I guess - // check phase report - if (vPhaseReport.size() > 1) { - game.addReports(vPhaseReport); - changePhase(IGame.PHASE_FIRING_REPORT); - } else { - //just the header, so we'll add the label - addReport(new Report(1205, Report.PUBLIC)); - sendReport(); - game.addReports(vPhaseReport); - changePhase(IGame.PHASE_PHYSICAL); - } - break; - case IGame.PHASE_FIRING_REPORT : - changePhase(IGame.PHASE_PHYSICAL); - break; - case IGame.PHASE_PHYSICAL : - resolvePhysicalAttacks(); - applyBuildingDamage(); - checkFor20Damage(); - resolveCrewDamage(); - resolvePilotingRolls(); - resolveCrewDamage(); // again, I guess - resolveSinkVees(); - // check phase report - if (vPhaseReport.size() > 1) { - game.addReports(vPhaseReport); - changePhase(IGame.PHASE_PHYSICAL_REPORT); - } else { - //just the header, so we'll add the label - addReport(new Report(1205, Report.PUBLIC)); - game.addReports(vPhaseReport); - sendReport(); - changePhase(IGame.PHASE_END); - } - break; - case IGame.PHASE_PHYSICAL_REPORT : - changePhase(IGame.PHASE_END); - break; - case IGame.PHASE_TARGETING : - enqueueIndirectArtilleryAttacks(); - changePhase(IGame.PHASE_MOVEMENT); - break; - case IGame.PHASE_OFFBOARD : - //write Offboard Attack Phase header - addReport(new Report(1100, Report.PUBLIC)); - resolveAllButWeaponAttacks(); //torso twist or flip arms possible - resolveOnlyWeaponAttacks(); //should only be TAG at this point - resolveIndirectArtilleryAttacks(); - applyBuildingDamage(); - checkFor20Damage(); - resolveCrewDamage(); - resolvePilotingRolls(); - resolveCrewDamage(); // again, I guess - //check reports - if (vPhaseReport.size() > 1) { - game.addReports(vPhaseReport); - changePhase(IGame.PHASE_OFFBOARD_REPORT); - } else { - //just the header, so we'll add the label - addReport(new Report(1205, Report.PUBLIC)); - game.addReports(vPhaseReport); - sendReport(); - changePhase(IGame.PHASE_FIRING); - } - break; - case IGame.PHASE_OFFBOARD_REPORT: - changePhase(IGame.PHASE_FIRING); - break; - case IGame.PHASE_END : - // check phase report - //HACK: hardcoded message ID check - if (vPhaseReport.size() > 3 - || ((Report)vPhaseReport.elementAt(1)).messageId != 1205) { - game.addReports(vPhaseReport); - changePhase(IGame.PHASE_END_REPORT); - } else { - //just the heat and end headers, so we'll add - // the label - addReport(new Report(1205, Report.PUBLIC)); - game.addReports(vPhaseReport); - sendReport(); - if (victory()) { - changePhase(IGame.PHASE_VICTORY); - } else { - changePhase(IGame.PHASE_INITIATIVE); - } - } - break; - case IGame.PHASE_END_REPORT : - if (victory()) { - changePhase(IGame.PHASE_VICTORY); - } else { - changePhase(IGame.PHASE_INITIATIVE); - } - break; - case IGame.PHASE_VICTORY : - resetGame(); - break; - } - } - - /** - * Increment's the server's game round and send it to all the clients - */ - private void incrementAndSendGameRound() { - game.incrementRoundCount(); - send(new Packet(Packet.COMMAND_ROUND_UPDATE, new Integer(game.getRoundCount()))); - } - - /** - * Tries to change to the next turn. If there are no more turns, ends the - * current phase. If the player whose turn it is next is not connected, - * we allow the other players to skip that player. - */ - private void changeToNextTurn() { - // if there aren't any more turns, end the phase - if (!game.hasMoreTurns()) { - endCurrentPhase(); - return; - } - - // okay, well next turn then! - GameTurn nextTurn = game.changeToNextTurn(); - send(createTurnIndexPacket()); - - Player player = getPlayer( nextTurn.getPlayerNum() ); - if ( null != player && player.isGhost() ) { - sendGhostSkipMessage( player ); - } - else if ( null == game.getFirstEntity() - && null != player - && ((game.getPhase() != IGame.PHASE_DEPLOY_MINEFIELDS) && (game.getPhase() != IGame.PHASE_SET_ARTYAUTOHITHEXES))) { - sendTurnErrorSkipMessage( player ); - } - } - - /** - * Sends out a notification message indicating that a ghost player may - * be skipped. - * - * @param ghost - the Player who is ghosted. - * This value must not be null. - */ - private void sendGhostSkipMessage( Player ghost ) { - StringBuffer message = new StringBuffer(); - message.append( "Player '" ) - .append( ghost.getName() ) - .append( "' is disconnected. You may skip his/her current turn with the /skip command." ); - sendServerChat( message.toString() ); - } - - /** - * Sends out a notification message indicating that the current turn is an - * error and should be skipped. - * - * @param skip - the Player who is to be skipped. - * This value must not be null. - */ - private void sendTurnErrorSkipMessage( Player skip ) { - StringBuffer message = new StringBuffer(); - message.append( "Player '" ) - .append( skip.getName() ) - .append( "' has no units to move. You should skip his/her/your current turn with the /skip command. You may want to report this error. See the MegaMek homepage (http://megamek.sf.net/) for details." ); - sendServerChat( message.toString() ); - } - - /** - * Skips the current turn. This only makes sense in phases that have turns. - * Operates by finding an entity to move and then doing nothing with it. - */ - public void skipCurrentTurn() { - // find an entity to skip... - Entity toSkip = game.getFirstEntity(); - - switch (game.getPhase()) { - case IGame.PHASE_DEPLOYMENT : - sendServerChat("Turns cannot be skipped in the deployment phase."); - break; - case IGame.PHASE_MOVEMENT : - if ( toSkip != null ) { - processMovement(toSkip, new MovePath(game, toSkip)); - } - endCurrentTurn(toSkip); - break; - case IGame.PHASE_FIRING : - case IGame.PHASE_PHYSICAL : - case IGame.PHASE_TARGETING : - case IGame.PHASE_OFFBOARD : - if ( toSkip != null ) { - processAttack(toSkip, new Vector(0)); - } - endCurrentTurn(toSkip); - break; - default : - - } - } - - /** - * Returns true if the current turn may be skipped. Ghost players' turns - * are skippable, and a turn should be skipped if there's nothing to move. - */ - public boolean isTurnSkippable() { - GameTurn turn = game.getTurn(); - if (null == turn) return false; - Player player = getPlayer( turn.getPlayerNum() ); - return ( null == player || player.isGhost() - || game.getFirstEntity() == null ); - } - - /** - * Returns true if victory conditions have been met. Victory conditions - * are when there is only one player left with mechs or only one team. - */ - public boolean victory() { - if (game.isForceVictory()) { - int victoryPlayerId = game.getVictoryPlayerId(); - int victoryTeam = game.getVictoryTeam(); - Vector players = game.getPlayersVector(); - boolean forceVictory = true; - - // Individual victory. - if (victoryPlayerId != Player.PLAYER_NONE) { - for (int i = 0; i < players.size(); i++) { - Player player = (Player) players.elementAt(i); - - if (player.getId() != victoryPlayerId && !player.isObserver()) { - if (!player.admitsDefeat()) { - forceVictory = false; - break; - } - } - } - } - // Team victory. - if (victoryTeam != Player.TEAM_NONE) { - for (int i = 0; i < players.size(); i++) { - Player player = (Player) players.elementAt(i); - - if (player.getTeam() != victoryTeam && !player.isObserver()) { - if (!player.admitsDefeat()) { - forceVictory = false; - break; - } - } - } - } - - for (int i = 0; i < players.size(); i++) { - Player player = (Player) players.elementAt(i); - player.setAdmitsDefeat(false); - } - - if (forceVictory) { - return true; - } - cancelVictory(); - } - - if (!game.getOptions().booleanOption("check_victory")) { - return false; - } - - // check all players/teams for aliveness - int playersAlive = 0; - Player lastPlayer = null; - boolean oneTeamAlive = false; - int lastTeam = Player.TEAM_NONE; - boolean unteamedAlive = false; - for (Enumeration e = game.getPlayers(); e.hasMoreElements();) { - Player player = (Player)e.nextElement(); - int team = player.getTeam(); - if (game.getLiveDeployedEntitiesOwnedBy(player) <= 0) { - continue; - } - // we found a live one! - playersAlive++; - lastPlayer = player; - // check team - if (team == Player.TEAM_NONE) { - unteamedAlive = true; - } else if (lastTeam == Player.TEAM_NONE) { - // possibly only one team alive - oneTeamAlive = true; - lastTeam = team; - } else if (team != lastTeam) { - // more than one team alive - oneTeamAlive = false; - lastTeam = team; - } - } - - // check if there's one player alive - if (playersAlive < 1) { - game.setVictoryPlayerId( Player.PLAYER_NONE ); - game.setVictoryTeam( Player.TEAM_NONE ); - return true; - } - else if ( playersAlive == 1 ) { - if (lastPlayer.getTeam() == Player.TEAM_NONE) { - // individual victory - game.setVictoryPlayerId(lastPlayer.getId()); - game.setVictoryTeam(Player.TEAM_NONE); - return true; - } - } - - // did we only find one live team? - if (oneTeamAlive && !unteamedAlive) { - // team victory - game.setVictoryPlayerId(Player.PLAYER_NONE); - game.setVictoryTeam(lastTeam); - return true; - } - - return false; - } - - /** - * Applies board settings. This loads and combines all the boards that - * were specified into one mega-board and sets that board as current. - */ - public void applyBoardSettings() { - mapSettings.replaceBoardWithRandom(MapSettings.BOARD_RANDOM); - mapSettings.replaceBoardWithRandom(MapSettings.BOARD_SURPRISE); - IBoard[] sheetBoards = new IBoard[mapSettings.getMapWidth() * mapSettings.getMapHeight()]; - for (int i = 0; i < mapSettings.getMapWidth() * mapSettings.getMapHeight(); i++) { - sheetBoards[i] = new Board(); - String name = (String)mapSettings.getBoardsSelectedVector().elementAt(i); - boolean isRotated = false; - if ( name.startsWith( Board.BOARD_REQUEST_ROTATION ) ) { - isRotated = true; - name = name.substring( Board.BOARD_REQUEST_ROTATION.length() ); - } - if (name.startsWith(MapSettings.BOARD_GENERATED)) { - sheetBoards[i] = BoardUtilities.generateRandom(mapSettings); - } else { - sheetBoards[i].load( name + ".board"); - BoardUtilities.flip(sheetBoards[i], isRotated, isRotated ); - } - } - IBoard newBoard = BoardUtilities.combine(mapSettings.getBoardWidth(), mapSettings.getBoardHeight(), - mapSettings.getMapWidth(), mapSettings.getMapHeight(), sheetBoards); - game.setBoard(newBoard); - } - - - /** - * Rolls initiative for all the players. - */ - private void rollInitiative() { - if(game.getOptions().booleanOption("individual_initiative")) { - TurnOrdered.rollInitiative(game.getEntitiesVector()); - } else { - // Roll for initative on the teams. - TurnOrdered.rollInitiative(game.getTeamsVector()); - } - - transmitAllPlayerUpdates(); - } - - /** - * Determines the turn oder for a given phase (with individual init) - * @param phase the int id of the phase - */ - private void determineTurnOrderIUI(int phase) { - for (Enumeration loop = game.getEntities(); loop.hasMoreElements();) { - final Entity entity = (Entity)loop.nextElement(); - entity.resetOtherTurns(); - if (entity.isSelectableThisTurn()) { - entity.incrementOtherTurns(); - } - } - // Now, generate the global order of all teams' turns. - TurnVectors team_order = TurnOrdered.generateTurnOrder - ( game.getEntitiesVector(), game ); - - // See if there are any loaded units stranded on immobile transports. - Enumeration strandedUnits = game.getSelectedEntities - ( new EntitySelector() { - public boolean accept( Entity entity ) { - if ( Server.this.game.isEntityStranded(entity) ) - return true; - return false; - } - } ); - - // Now, we collect everything into a single vector. - Vector turns; - - if ( strandedUnits.hasMoreElements() && - game.getPhase() == IGame.PHASE_MOVEMENT ) { - // Add a game turn to unload stranded units, if this - // is the movement phase. - turns = new Vector( team_order.getNormalTurns() + - team_order.getEvenTurns() + 1); - turns.addElement( new GameTurn.UnloadStrandedTurn(strandedUnits) ); - } else { - // No stranded units. - turns = new Vector( team_order.getNormalTurns() + - team_order.getEvenTurns() ); - } - - //add the turns (this is easy) - while(team_order.hasMoreElements()) { - Entity e = (Entity)team_order.nextElement(); - if(e.isSelectableThisTurn()) - turns.addElement(new GameTurn.SpecificEntityTurn(e.getOwnerId(), e.getId())); - } - - // set fields in game - game.setTurnVector(turns); - game.resetTurnIndex(); - - // send turns to all players - send(createTurnVectorPacket()); - } - /** - * Determines the turn oder for a given phase - * @param phase the int id of the phase - */ - private void determineTurnOrder(int phase) { - - if(game.getOptions().booleanOption("individual_initiative")) { - determineTurnOrderIUI(phase); - return; - } - // and/or deploy even according to game options. - boolean infMoveEven = - ( game.getOptions().booleanOption("inf_move_even") && - (game.getPhase() == IGame.PHASE_INITIATIVE || - game.getPhase() == IGame.PHASE_MOVEMENT) ) || - ( game.getOptions().booleanOption("inf_deploy_even") && - game.getPhase() == IGame.PHASE_DEPLOYMENT ); - boolean infMoveMulti = - ( game.getOptions().booleanOption("inf_move_multi") && - (game.getPhase() == IGame.PHASE_INITIATIVE || - game.getPhase() == IGame.PHASE_MOVEMENT) ); - boolean protosMoveEven = - ( game.getOptions().booleanOption("protos_move_even") && - (game.getPhase() == IGame.PHASE_INITIATIVE || - game.getPhase() == IGame.PHASE_MOVEMENT) ) || - ( game.getOptions().booleanOption("protos_deploy_even") && - game.getPhase() == IGame.PHASE_DEPLOYMENT ); - boolean protosMoveMulti = - game.getOptions().booleanOption("protos_move_multi"); - boolean protosFireMulti = !protosMoveMulti && - game.getPhase() == IGame.PHASE_FIRING; - int evenMask = 0; - if ( infMoveEven ) evenMask += GameTurn.CLASS_INFANTRY; - if ( protosMoveEven ) evenMask += GameTurn.CLASS_PROTOMECH; - - // Reset all of the Players' turn category counts - for (Enumeration loop = game.getPlayers(); loop.hasMoreElements();) { - final Player player = (Player) loop.nextElement(); - player.resetEvenTurns(); - player.resetMultiTurns(); - player.resetOtherTurns(); - - // Add turns for protomechs weapons declaration. - if ( protosFireMulti ) { - - // How many Protomechs does the player have? - int numPlayerProtos = game.getSelectedEntityCount - ( new EntitySelector() { - private final int ownerId = player.getId(); - public boolean accept( Entity entity ) { - if ( entity instanceof Protomech && - ownerId == entity.getOwnerId() ) - return true; - return false; - } - } ); - int numProtoUnits = - (int) Math.ceil( (numPlayerProtos) / 5.0 ); - for ( int unit = 0; unit < numProtoUnits; unit++ ) { - if ( protosMoveEven ) player.incrementEvenTurns(); - else player.incrementOtherTurns(); - } - - } // End handle-proto-firing-turns - - } // Handle the next player - - // Go through all entities, and update the turn categories of the - // entity's player. The teams get their totals from their players. - // N.B. protomechs declare weapons fire based on their point. - for (Enumeration loop = game.getEntities(); loop.hasMoreElements();) { - final Entity entity = (Entity)loop.nextElement(); - if (entity.isSelectableThisTurn()) { - final Player player = entity.getOwner(); - if ( entity instanceof Infantry ) { - if ( infMoveEven ) player.incrementEvenTurns(); - else if ( infMoveMulti ) player.incrementMultiTurns(); - else player.incrementOtherTurns(); - } - else if ( entity instanceof Protomech ) { - if ( !protosFireMulti ) { - if ( protosMoveEven ) player.incrementEvenTurns(); - else if ( protosMoveMulti ) player.incrementMultiTurns(); - else player.incrementOtherTurns(); - } - } - else - player.incrementOtherTurns(); - } - } - - // Generate the turn order for the Players *within* - // each Team. Map the teams to their turn orders. - // Count the number of teams moving this turn. - int nTeams = game.getNoOfTeams(); - Hashtable allTeamTurns = new Hashtable( nTeams ); - Hashtable evenTrackers = new Hashtable( nTeams ); - int numTeamsMoving = 0; - for (Enumeration loop = game.getTeams(); loop.hasMoreElements(); ) { - final Team team = (Team) loop.nextElement(); - allTeamTurns.put( team, team.determineTeamOrder(game) ); - - // Track both the number of times we've checked the team for - // "leftover" turns, and the number of "leftover" turns placed. - int[] evenTracker = new int[2]; - evenTracker[0] = 0; - evenTracker[1] = 0; - evenTrackers.put (team, evenTracker); - - // Count this team if it has any "normal" moves. - if (team.getNormalTurns(game) > 0) - numTeamsMoving++; - } - - // Now, generate the global order of all teams' turns. - TurnVectors team_order = TurnOrdered.generateTurnOrder - ( game.getTeamsVector(), game ); - - // See if there are any loaded units stranded on immobile transports. - Enumeration strandedUnits = game.getSelectedEntities - ( new EntitySelector() { - public boolean accept( Entity entity ) { - if ( Server.this.game.isEntityStranded(entity) ) - return true; - return false; - } - } ); - - // Now, we collect everything into a single vector. - Vector turns; - - if ( strandedUnits.hasMoreElements() && - game.getPhase() == IGame.PHASE_MOVEMENT ) { - // Add a game turn to unload stranded units, if this - // is the movement phase. - turns = new Vector( team_order.getNormalTurns() + - team_order.getEvenTurns() + 1); - turns.addElement( new GameTurn.UnloadStrandedTurn(strandedUnits) ); - } else { - // No stranded units. - turns = new Vector( team_order.getNormalTurns() + - team_order.getEvenTurns() ); - } - - // Walk through the global order, assigning turns - // for individual players to the single vector. - // Keep track of how many turns we've added to the vector. - Team prevTeam = null; - int min = team_order.getMin(); - for ( int numTurn = 0; team_order.hasMoreElements(); numTurn++ ) { - Team team = (Team) team_order.nextElement(); - TurnVectors withinTeamTurns = (TurnVectors) allTeamTurns.get(team); - - int[] evenTracker = (int[]) evenTrackers.get (team); - float teamEvenTurns = team.getEvenTurns(); - - // Calculate the number of "even" turns to add for this team. - int numEven = 0; - if (1 == numTeamsMoving) { - // The only team moving should move all "even" units. - numEven += teamEvenTurns; - } - else if (prevTeam == null) { - // Increment the number of times we've checked for "leftovers". - evenTracker[0]++; - - // The first team to move just adds the "baseline" turns. - numEven += teamEvenTurns / min; - } - else if (!team.equals(prevTeam)) { - // Increment the number of times we've checked for "leftovers". - evenTracker[0]++; - - // This wierd equation attempts to spread the "leftover" - // turns accross the turn's moves in a "fair" manner. - // It's based on the number of times we've checked for - // "leftovers" the number of "leftovers" we started with, - // the number of times we've added a turn for a "leftover", - // and the total number of times we're going to check. - numEven += Math.ceil (evenTracker[0] * (teamEvenTurns % min) - / min - 0.5) - evenTracker[1]; - - // Update the number of turns actually added for "leftovers". - evenTracker[1] += numEven; - - // Add the "baseline" number of turns. - numEven += teamEvenTurns / min; - } - - // Record this team for the next move. - prevTeam = team; - - // This may be a "placeholder" for a team without "normal" turns. - if (withinTeamTurns.hasMoreElements()) { - - // Not a placeholder... get the player who moves next. - Player player = (Player) withinTeamTurns.nextElement(); - - // If we've added all "normal" turns, allocate turns - // for the infantry and/or protomechs moving even. - GameTurn turn = null; - if ( numTurn >= team_order.getNormalTurns() ) { - turn = new GameTurn.EntityClassTurn - (player.getId(), evenMask); - } - - // If either Infantry or Protomechs move even, only allow - // the other classes to move during the "normal" turn. - else if ( infMoveEven || protosMoveEven ) { - turn = new GameTurn.EntityClassTurn - (player.getId(), ~evenMask); - } - - // Otherwise, let *anybody* move. - else { - turn = new GameTurn( player.getId() ); - } - turns.addElement(turn); - - } // End team-has-"normal"-turns - - // Add the calculated number of "even" turns. - // Allow the player at least one "normal" turn before the - // "even" turns to help with loading infantry in deployment. - while (numEven > 0 && withinTeamTurns.hasMoreEvenElements()) { - Player evenPlayer = (Player) withinTeamTurns.nextEvenElement(); - turns.addElement - (new GameTurn.EntityClassTurn (evenPlayer.getId(), - evenMask)); - numEven--; - } - } - - // set fields in game - game.setTurnVector(turns); - game.resetTurnIndex(); - - // send turns to all players - send(createTurnVectorPacket()); - - } - - /** - * Write the initiative results to the report - */ - private void writeInitiativeReport(boolean abbreviatedReport) { - // write to report - Report r; - boolean deployment = false; - if (!abbreviatedReport) { - r = new Report(1210); - r.type = Report.PUBLIC; - if ((game.getLastPhase() == IGame.PHASE_DEPLOYMENT) || game.isDeploymentComplete() || !game.shouldDeployThisRound()) { - r.messageId = 1000; - r.add(game.getRoundCount()); - } else { - deployment = true; - if ( game.getRoundCount() == 0 ) { - r.messageId = 1005; - } else { - r.messageId = 1010; - r.add(game.getRoundCount()); - } - } - addReport(r); - - //write seperator - addReport(new Report(1200, Report.PUBLIC)); - } else { - addReport(new Report(1210, Report.PUBLIC)); //newline - } - - if(game.getOptions().booleanOption("individual_initiative")) { - r = new Report(1040, Report.PUBLIC); - addReport(r); - for(Enumeration e = game.getTurns();e.hasMoreElements();) { - GameTurn t = e.nextElement(); - if(t instanceof GameTurn.SpecificEntityTurn) { - Entity entity = game.getEntity(((GameTurn.SpecificEntityTurn)t).getEntityNum()); - r = new Report(1045); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(entity.getInitiative().toString()); - addReport(r); - } else { - Player player = getPlayer( t.getPlayerNum() ); - if ( null != player ) { - r = new Report(1050, Report.PUBLIC); - r.add(player.getName()); - addReport(r); - } - } - } - } else { - for (Enumeration i = game.getTeams(); i.hasMoreElements();) { - final Team team = (Team)i.nextElement(); - - // If there is only one player, list them as the 'team', and - // use the team iniative - if (team.getSize() == 1) { - final Player player = (Player)team.getPlayers().nextElement(); - r = new Report(1015, Report.PUBLIC); - r.add(player.getName()); - r.add(team.getInitiative().toString()); - addReport(r); - } else { - // Multiple players. List the team, then break it down. - r = new Report(1015, Report.PUBLIC); - r.add(Player.teamNames[team.getId()]); - r.add(team.getInitiative().toString()); - addReport(r); - for( Enumeration j = team.getPlayers(); j.hasMoreElements();) { - final Player player = (Player)j.nextElement(); - r = new Report(1015, Report.PUBLIC); - r.indent(); - r.add(player.getName()); - r.add(player.getInitiative().toString()); - addReport(r); - } - } - } - - // The turn order is different in movement phase - // if a player has any "even" moving units. - r = new Report(1020, Report.PUBLIC); - - boolean firstTurn = true; - boolean hasEven = false; - for (Enumeration i = game.getTurns(); i.hasMoreElements();) { - GameTurn turn = (GameTurn)i.nextElement(); - Player player = getPlayer( turn.getPlayerNum() ); - if ( null != player ) { - r.add(player.getName()); - firstTurn = false; - if (player.getEvenTurns() > 0) - hasEven = true; - } - } - r.newlines = 2; - addReport(r); - if (hasEven) { - r = new Report(1021, Report.PUBLIC); - if ((game.getOptions().booleanOption("inf_deploy_even") - || game.getOptions().booleanOption("protos_deploy_even")) && - !(game.getLastPhase() == IGame.PHASE_END_REPORT)) - r.choose(true); - else r.choose(false); - r.indent(); - r.newlines = 2; - addReport(r); - } - } - if (!abbreviatedReport) { - //Wind direction and strength - r = new Report(1025, Report.PUBLIC); - r.add(game.getStringWindDirection()); - if (game.getWindStrength() != -1) { - Report r2 = new Report(1030, Report.PUBLIC); - r2.add(game.getStringWindStrength()); - r.newlines = 0; - addReport(r); - addReport(r2); - } else { - addReport(r); - } - - if (deployment) - addNewLines(); - } - } - - /** - * Marks ineligible entities as not ready for this phase - */ - private void setIneligible(int phase) { - Vector assistants = new Vector(); - boolean assistable = false; - Entity entity = null; - for (Enumeration e = game.getEntities(); e.hasMoreElements();) { - entity = (Entity)e.nextElement(); - if (!entity.isEligibleFor(phase)) { - assistants.addElement(entity); - } else { - assistable=true; - } - } - for (int i=0;iEntity that is loading the unit. - * @param unit - the Entity being loaded. - */ - private void loadUnit( Entity loader, Entity unit ) { - - // Remove the *last* friendly turn (removing the *first* penalizes - // the opponent too much, and re-calculating moves is too hard). - game.removeTurnFor(unit); - send(createTurnVectorPacket()); - - // Load the unit. - loader.load( unit ); - - // The loaded unit is being carried by the loader. - unit.setTransportId( loader.getId() ); - - // Remove the loaded unit from the screen. - unit.setPosition( null ); - - // Update the loaded unit. - this.entityUpdate( unit.getId() ); - } - - /** - * Have the unloader unload the indicated unit. - * The unit being unloaded does *not* gain a turn. - * - * @param unloader - the Entity that is unloading the unit. - * @param unloaded - the Targetable unit being unloaded. - * @param pos - the Coords for the unloaded unit. - * @param facing - the int facing for the unloaded unit. - * @param elevation - the int elevation at which to unload, - * if both loader and loaded units use VTOL movement. - * @return true if the unit was successfully unloaded, - * false if the unit isn't carried in unloader. - */ - private boolean unloadUnit( Entity unloader, Targetable unloaded, - Coords pos, int facing, int elevation ) { - - // We can only unload Entities. - Entity unit = null; - if ( unloaded instanceof Entity ) { - unit = (Entity) unloaded; - } else { - return false; - } - - // Unload the unit. - if ( !unloader.unload( unit ) ) { - return false; - } - - // The unloaded unit is no longer being carried. - unit.setTransportId( Entity.NONE ); - - // Place the unloaded unit onto the screen. - unit.setPosition( pos ); - - // Units unloaded onto the screen are deployed. - if ( pos != null ) { - unit.setDeployed( true ); - } - - // Point the unloaded unit in the given direction. - unit.setFacing( facing ); - unit.setSecondaryFacing( facing ); - - IHex hex = game.getBoard().getHex(pos); - boolean isBridge = hex.containsTerrain(Terrains.PAVEMENT); - - if (unloader.getMovementMode() == IEntityMovementMode.VTOL) { - if (unit.getMovementMode() == IEntityMovementMode.VTOL) { - // Flying units onload to the same elevation as the flying transport - unit.setElevation(elevation); - } else if (game.getBoard().getBuildingAt(pos) != null) { - // non-flying unit onloaded from a flying onto a building - // -> sit on the roff - unit.setElevation(hex.terrainLevel(Terrains.BLDG_ELEV)); - } - } else if (game.getBoard().getBuildingAt(pos) != null) { - // non flying unit unloading units into a building - // -> sit in the building at the same elevation - unit.setElevation(elevation); - } else if (hex.terrainLevel(Terrains.WATER)>0) { - if (unit.getMovementMode() == IEntityMovementMode.HOVER || - unit.getMovementMode() == IEntityMovementMode.HYDROFOIL || - unit.getMovementMode() == IEntityMovementMode.NAVAL || - unit.getMovementMode() == IEntityMovementMode.SUBMARINE || - hex.containsTerrain(Terrains.ICE) || - isBridge) { - // units that can float stay on the surface, or we go on the bridge - // this means elevation 0, because elevation is relative to the surface - unit.setElevation(0); - } - } else { - // default to the floor of the hex. - // unit elevation is relative to the surface - unit.setElevation(hex.floor() - hex.surface()); - } - doSetLocationsExposure(unit, hex, false, unit.getElevation()); - - // Update the unloaded unit. - this.entityUpdate( unit.getId() ); - - // Unloaded successfully. - return true; - } - - /** - * Record that the given building has been affected by the current - * entity's movement. At the end of the entity's movement, notify - * the clients about the updates. - * - * @param bldg - the Building that has been affected. - * @param collapse - a boolean value that specifies that - * the building collapsed (when true). - */ - private void addAffectedBldg( Building bldg, boolean collapse ) { - - // If the building collapsed, then the clients have already - // been notified, so remove it from the notification list. - if ( collapse ) { - System.err.print( "Removing building from a list of " + affectedBldgs.size() + "\n" );//killme - this.affectedBldgs.remove( bldg ); - System.err.print( "... now list of " + affectedBldgs.size() + "\n" );//killme - } - - // Otherwise, make sure that this building is tracked. - else { - this.affectedBldgs.put( bldg, Boolean.FALSE ); - } - } - - /** - * Walk through the building hexes that were affected by the recent - * entity's movement. Notify the clients about the updates to all - * affected entities and uncollapsed buildings. The affected hexes - * is then cleared for the next entity's movement. - */ - private void applyAffectedBldgs() { - - // Build a list of Building updates. - Vector bldgUpdates = new Vector(); - - // Only send a single turn update. - boolean bTurnsChanged = false; - - // Walk the set of buildings. - Enumeration bldgs = this.affectedBldgs.keys(); - while ( bldgs.hasMoreElements() ) { - final Building bldg = (Building) bldgs.nextElement(); - - // Walk through the building's coordinates. - Enumeration bldgCoords = bldg.getCoords(); - while ( bldgCoords.hasMoreElements() ) { - final Coords coords = (Coords) bldgCoords.nextElement(); - - // Walk through the entities at these coordinates. - Enumeration entities = game.getEntities( coords ); - while( entities.hasMoreElements() ) { - final Entity entity = (Entity) entities.nextElement(); - - // Is the entity infantry? - if ( entity instanceof Infantry ) { - - // Is the infantry dead? - if ( entity.isDoomed() || entity.isDestroyed() ) { - - // Has the entity taken a turn? - if ( !entity.isDone() ) { - - // Dead entities don't take turns. - game.removeTurnFor(entity); - bTurnsChanged = true; - - } // End entity-still-to-move - - // Clean out the dead entity. - entity.setDestroyed(true); - game.moveToGraveyard(entity.getId()); - send(createRemoveEntityPacket(entity.getId())); - } - - // Infantry that aren't dead are damaged. - else { - this.entityUpdate( entity.getId() ); - } - - } // End entity-is-infantry - - } // Check the next entity. - - } // Handle the next hex in this building. - - // Add this building to the report. - bldgUpdates.addElement( bldg ); - - } // Handle the next affected building. - - // Did we update the turns? - if ( bTurnsChanged ) { - send(createTurnVectorPacket()); - } - - // Are there any building updates? - if ( !bldgUpdates.isEmpty() ) { - - // Send the building updates to the clients. - sendChangedCFBuildings( bldgUpdates ); - - // Clear the list of affected buildings. - this.affectedBldgs.clear(); - } - - // And we're done. - return; - - } // End private void applyAffectedBldgs() - - /** - * Receives an entity movement packet, and if valid, executes it and ends - * the current turn. - * - */ - private void receiveMovement(Packet packet, int connId) { - Entity entity = game.getEntity(packet.getIntValue(0)); - MovePath md = (MovePath)packet.getObject(1); - - // is this the right phase? - if (game.getPhase() != IGame.PHASE_MOVEMENT) { - System.err.println("error: server got movement packet in wrong phase"); - return; - } - - // can this player/entity act right now? - if (!game.getTurn().isValid(connId, entity, game)) { - System.err.println("error: server got invalid movement packet"); - return; - } - - // looks like mostly everything's okay - processMovement(entity, md); - - // Notify the clients about any building updates. - applyAffectedBldgs(); - - // Update visibility indications if using double blind. - if (doBlind()) { - updateVisibilityIndicator(); - } - - // This entity's turn is over. - // N.B. if the entity fell, a *new* turn has already been added. - endCurrentTurn(entity); - } - - /** - * Steps through an entity movement packet, executing it. - */ - private void processMovement(Entity entity, MovePath md) { - Report r; - boolean sideslipped = false; // for VTOL sideslipping - - // check for fleeing - if (md.contains(MovePath.STEP_FLEE)) { - // Unit has fled the battlefield. - r = new Report(2005, Report.PUBLIC); - r.addDesc(entity); - addReport(r); - - // Is the unit carrying passengers? - final Vector passengers = entity.getLoadedUnits(); - if ( !passengers.isEmpty() ) { - final Enumeration iter = passengers.elements(); - while ( iter.hasMoreElements() ) { - final Entity passenger = (Entity) iter.nextElement(); - // Unit has fled the battlefield. - r = new Report(2010, Report.PUBLIC); - r.indent(); - r.addDesc(passenger); - addReport(r); - game.removeEntity( passenger.getId(), - IEntityRemovalConditions.REMOVE_IN_RETREAT ); - send( createRemoveEntityPacket(passenger.getId(), - IEntityRemovalConditions.REMOVE_IN_RETREAT) ); - } - } - - // Handle any picked up MechWarriors - Enumeration iter = entity.getPickedUpMechWarriors().elements(); - while (iter.hasMoreElements() ) { - Integer mechWarriorId = (Integer)iter.nextElement(); - Entity mw = game.getEntity(mechWarriorId.intValue()); - - // Is the MechWarrior an enemy? - int condition = IEntityRemovalConditions.REMOVE_IN_RETREAT; - r = new Report(2010); - if (mw.isCaptured()) { - r = new Report(2015); - condition = IEntityRemovalConditions.REMOVE_CAPTURED; - } - game.removeEntity( mw.getId(), condition ); - send( createRemoveEntityPacket(mw.getId(), condition) ); - r.addDesc(mw); - r.indent(); - addReport(r); - } - - // Is the unit being swarmed? - final int swarmerId = entity.getSwarmAttackerId(); - if ( Entity.NONE != swarmerId ) { - final Entity swarmer = game.getEntity( swarmerId ); - - // Has the swarmer taken a turn? - if ( !swarmer.isDone() ) { - - // Dead entities don't take turns. - game.removeTurnFor(swarmer); - send(createTurnVectorPacket()); - - } // End swarmer-still-to-move - - // Unit has fled the battlefield. - swarmer.setSwarmTargetId( Entity.NONE ); - entity.setSwarmAttackerId( Entity.NONE ); - r = new Report(2015, Report.PUBLIC); - r.indent(); - r.addDesc(swarmer); - addReport(r); - game.removeEntity( swarmerId, IEntityRemovalConditions.REMOVE_CAPTURED ); - send( createRemoveEntityPacket(swarmerId, - IEntityRemovalConditions.REMOVE_CAPTURED) ); - } - game.removeEntity( entity.getId(), IEntityRemovalConditions.REMOVE_IN_RETREAT ); - send( createRemoveEntityPacket(entity.getId(), - IEntityRemovalConditions.REMOVE_IN_RETREAT) ); - return; - } - - if (md.contains(MovePath.STEP_EJECT)) { - if (entity instanceof Mech) { - r = new Report(2020); - r.subject = entity.getId(); - r.add(entity.getCrew().getName()); - r.addDesc(entity); - addReport(r); - } else if (entity instanceof Tank) { - r = new Report(2025); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - } - addReport( ejectEntity(entity, false)); - - return; - } - - // okay, proceed with movement calculations - Coords lastPos = entity.getPosition(); - Coords curPos = entity.getPosition(); - int curFacing = entity.getFacing(); - int curVTOLElevation = entity.getElevation(); - int distance = 0; - int mpUsed = 0; - int moveType = IEntityMovementType.MOVE_NONE; - int overallMoveType = IEntityMovementType.MOVE_NONE; - // if the entity already used some MPs, - // it previously tried to get up and fell, - // and then got another turn. set moveType - // and overallMoveType accordingly - if (entity.mpUsed > 0) { - moveType = IEntityMovementType.MOVE_WALK; - overallMoveType = IEntityMovementType.MOVE_WALK; - if (entity.mpUsed > entity.getWalkMP()) { - moveType = IEntityMovementType.MOVE_RUN; - overallMoveType = IEntityMovementType.MOVE_RUN; - } - } - boolean firstStep; - boolean wasProne; - boolean fellDuringMovement; - int prevFacing = curFacing; - IHex prevHex = null; - final boolean isInfantry = (entity instanceof Infantry); - AttackAction charge = null; - PilotingRollData rollTarget; - // cache this here, otherwise changing MP in the turn causes - // errorneous gravity PSRs - int cachedGravityLimit = (IEntityMovementType.MOVE_JUMP == moveType)? - entity.getOriginalJumpMP() : entity.getRunMP(false); - - // Compile the move - md.compile(game, entity); - - if (md.contains(MovePath.STEP_CLEAR_MINEFIELD)) { - ClearMinefieldAction cma = new ClearMinefieldAction(entity.getId()); - entity.setClearingMinefield(true); - game.addAction(cma); - } - - // check for MASC failure - if (entity instanceof Mech) { - Vector crits = new Vector(); - Vector vReport = new Vector(); - if (((Mech)entity).checkForMASCFailure(md, vReport, crits)) { - addReport(vReport); - CriticalSlot cs = null; - int loc = Entity.LOC_NONE; - for(Enumeration e = crits.elements();e.hasMoreElements();) { - Object o = e.nextElement(); - if(o instanceof Integer) - loc = (Integer) o; - else if (o instanceof CriticalSlot) { - cs = (CriticalSlot) o; - applyCriticalHit(entity, loc, cs, true); - } - } - // no movement after that - md.clear(); - } - } - - overallMoveType = md.getLastStepMovementType(); - - //check for starting in liquid magma - if(game.getBoard().getHex(entity.getPosition()).terrainLevel(Terrains.MAGMA) == 2 - && entity.getElevation() == 0) { - doMagmaDamage(entity, false); - } - - // iterate through steps - firstStep = true; - fellDuringMovement = false; - /* Bug 754610: Revert fix for bug 702735. */ - MoveStep prevStep = null; - - Vector movePath = new Vector(); - - for (final Enumeration i = md.getSteps(); i.hasMoreElements();) { - final MoveStep step = (MoveStep)i.nextElement(); - wasProne = entity.isProne(); - boolean isPavementStep = step.isPavementStep(); - boolean entityFellWhileAttemptingToStand = false; - - // stop for illegal movement - if (step.getMovementType() == IEntityMovementType.MOVE_ILLEGAL) { - break; - } - - //stop if the entity already killed itself - if(entity.isDestroyed() || entity.isDoomed()) { - break; - } - - // check piloting skill for getting up - rollTarget = entity.checkGetUp(step); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - entity.heatBuildup += 1; - entity.setProne(false); - entity.setHullDown(false); - wasProne = false; - game.resetPSRs(entity); - entityFellWhileAttemptingToStand = !doSkillCheckInPlace(entity, rollTarget); - } - // did the entity just fall? - if (entityFellWhileAttemptingToStand) { - moveType = step.getMovementType(); - curFacing = entity.getFacing(); - curPos = entity.getPosition(); - mpUsed = step.getMpUsed(); - fellDuringMovement = true; - break; - } - - if (step.getType() == MovePath.STEP_UNJAM_RAC) { - entity.setUnjammingRAC(true); - game.addAction(new UnjamAction(entity.getId())); - - break; - } - - if (step.getType() == MovePath.STEP_LAY_MINE) { - LayMinefieldAction lma = new LayMinefieldAction(entity.getId(), step.getMineToLay()); - game.addLayMinefieldAction(lma); - entity.setLayingMines(true); - break; - } - - if (step.getType() == MovePath.STEP_SEARCHLIGHT && entity.hasSpotlight()) { - final boolean SearchOn = !entity.isUsingSpotlight(); - entity.setSpotlightState(SearchOn); - sendServerChat(entity.getDisplayName() + " switched searchlight "+(SearchOn?"on":"off")+"."); - } - - // set most step parameters - moveType = step.getMovementType(); - distance = step.getDistance(); - mpUsed = step.getMpUsed(); - - // check for charge - if (step.getType() == MovePath.STEP_CHARGE) { - if (entity.canCharge()) { - checkExtremeGravityMovement(entity, step, curPos, cachedGravityLimit); - Targetable target = step.getTarget( game ); - ChargeAttackAction caa = new ChargeAttackAction(entity.getId(), target.getTargetType(), target.getTargetId(), target.getPosition()); - entity.setDisplacementAttack(caa); - game.addCharge(caa); - charge = caa; - } else { - sendServerChat("Illegal charge!! I don't think "+entity.getDisplayName() +" should be allowed to charge,"+ - " but the client of "+entity.getOwner().getName()+" disagrees."); - sendServerChat("Please make sure "+entity.getOwner().getName()+" is running MegaMek "+MegaMek.VERSION+ - ", or if that is already the case, submit a bug report at http://megamek.sf.net/"); - return; - } - break; - } - - // check for dfa - if (step.getType() == MovePath.STEP_DFA) { - if (entity.canDFA()) { - checkExtremeGravityMovement(entity, step, curPos, cachedGravityLimit); - Targetable target = step.getTarget( game ); - DfaAttackAction daa = new DfaAttackAction(entity.getId(), target.getTargetType(), target.getTargetId(), target.getPosition()); - entity.setDisplacementAttack(daa); - game.addCharge(daa); - charge = daa; - } else { - sendServerChat("Illegal DFA!! I don't think "+entity.getDisplayName() +" should be allowed to DFA,"+ - " but the client of "+entity.getOwner().getName()+" disagrees."); - sendServerChat("Please make sure "+entity.getOwner().getName()+" is running MegaMek "+MegaMek.VERSION+ - ", or if that is already the case, submit a bug report at http://megamek.sf.net/"); - return; - } - break; - } - - // set last step parameters - curPos = step.getPosition(); - if(moveType != IEntityMovementType.MOVE_JUMP || entity.getJumpType() != Mech.JUMP_BOOSTER) - curFacing = step.getFacing(); - curVTOLElevation = step.getElevation(); - //set elevation in case of collapses - entity.setElevation(step.getElevation()); - - final IHex curHex = game.getBoard().getHex(curPos); - - // check for automatic unstick - if(entity.canUnstickByJumping() && entity.isStuck() && moveType == IEntityMovementType.MOVE_JUMP) { - entity.setStuck(false); - entity.setCanUnstickByJumping(false); - } - - // Check for skid. - rollTarget = entity.checkSkid(moveType, prevHex, overallMoveType, - prevStep, prevFacing, curFacing, - lastPos, curPos, isInfantry, - distance); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - // Have an entity-meaningful PSR message. - boolean psrPassed = true; - if ( entity instanceof Mech ) { - psrPassed = doSkillCheckWhileMoving( entity, lastPos, - lastPos, rollTarget, - true ); - } else { - psrPassed = doSkillCheckWhileMoving( entity, lastPos, - lastPos, rollTarget, - false ); - } - // Does the entity skid? - if ( !psrPassed ){ - - curPos = lastPos; - Coords nextPos = curPos; - IHex nextHex = null; - int skidDistance = 0; - Enumeration targets = null; - Entity target = null; - int curElevation; - int nextElevation; - int skidDirection = prevFacing; - - // All charge damage is based upon - // the pre-skid move distance. - entity.delta_distance = distance-1; - - // Attacks against a skidding target have additional +2. - moveType = IEntityMovementType.MOVE_SKID; - - // What is the first hex in the skid? - if(step.isThisStepBackwards()) { - skidDirection = (skidDirection + 3) % 6; - } - nextPos = curPos.translated( skidDirection ); - nextHex = game.getBoard().getHex( nextPos ); - - // Move the entity a number hexes from curPos in the - // skidDirection direction equal to half the distance moved - // this turn (rounded up), unless something intervenes. - for ( skidDistance = 0; - skidDistance < (int) Math.ceil(entity.delta_distance / 2.0); - skidDistance++ ) { - - // Is the next hex off the board? - if ( !game.getBoard().contains(nextPos) ) { - - // Can the entity skid off the map? - if (game.getOptions().booleanOption("push_off_board")) { - // Yup. One dead entity. - game.removeEntity(entity.getId(), - IEntityRemovalConditions.REMOVE_PUSHED); - send(createRemoveEntityPacket(entity.getId(), - IEntityRemovalConditions.REMOVE_PUSHED)); - r = new Report(2030, Report.PUBLIC); - r.addDesc(entity); - addReport(r); - - // TODO: remove passengers and swarmers. - - // The entity's movement is completed. - return; - - } else { - // Nope. Update the report. - r = new Report(2035); - r.subject = entity.getId(); - r.indent(); - addReport(r); - } - // Stay in the current hex and stop skidding. - break; - } - - // Can the skiding entity enter the next hex from this? - // N.B. can skid along roads. - if ( ( entity.isHexProhibited(curHex) || - entity.isHexProhibited(nextHex) ) && - !Compute.canMoveOnPavement(game, curPos, nextPos) - ) { - // Update report. - r = new Report(2040); - r.subject = entity.getId(); - r.indent(); - r.add(nextPos.getBoardNum(), true); - addReport(r); - - // N.B. the BMRr pg. 22 says that the unit - // "crashes" into the terrain but it doesn't - // mention any damage. - - // Stay in the current hex and stop skidding. - break; - } - - // Hovercraft can "skid" over water. - // all units can skid over ice. - // TODO: allow entities to occupy different levels of - // buildings. - curElevation = curHex.floor(); - nextElevation = nextHex.floor(); - if ( entity instanceof Tank && - entity.getMovementMode() == - IEntityMovementMode.HOVER ) { - if ( curHex.containsTerrain(Terrains.WATER) ) { - curElevation = curHex.surface(); - } - if ( nextHex.containsTerrain(Terrains.WATER) ) { - nextElevation += nextHex.surface(); - } - } else { - if(curHex.containsTerrain(Terrains.ICE)) { - curElevation = curHex.surface(); - } - if(nextHex.containsTerrain(Terrains.ICE)) { - nextElevation = nextHex.surface(); - } - } - - // BMRr pg. 22 - Can't skid uphill, - // but can skid downhill. - if ( curElevation < nextElevation ) { - r = new Report(2045); - r.subject = entity.getId(); - r.indent(); - r.add(nextPos.getBoardNum(), true); - addReport(r); - - // Stay in the current hex and stop skidding. - break; - } - - // Have skidding units suffer falls. - else if ( curElevation > nextElevation + 1 ) { - doEntityFallsInto( entity, curPos, nextPos, - entity.getBasePilotingRoll() ); - doEntityDisplacementMinefieldCheck(entity, curPos, nextPos); - // Stay in the current hex and stop skidding. - break; - } - - // Get any building in the hex. - Building bldg = game.getBoard().getBuildingAt(nextPos); - boolean bldgSuffered = false; - boolean stopTheSkid = false; - // Does the next hex contain an entities? - // ASSUMPTION: hurt EVERYONE in the hex. - // TODO: allow entities to occupy different levels of - // buildings, and only skid into a single level. - targets = game.getEntities( nextPos ); - if ( targets.hasMoreElements()) { - boolean skidChargeHit = false; - while ( targets.hasMoreElements() ) { - target = (Entity) targets.nextElement(); - - // TODO : allow ready targets to move out of way - - // Mechs and vehicles get charged, - // but need to make a to-hit roll - if ( target instanceof Mech || - target instanceof Tank ) { - ChargeAttackAction caa = new ChargeAttackAction(entity.getId(), target.getTargetType(), target.getTargetId(), target.getPosition()); - ToHitData toHit = caa.toHit(game, true); - - // Calculate hit location. - if ( entity instanceof Tank - && ((entity.getMovementMode() == IEntityMovementMode.HOVER) - || (entity.getMovementMode() == IEntityMovementMode.NAVAL) - || (entity.getMovementMode() == IEntityMovementMode.HYDROFOIL)) - && 0 < nextHex.terrainLevel(Terrains.WATER) - && target.getElevation() < 0) { - if ( 2 <= nextHex.terrainLevel(Terrains.WATER) || - target.isProne() ) { - // Hovercraft/Naval Craft can't hit the Mek. - continue; - } - else { - toHit.setHitTable(ToHitData.HIT_PUNCH); - } - } else if ( entity.getHeight() < - target.getHeight() ) { - toHit.setHitTable(ToHitData.HIT_KICK); - } else { - toHit.setHitTable(ToHitData.HIT_NORMAL); - } - toHit.setSideTable - (Compute.targetSideTable(entity, target)); - - // roll - int roll = Compute.d6(2); - // Update report. - r = new Report(2050); - r.subject = entity.getId(); - r.indent(); - r.add(target.getShortName(), true); - r.add(nextPos.getBoardNum(), true); - r.newlines = 0; - addReport(r); - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - roll = -12; - r = new Report(2055); - r.subject = entity.getId(); - r.add(toHit.getDesc()); - r.newlines = 0; - addReport(r); - } else if (toHit.getValue() == ToHitData.AUTOMATIC_SUCCESS) { - r = new Report(2060); - r.subject = entity.getId(); - r.add(toHit.getDesc()); - r.newlines = 0; - addReport(r); - roll = Integer.MAX_VALUE; - } else { - // report the roll - r = new Report(2065); - r.subject = entity.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - } - - // Resolve a charge against the target. - // ASSUMPTION: buildings block damage for - // *EACH* entity charged. - if (roll < toHit.getValue()) { - r = new Report(2070); - r.subject = entity.getId(); - addReport(r); - } else { - // Resolve the charge. - resolveChargeDamage - (entity, target, toHit, skidDirection); - // HACK: set the entity's location - // to the original hex again, for the other targets - if (targets.hasMoreElements()) { - entity.setPosition(curPos); - } - bldgSuffered = true; - skidChargeHit = true; - } - // The skid ends here if the target lives. - if ( !target.isDoomed() && - !target.isDestroyed() && - !game.isOutOfGame(target) ) { - stopTheSkid = true; - } - - // if we don't do this here, - // we can have a mech without a leg - // standing on the field and moving - // as if it still had his leg after - // getting skid-charged. - if (!target.isDone()) { - resolvePilotingRolls(target); - game.resetPSRs(target); - target.applyDamage(); - addNewLines(); - } - - } - - // Resolve "move-through" damage on infantry. - // Infantry inside of a building don't get a - // move-through, but suffer "bleed through" - // from the building. - else if ( target instanceof Infantry && - bldg != null ) { - // Update report. - r = new Report(2075); - r.subject = entity.getId(); - r.indent(); - r.add(target.getShortName(), true); - r.add(nextPos.getBoardNum(), true); - r.newlines = 0; - addReport(r); - - // Infantry don't have different - // tables for punches and kicks - HitData hit = target.rollHitLocation( ToHitData.HIT_NORMAL, Compute.targetSideTable(entity, target) ); - - // Damage equals tonnage, divided by 5. - // ASSUMPTION: damage is applied in one hit. - addReport( - damageEntity(target, hit, - Math.round(entity.getWeight()/5))); - addNewLines(); - } - - // Has the target been destroyed? - if ( target.isDoomed() ) { - - // Has the target taken a turn? - if ( !target.isDone() ) { - - // Dead entities don't take turns. - game.removeTurnFor(target); - send(createTurnVectorPacket()); - - } // End target-still-to-move - - // Clean out the entity. - target.setDestroyed(true); - game.moveToGraveyard(target.getId()); - send(createRemoveEntityPacket(target.getId())); - } - - // Update the target's position, - // unless it is off the game map. - if ( !game.isOutOfGame(target) ) { - entityUpdate( target.getId() ); - } - - } // Check the next entity in the hex. - - // if we missed all the entities in the hex, - // move attacker to side hex - if (!skidChargeHit) { - Coords src = entity.getPosition(); - Coords dest = Compute.getMissedChargeDisplacement - (game, entity.getId(), src, skidDirection); - doEntityDisplacement(entity, src, dest, null); - } else { - // HACK: otherwise, set the entities position to that - // hex's coords, because we had to move the entity - // back earlier for the other targets - entity.setPosition(nextPos); - } - } - - // Handle the building in the hex. - // TODO : BMRr pg. 22, only count buildings that are - // higher than our starting terrain height. - // TODO: allow units to skid on top of buildings. - if ( bldg != null ) { - - // Report that the entity has entered the bldg. - r = new Report(2080); - r.subject = entity.getId(); - r.indent(); - r.add(bldg.getName()); - r.add(nextPos.getBoardNum(), true); - addReport(r); - - // If the building hasn't already suffered - // damage, then apply charge damage to the - // building and displace the entity inside. - // ASSUMPTION: you don't charge the building - // if Tanks or Mechs were charged. - int chargeDamage = ChargeAttackAction.getDamageFor - ( entity ); - if ( !bldgSuffered ) { - Report buildingReport = damageBuilding( bldg, chargeDamage ); - buildingReport.indent(2); - buildingReport.subject = entity.getId(); - addReport(buildingReport); - - // Apply damage to the attacker. - int toAttacker = ChargeAttackAction.getDamageTakenBy - ( entity, bldg ); - HitData hit = entity.rollHitLocation( ToHitData.HIT_NORMAL, - entity.sideTable(nextPos) - ); - addReport( - damageEntity( entity, hit, toAttacker )); - addNewLines(); - - entity.setPosition( nextPos ); - doEntityDisplacementMinefieldCheck(entity, curPos, nextPos); - curPos = nextPos; - } // End buildings-suffer-too - - // Any infantry in the building take damage - // equal to the building being charged. - // ASSUMPTION: infantry take no damage from the - // building absorbing damage from - // Tanks and Mechs being charged. - damageInfantryIn( bldg, chargeDamage ); - - // If a building still stands, then end the skid, - // and add it to the list of affected buildings. - if ( bldg.getCurrentCF() > 0 ) { - stopTheSkid = true; - this.addAffectedBldg( bldg, false ); - } - - } // End handle-building. - - // Do we stay in the current hex and stop skidding? - if ( stopTheSkid ) { - break; - } - // is the next hex a rubble hex? - rollTarget = entity.checkRubbleMove(step, nextHex, - curPos, nextPos); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - doSkillCheckWhileMoving(entity, curPos, nextPos, - rollTarget, true); - if (entity.isProne()) { - // if we fell, stop the skid (see bug 1115608) - break; - } - } - - //check for breaking magma crust - if(curHex.terrainLevel(Terrains.MAGMA) == 1) { - int roll = Compute.d6(1); - r = new Report(2395); - r.addDesc(entity); - r.add(roll); - r.subject = entity.getId(); - addReport(r); - if(roll == 6) { - curHex.removeTerrain(Terrains.MAGMA); - curHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.MAGMA, 2)); - sendChangedHex(curPos); - for(Enumeration e=game.getEntities(curPos);e.hasMoreElements();) { - Entity en = (Entity)e.nextElement(); - if(en != entity) - doMagmaDamage(en, false); - } - } - } - - //check for entering liquid magma - if(curHex.terrainLevel(Terrains.MAGMA) == 2) { - doMagmaDamage(entity, false); - } - - // is the next hex a swamp? - rollTarget = entity.checkSwampMove(step, nextHex, - curPos, nextPos); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - if (!doSkillCheckWhileMoving(entity, curPos, - nextPos, rollTarget, false)){ - entity.setStuck(true); - r = new Report(2081); - r.subject = entity.getId(); - r.add(entity.getDisplayName(), true); - // stay here and stop skidding, see bug 1115608 - break; - } - } - - // Update the position and keep skidding. - entity.setPosition( nextPos ); - doEntityDisplacementMinefieldCheck(entity, curPos, nextPos); - curPos = nextPos; - r = new Report(2085); - r.subject = entity.getId(); - r.indent(); - r.add(curPos.getBoardNum(), true); - addReport(r); - - // Get the next hex in the skid? - nextPos = nextPos.translated( skidDirection ); - nextHex = game.getBoard().getHex( nextPos ); - - } // Handle the next skid hex. - - // If the skidding entity violates stacking, - // displace targets until it doesn't. - curPos = entity.getPosition(); - target = Compute.stackingViolation - (game, entity.getId(), curPos); - while (target != null) { - nextPos = Compute.getValidDisplacement - (game, target.getId(), - target.getPosition(), skidDirection); - // ASSUMPTION - // There should always be *somewhere* that - // the target can go... last skid hex if - // nothing else is available. - if ( null == nextPos ) { - // But I don't trust the assumption fully. - // Report the error and try to continue. - System.err.println( "The skid of " + - entity.getShortName() + - " should displace " + - target.getShortName() + - " in hex " + - curPos.getBoardNum() + - " but there is nowhere to go." - ); - break; - } - // indent displacement - r = new Report(1210, Report.PUBLIC); - r.indent(); - r.newlines = 0; - addReport(r); - doEntityDisplacement(target, curPos, nextPos, null); - doEntityDisplacementMinefieldCheck(entity, curPos, nextPos); - target = Compute.stackingViolation( game, - entity.getId(), - curPos ); - } - - // Mechs suffer damage for every hex skidded. - if ( entity instanceof Mech ) { - // Calculate one half falling damage times skid length. - int damage = skidDistance * (int) Math.ceil(Math.round(entity.getWeight() / 10.0) / 2.0); - - // report skid damage - r = new Report(2090); - r.subject = entity.getId(); - r.indent(); - r.addDesc(entity); - r.add(damage); - addReport(r); - - // standard damage loop - // All skid damage is to the front. - while (damage > 0) { - int cluster = Math.min(5, damage); - HitData hit = entity.rollHitLocation(ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT); - addReport( - damageEntity(entity, hit, cluster)); - damage -= cluster; - } - addNewLines(); - } - - // Clean up the entity if it has been destroyed. - if ( entity.isDoomed() ) { - entity.setDestroyed(true); - game.moveToGraveyard(entity.getId()); - send(createRemoveEntityPacket(entity.getId())); - - // The entity's movement is completed. - return; - } - - // Let the player know the ordeal is over. - r = new Report(2095); - r.subject = entity.getId(); - r.indent(); - addReport(r); - - // set entity parameters - curFacing = entity.getFacing(); - curPos = entity.getPosition(); - entity.setSecondaryFacing( curFacing ); - - // skid consumes all movement - if (md.hasActiveMASC()) { - mpUsed = entity.getRunMP(); - } else { - mpUsed = entity.getRunMPwithoutMASC(); - } - - entity.moved = moveType; - fellDuringMovement = true; - distance = entity.delta_distance; - break; - - } // End failed-skid-psr - - } // End need-skid-psr - if(entity instanceof VTOL) { - rollTarget = ((VTOL)entity).checkSideSlip(moveType, prevHex, overallMoveType, - prevStep, prevFacing, curFacing, - lastPos, curPos, - distance); - if(rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - if(!doSkillCheckWhileMoving(entity,lastPos,curPos,rollTarget, false)) { - //report sideslip - sideslipped = true; - r = new Report(2100); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - Coords newPos = lastPos.translated((prevFacing));//does this work for opposing hex? - // Is the next hex off the board? - if ( !game.getBoard().contains(newPos) ) { - // Can the entity skid off the map? - if (game.getOptions().booleanOption("push_off_board")) { - // Yup. One dead entity. - game.removeEntity(entity.getId(), - IEntityRemovalConditions.REMOVE_PUSHED); - send(createRemoveEntityPacket(entity.getId(), - IEntityRemovalConditions.REMOVE_PUSHED)); - r = new Report(2030); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - - // TODO: remove passengers and swarmers. - // The entity's movement is completed. - return; - } else { - // Nope. Update the report. - r = new Report(2035); - r.subject = entity.getId(); - addReport(r); - } - // Stay in the current hex and stop skidding. - break; - } - IHex hex = game.getBoard().getHex(newPos); - int terrainLevel = hex.ceiling() - hex.surface(); - int newElevation=(entity.calcElevation(game.getBoard().getHex(curPos),game.getBoard().getHex(newPos),curVTOLElevation,step.climbMode())); - if(newElevation<=terrainLevel) { - r = new Report(2105); - r.subject = entity.getId(); - r.add(newPos.getBoardNum(), true); - addReport(r); - - int hitSide=curFacing-prevFacing+6; - hitSide=hitSide % 6; - int table=0; - switch(hitSide) {//quite hackish...I think it ought to work, though. - case 0://can this happen? - table=ToHitData.SIDE_FRONT; - break; - case 1: - case 2: - table=ToHitData.SIDE_LEFT; - break; - case 3: - table=ToHitData.SIDE_REAR; - break; - case 4: - case 5: - table=ToHitData.SIDE_RIGHT; - break; - } - curPos=newPos; - curVTOLElevation=newElevation; - addReport(crashVTOL(((VTOL)entity),true,distance,curPos,curVTOLElevation,table)); - - if((hex.containsTerrain(Terrains.WATER) && !hex.containsTerrain(Terrains.ICE)) - || hex.containsTerrain(Terrains.WOODS) - || hex.containsTerrain(Terrains.JUNGLE)) { - addReport(destroyEntity(entity,"could not land in crash site")); - } else if(newElevation < hex.terrainLevel(Terrains.BLDG_ELEV)){ - addReport(destroyEntity(entity, "crashed into building")); - } - } else { - r = new Report(2110); - r.subject = entity.getId(); - r.add(newPos.getBoardNum(), true); - addReport(r); - entity.setElevation(entity.calcElevation(game.getBoard().getHex(curPos),game.getBoard().getHex(newPos),curVTOLElevation,step.climbMode())); - curPos=newPos; - } - - if(!entity.isDestroyed() && !entity.isDoomed()) { - fellDuringMovement= true; //No, but it should work... - } - break; - } - } - } - - // check if we've moved into rubble - rollTarget = entity.checkRubbleMove(step, curHex, lastPos, curPos); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - doSkillCheckWhileMoving(entity, lastPos, curPos, rollTarget, - true); - } - - //check for breaking magma crust - if(curHex.terrainLevel(Terrains.MAGMA) == 1 - && step.getElevation() == 0 - && step.getMovementType() != IEntityMovementType.MOVE_JUMP) { - int roll = Compute.d6(1); - r = new Report(2395); - r.addDesc(entity); - r.add(roll); - r.subject = entity.getId(); - addReport(r); - if(roll == 6) { - curHex.removeTerrain(Terrains.MAGMA); - curHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.MAGMA, 2)); - sendChangedHex(curPos); - for(Enumeration e=game.getEntities(curPos);e.hasMoreElements();) { - Entity en = (Entity)e.nextElement(); - if(en != entity) - doMagmaDamage(en, false); - } - } - } - - //check for entering liquid magma - if(curHex.terrainLevel(Terrains.MAGMA) == 2 - && step.getElevation() == 0 - && step.getMovementType() != IEntityMovementType.MOVE_JUMP) { - doMagmaDamage(entity, false); - } - - // check if we've moved into a swamp - rollTarget = entity.checkSwampMove(step, curHex, lastPos, curPos); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - if (!doSkillCheckWhileMoving(entity, lastPos, curPos, rollTarget, - false)){ - entity.setStuck(true); - entity.setCanUnstickByJumping(true); - r = new Report(2081); - r.add(entity.getDisplayName()); - r.subject = entity.getId(); - addReport(r); - break; - } - } - - // check to see if we are a mech and we've moved OUT of fire - IHex lastHex = game.getBoard().getHex(lastPos); - if (entity instanceof Mech) { - if ( !lastPos.equals(curPos) - && (lastHex.containsTerrain(Terrains.FIRE) - || lastHex.containsTerrain(Terrains.MAGMA)) - && ( step.getMovementType() != IEntityMovementType.MOVE_JUMP - // Bug #828741 -- jumping bypasses fire, but not on the first step - // getMpUsed -- total MP used to this step - // getMp -- MP used in this step - // the difference will always be 0 on the "first step" of a jump, - // and >0 on a step in the midst of a jump - || ( 0 == step.getMpUsed() - step.getMp() ) ) ) - { - int heat=0; - if(lastHex.containsTerrain(Terrains.FIRE)) - heat+=2; - if(lastHex.terrainLevel(Terrains.MAGMA) == 1) { - heat+=2; - } - else if(lastHex.terrainLevel(Terrains.MAGMA) == 2) { - heat+=5; - } - entity.heatBuildup+=heat; - r = new Report(2115); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(heat); - addReport(r); - } - } - - // check to see if we are not a mech and we've moved INTO fire - if (!(entity instanceof Mech)) { - if ( game.getBoard().getHex(curPos).containsTerrain(Terrains.FIRE) - && !lastPos.equals(curPos) - && step.getMovementType() != IEntityMovementType.MOVE_JUMP - && step.getElevation() <= 1 ) { - if(game.getOptions().booleanOption("vehicle_fires") - && entity instanceof Tank) { - checkForVehicleFire((Tank)entity, false); - } else { - doFlamingDeath(entity); - } - } - } - // check for extreme gravity movement - if (!i.hasMoreElements() && !firstStep) { - checkExtremeGravityMovement(entity, step, curPos, cachedGravityLimit); - } - // check for minefields. - if ((!lastPos.equals(curPos) && (step.getMovementType() != IEntityMovementType.MOVE_JUMP)) - || ((overallMoveType == IEntityMovementType.MOVE_JUMP) && (!i.hasMoreElements()))) { - checkVibrabombs(entity, curPos, false, lastPos, curPos); - if (game.containsMinefield(curPos)) { - Enumeration minefields = game.getMinefields(curPos).elements(); - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - - boolean isOnGround = (!i.hasMoreElements()); - isOnGround |= (step.getMovementType() != IEntityMovementType.MOVE_JUMP); - isOnGround &= step.getElevation() == 0; - if (isOnGround) { - enterMinefield(entity, mf, curPos, curPos, true); - } else if (mf.getType() == Minefield.TYPE_THUNDER_ACTIVE) { - enterMinefield(entity, mf, curPos, curPos, true, 2); - } - } - } - } - - // infantry discovers minefields if they end their move - // in a minefield. - - if (!lastPos.equals(curPos) && - !i.hasMoreElements() && - isInfantry) { - if (game.containsMinefield(curPos)) { - Player owner = entity.getOwner(); - Enumeration minefields = game.getMinefields(curPos).elements(); - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - if (!owner.containsMinefield(mf)) { - r = new Report(2120); - r.subject = entity.getId(); - r.add(entity.getShortName(), true); - addReport(r); - revealMinefield(owner, mf); - } - } - } - } - - // check if we've moved into water - rollTarget = entity.checkWaterMove(step, curHex, lastPos, curPos, - isPavementStep); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - // Swarmers need special handling. - final int swarmerId = entity.getSwarmAttackerId(); - boolean swarmerDone = true; - Entity swarmer = null; - if (Entity.NONE != swarmerId) { - swarmer = game.getEntity( swarmerId ); - swarmerDone = swarmer.isDone(); - } - - // Now do the skill check. - doSkillCheckWhileMoving(entity, lastPos, curPos, rollTarget, - true); - - // Swarming infantry platoons may drown. - if (curHex.terrainLevel(Terrains.WATER) > 1) { - drownSwarmer(entity, curPos); - } - - // Do we need to remove a game turn for the swarmer - if (!swarmerDone && - ( swarmer.isDoomed() || swarmer.isDestroyed() )) { - // We have to diddle with the swarmer's - // status to get its turn removed. - swarmer.setDone( false ); - swarmer.setUnloaded( false ); - - // Dead entities don't take turns. - game.removeTurnFor( swarmer ); - send( createTurnVectorPacket() ); - - // Return the original status. - swarmer.setDone( true ); - swarmer.setUnloaded( true ); - } - - // check for inferno wash-off - checkForWashedInfernos(entity, curPos); - } - - // In water, may or may not be a new hex, neccessary to - // check during movement, for breach damage, and always - // set dry if appropriate - //TODO: possibly make the locations local and set later - doSetLocationsExposure(entity, curHex, - step.getMovementType() == IEntityMovementType.MOVE_JUMP, - step.getElevation()); - - //check for breaking ice by breaking through from below - if(prevHex != null && prevStep != null - && prevStep.getElevation() < 0 - && step.getElevation() == 0 - && prevHex.containsTerrain(Terrains.ICE) - && prevHex.containsTerrain(Terrains.WATER) - && step.getMovementType() != IEntityMovementType.MOVE_JUMP - && !(lastPos.equals(curPos))) { - r = new Report(2410); - r.addDesc(entity); - addReport(r); - resolveIceBroken(lastPos); - } - //check for breaking ice by stepping on it - if(curHex.containsTerrain(Terrains.ICE) - && curHex.containsTerrain(Terrains.WATER) - && step.getMovementType() != IEntityMovementType.MOVE_JUMP - && !(lastPos.equals(curPos))) { - if(step.getElevation() == 0 - ) { - int roll = Compute.d6(1); - r = new Report(2118); - r.addDesc(entity); - r.add(roll); - r.subject = entity.getId(); - addReport(r); - if(roll == 6) { - resolveIceBroken(curPos); - doEntityFallsInto(entity, lastPos, curPos, entity.getBasePilotingRoll(), false); - } - } - //or intersecting it - else if(step.getElevation() + entity.height() == 0) { - r = new Report(2410); - r.addDesc(entity); - addReport(r); - resolveIceBroken(curPos); - } - } - - // Handle loading units. - if ( step.getType() == MovePath.STEP_LOAD ) { - - // Find the unit being loaded. - Entity loaded = null; - Enumeration entities = game.getEntities( curPos ); - while ( entities.hasMoreElements() ) { - - // Is the other unit friendly and not the current entity? - loaded = (Entity)entities.nextElement(); - if ( entity.getOwner() == loaded.getOwner() && - !entity.equals(loaded) ) { - - // The moving unit should be able to load the other - // unit and the other should be able to have a turn. - if ( !entity.canLoad(loaded) || - !loaded.isSelectableThisTurn() ) { - // Something is fishy in Denmark. - System.err.println( entity.getShortName() + - " can not load " + - loaded.getShortName() ); - loaded = null; - } - else { - // Have the deployed unit load the indicated unit. - this.loadUnit( entity, loaded ); - - // Stop looking. - break; - } - - } else { - // Nope. Discard it. - loaded = null; - } - - } // Handle the next entity in this hex. - - // We were supposed to find someone to load. - if ( loaded == null ) { - System.err.println( "Could not find unit for " + - entity.getShortName() + - " to load in " + curPos ); - } - - } // End STEP_LOAD - - // Handle unloading units. - if ( step.getType() == MovePath.STEP_UNLOAD ) { - Targetable unloaded = step.getTarget( game ); - if ( !this.unloadUnit( entity, unloaded, - curPos, curFacing, step.getElevation() ) ) { - System.err.println( "Error! Server was told to unload " + - unloaded.getDisplayName() + - " from " + entity.getDisplayName() + - " into " + curPos.getBoardNum() ); - } - } - - // Handle non-infantry moving into a building. - int buildingMove = entity.checkMovementInBuilding(step, prevStep, curPos, lastPos); - if (buildingMove > 0) { - - // Get the building being exited. - Building bldgExited = null; - if((buildingMove & 1) == 1) - bldgExited = game.getBoard().getBuildingAt( lastPos ); - - // Get the building being entered. - Building bldgEntered = null; - if((buildingMove & 2) == 2) - bldgEntered = game.getBoard().getBuildingAt( curPos ); - - // Get the building being stepped on. - Building bldgStepped = null; - if((buildingMove & 4) == 4) - bldgStepped = game.getBoard().getBuildingAt( curPos ); - - boolean collapsed = false; - //are we passing through a building wall? - if(bldgEntered != null || bldgExited != null) { - // If we're not leaving a building, just handle the "entered". - if ( bldgExited == null) { - collapsed = passBuildingWall( entity, bldgEntered, - lastPos, curPos, - distance, "entering" ); - this.addAffectedBldg( bldgEntered, collapsed ); - } - - // If we're moving withing the same building, just handle - // the "within". - else if ( bldgExited.equals( bldgEntered ) ) { - collapsed = passBuildingWall( entity, bldgEntered, - lastPos, curPos, - distance, "moving in" ); - this.addAffectedBldg( bldgEntered, collapsed ); - } - - // If we have different buildings, roll for each. - else if ( bldgExited != null && bldgEntered != null ) { - collapsed = passBuildingWall( entity, bldgExited, - lastPos, curPos, - distance, "exiting" ); - this.addAffectedBldg( bldgExited, collapsed ); - collapsed = passBuildingWall( entity, bldgEntered, - lastPos, curPos, - distance, "entering" ); - this.addAffectedBldg( bldgEntered, collapsed ); - } - - // Otherwise, just handle the "exited". - else if (bldgExited != null){ - collapsed = passBuildingWall( entity, bldgExited, - lastPos, curPos, - distance, "exiting" ); - this.addAffectedBldg( bldgExited, collapsed ); - } - } - - //stepping on roof, no PSR just check for over weight - if(bldgStepped != null) { - collapsed = checkBuildingCollapseWhileMoving(bldgStepped, entity, curPos); - this.addAffectedBldg( bldgStepped, collapsed ); - } - - // Clean up the entity if it has been destroyed. - if ( entity.isDoomed() ) { - entity.setDestroyed(true); - game.moveToGraveyard(entity.getId()); - send(createRemoveEntityPacket(entity.getId())); - - // The entity's movement is completed. - return; - } - - // TODO: what if a building collapses into rubble? - } - - // did the entity just fall? - if (!wasProne && entity.isProne()) { - curFacing = entity.getFacing(); - curPos = entity.getPosition(); - mpUsed = step.getMpUsed(); - fellDuringMovement = true; - break; - } - - // dropping prone intentionally? - if (step.getType() == MovePath.STEP_GO_PRONE) { - mpUsed = step.getMpUsed(); - rollTarget = entity.checkDislodgeSwarmers(step); - if (rollTarget.getValue() == TargetRoll.CHECK_FALSE) { - // Not being swarmed - entity.setProne(true); - // check to see if we washed off infernos - checkForWashedInfernos(entity, curPos); - break; - } else { - // Being swarmed - entity.setPosition(curPos); - if (doDislodgeSwarmerSkillCheck(entity, - rollTarget, - curPos)) { - // Entity falls - curFacing = entity.getFacing(); - curPos = entity.getPosition(); - fellDuringMovement = true; - break; - } - } - } - - //going hull down - if(step.getType() == MovePath.STEP_HULL_DOWN) { - mpUsed = step.getMpUsed(); - entity.setHullDown(true); - } - - // Track this step's location. - movePath.addElement( new UnitLocation( entity.getId(), - curPos, - curFacing ) ); - - // update lastPos, prevStep, prevFacing & prevHex - lastPos = new Coords(curPos); - prevStep = step; - /* Bug 754610: Revert fix for bug 702735. - if (prevHex != null && !curHex.equals(prevHex)) { - */ - if (!curHex.equals(prevHex)) { - prevFacing = curFacing; - } - prevHex = curHex; - - firstStep = false; - } - - // set entity parameters - entity.setPosition(curPos); - entity.setFacing(curFacing); - entity.setSecondaryFacing(curFacing); - entity.delta_distance = distance; - entity.moved = moveType; - entity.mpUsed = mpUsed; - if (!sideslipped && !fellDuringMovement) { - entity.setElevation(curVTOLElevation); - } - entity.setClimbMode(md.getFinalClimbMode()); - - - - // if we ran with destroyed hip or gyro, we need a psr - rollTarget = entity.checkRunningWithDamage(overallMoveType); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - doSkillCheckInPlace(entity, rollTarget); - } - - // but the danger isn't over yet! landing from a jump can be risky! - if (overallMoveType == IEntityMovementType.MOVE_JUMP && !entity.isMakingDfa()) { - final IHex curHex = game.getBoard().getHex(curPos); - // check for damaged criticals - rollTarget = entity.checkLandingWithDamage(); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - doSkillCheckInPlace(entity, rollTarget); - } - // jumped into water? - int waterLevel = curHex.terrainLevel(Terrains.WATER); - if(curHex.containsTerrain(Terrains.ICE) && waterLevel > 0) { - waterLevel = 0; - //check for breaking ice - int roll = Compute.d6(1); - r = new Report(2122); - r.add(entity.getDisplayName(), true); - r.add(roll); - r.subject = entity.getId(); - addReport(r); - if(roll >= 4) { - //oops! - resolveIceBroken(curPos); - doEntityFallsInto(entity, lastPos, curPos, entity.getBasePilotingRoll(), false); - } - } - rollTarget = entity.checkWaterMove(waterLevel); - if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - doSkillCheckInPlace(entity, rollTarget); - } - if (waterLevel > 1) { - // Any swarming infantry will be destroyed. - drownSwarmer(entity, curPos); - } - - //check for building collapse - Building bldg = game.getBoard().getBuildingAt(curPos); - if(bldg != null) { - checkForCollapse( bldg, game.getPositionMap() ); - } - - //check for breaking magma crust - if(curHex.terrainLevel(Terrains.MAGMA) == 1) { - int roll = Compute.d6(1); - r = new Report(2395); - r.addDesc(entity); - r.add(roll); - r.subject = entity.getId(); - addReport(r); - if(roll == 6) { - curHex.removeTerrain(Terrains.MAGMA); - curHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.MAGMA, 2)); - sendChangedHex(curPos); - for(Enumeration e=game.getEntities(curPos);e.hasMoreElements();) { - Entity en = (Entity)e.nextElement(); - if(en != entity) - doMagmaDamage(en, false); - } - } - } - - //check for entering liquid magma - if(curHex.terrainLevel(Terrains.MAGMA) == 2) { - doMagmaDamage(entity, false); - } - - // jumped into swamp? maybe stuck! - if (curHex.containsTerrain(Terrains.SWAMP) - || curHex.containsTerrain(Terrains.MAGMA) - || curHex.containsTerrain(Terrains.SNOW) - || curHex.containsTerrain(Terrains.MUD) - || curHex.containsTerrain(Terrains.TUNDRA)) { - if (entity instanceof Mech) { - entity.setStuck(true); - r = new Report(2121); - r.add(entity.getDisplayName(), true); - r.subject = entity.getId(); - addReport(r); - } else if (entity instanceof Infantry) { - PilotingRollData roll = entity.getBasePilotingRoll(); - roll.addModifier(5, "infantry jumping into swamp"); - if (!doSkillCheckWhileMoving(entity, curPos, curPos, roll, false)) { - entity.setStuck(true); - r = new Report(2081); - r.add(entity.getDisplayName()); - r.subject = entity.getId(); - addReport(r); - } - } - } - - // If the entity is being swarmed, jumping may dislodge the fleas. - final int swarmerId = entity.getSwarmAttackerId(); - if ( Entity.NONE != swarmerId ) { - final Entity swarmer = game.getEntity( swarmerId ); - final PilotingRollData roll = - entity.getBasePilotingRoll(); - - entity.addPilotingModifierForTerrain(roll); - - // Add a +4 modifier. - roll.addModifier( 4, "dislodge swarming infantry" ); - - // If the swarmer has Assault claws, give a 1 modifier. - // We can stop looking when we find our first match. - for ( Enumeration iter = swarmer.getMisc(); - iter.hasMoreElements(); ) { - Mounted mount = (Mounted) iter.nextElement(); - EquipmentType equip = mount.getType(); - if ( BattleArmor.ASSAULT_CLAW.equals - (equip.getInternalName()) ) { - roll.addModifier( 1, "swarmer has assault claws" ); - break; - } - } - - // okay, print the info - r = new Report(2125); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - - // roll - final int diceRoll = Compute.d6(2); - r = new Report(2130); - r.subject = entity.getId(); - r.add(roll.getValueAsString()); - r.add(roll.getDesc()); - r.add(diceRoll); - if (diceRoll < roll.getValue()) { - r.choose(false); - addReport(r); - } else { - // Dislodged swarmers don't get turns. - game.removeTurnFor( swarmer ); - send( createTurnVectorPacket() ); - - // Update the report and the swarmer's status. - r.choose(true); - addReport(r); - entity.setSwarmAttackerId( Entity.NONE ); - swarmer.setSwarmTargetId( Entity.NONE ); - - // Did the infantry fall into water? - if ( curHex.terrainLevel(Terrains.WATER) > 0 ) { - // Swarming infantry die. - swarmer.setPosition( curPos ); - r = new Report(2135); - r.subject = entity.getId(); - r.indent(); - r.addDesc(swarmer); - addReport(r); - addReport( - destroyEntity(swarmer, "a watery grave", false)); - } else { - // Swarming infantry take an 11 point hit. - // ASSUMPTION : damage should not be doubled. - r = new Report(2140); - r.subject = entity.getId(); - r.indent(); - r.addDesc(swarmer); - addReport(r); - addReport(damageEntity(swarmer, swarmer.rollHitLocation(ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT), 11)); - addNewLines(); - swarmer.setPosition( curPos ); - } - entityUpdate( swarmerId ); - } // End successful-PSR - - } // End try-to-dislodge-swarmers - - // one more check for inferno wash-off - checkForWashedInfernos(entity, curPos); - - } // End entity-is-jumping - // update entity's locations' exposure - doSetLocationsExposure(entity, game.getBoard().getHex(curPos), false, entity.getElevation()); - - // should we give another turn to the entity to keep moving? - if (fellDuringMovement && entity.mpUsed < entity.getRunMP() - && entity.isSelectableThisTurn() && !entity.isDoomed()) { - entity.applyDamage(); - entity.setDone(false); - GameTurn newTurn = new GameTurn.SpecificEntityTurn(entity.getOwner().getId(), entity.getId()); - game.insertNextTurn(newTurn); - // brief everybody on the turn update - send(createTurnVectorPacket()); - // let everyone know about what just happened - send(entity.getOwner().getId(), createSpecialReportPacket()); - } else { - entity.setDone(true); - } - - // If the entity is being swarmed, update the attacker's position. - final int swarmerId = entity.getSwarmAttackerId(); - if ( Entity.NONE != swarmerId ) { - final Entity swarmer = game.getEntity( swarmerId ); - swarmer.setPosition( curPos ); - // If the hex is on fire, and the swarming infantry is - // *not* Battle Armor, it drops off. - if ( !(swarmer instanceof BattleArmor) && - game.getBoard().getHex(curPos).containsTerrain(Terrains.FIRE) ) { - swarmer.setSwarmTargetId( Entity.NONE ); - entity.setSwarmAttackerId( Entity.NONE ); - r = new Report(2145); - r.subject = entity.getId(); - r.indent(); - r.add(swarmer.getShortName(), true); - addReport(r); - } - entityUpdate( swarmerId ); - } - - // Update the entitiy's position, - // unless it is off the game map. - if (!game.isOutOfGame(entity)) { - entityUpdate( entity.getId(), movePath ); - if (entity.isDoomed()) { - send(createRemoveEntityPacket(entity.getId(), entity.getRemovalCondition())); - } - } - - // if using double blind, update the player on new units he might see - if (doBlind()) { - send(entity.getOwner().getId(), createFilteredEntitiesPacket(entity.getOwner())); - } - - // if we generated a charge attack, report it now - if (charge != null) { - send(createAttackPacket(charge, 1)); - } - } - - - /** - * Delivers a thunder-aug shot to the targetted hex area. - * Thunder-Augs are 7 hexes, though, so... - */ - private void deliverThunderAugMinefield( Coords coords, - int playerId, int damage ) { - Coords mfCoord = null; - for (int dir=0; dir < 7; dir++) { - switch (dir) { - case 6: - // The targeted hex. - mfCoord = new Coords(coords); - break; - default: - // The hex in the dir direction from the targeted hex. - mfCoord = coords.translated(dir); - break; - } - - // Only if this is on the board... - if ( game.getBoard().contains(mfCoord) ) { - Minefield minefield = null; - Enumeration minefields = game.getMinefields(mfCoord).elements(); - // Check if there already are Thunder minefields in the hex. - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - if (mf.getType() == Minefield.TYPE_THUNDER) { - minefield = mf; - break; - } - } - - // Did we find a Thunder minefield in the hex? - // N.B. damage Thunder minefields equals the number of - // missiles, divided by two, rounded up. - if (minefield == null) { - // Nope. Create a new Thunder minefield - minefield = Minefield.createThunderMF - ( mfCoord, playerId, (damage/2 + damage%2) ); - game.addMinefield(minefield); - revealMinefield(minefield); - } else if (minefield.getDamage() < Minefield.MAX_DAMAGE) { - // Yup. Replace the old one. - removeMinefield(minefield); - int newDamage = (damage/2 + damage%2); - newDamage += minefield.getDamage(); - - // Damage from Thunder minefields are capped. - if ( newDamage > Minefield.MAX_DAMAGE ) { - newDamage = Minefield.MAX_DAMAGE; - } - minefield.setDamage(newDamage); - game.addMinefield(minefield); - revealMinefield(minefield); - } - } // End coords-on-board - - } // Handle the next coords - - } - - /** - * Adds a Thunder minefield to the hex. - * @param coords - * @param playerId - * @param damage - */ - private void deliverThunderMinefield( Coords coords, int playerId, - int damage ) { - Minefield minefield = null; - Enumeration minefields = game.getMinefields(coords).elements(); - // Check if there already are Thunder minefields in the hex. - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - if (mf.getType() == Minefield.TYPE_THUNDER) { - minefield = mf; - break; - } - } - - // Create a new Thunder minefield - if (minefield == null) { - minefield = Minefield.createThunderMF(coords, playerId, damage); - // Add to the old one - game.addMinefield(minefield); - revealMinefield(minefield); - } else if (minefield.getDamage() < Minefield.MAX_DAMAGE) { - removeMinefield(minefield); - int oldDamage = minefield.getDamage(); - damage += oldDamage; - damage = (damage > Minefield.MAX_DAMAGE) ? Minefield.MAX_DAMAGE : damage; - minefield.setDamage(damage); - game.addMinefield(minefield); - revealMinefield(minefield); - } - } - - /** - * Adds a Thunder Inferno minefield to the hex. - * @param coords - * @param playerId - * @param damage - */ - private void deliverThunderInfernoMinefield(Coords coords, int playerId, int damage) { - Minefield minefield = null; - Enumeration minefields = game.getMinefields(coords).elements(); - // Check if there already are Thunder minefields in the hex. - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - if (mf.getType() == Minefield.TYPE_THUNDER_INFERNO) { - minefield = mf; - break; - } - } - - // Create a new Thunder Inferno minefield - if (minefield == null) { - minefield = Minefield.createThunderInfernoMF(coords, playerId, damage); - // Add to the old one - game.addMinefield(minefield); - revealMinefield(minefield); - } else if (minefield.getDamage() < Minefield.MAX_DAMAGE) { - removeMinefield(minefield); - int oldDamage = minefield.getDamage(); - damage += oldDamage; - damage = (damage > Minefield.MAX_DAMAGE) ? Minefield.MAX_DAMAGE : damage; - minefield.setDamage(damage); - game.addMinefield(minefield); - revealMinefield(minefield); - } - } - - /** - *Delivers a Arrow IV FASCAM shot to the targetted hex area. - */ - private void deliverFASCAMMinefield( Coords coords, int playerId) { - // Only if this is on the board... - if ( game.getBoard().contains(coords) ) { - Minefield minefield = null; - Enumeration minefields = game.getMinefields(coords).elements(); - // Check if there already are Thunder minefields in the hex. - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - if (mf.getType() == Minefield.TYPE_THUNDER) { - minefield = mf; - break; - } - } - // Did we find a Thunder minefield in the hex? - // N.B. damage of FASCAM minefields is 30 - if (minefield == null) minefield = Minefield.createThunderMF( coords, playerId, 30 ); - removeMinefield(minefield); - minefield.setDamage(30); - game.addMinefield(minefield); - revealMinefield(minefield); - } // End coords-on-board - } - - /** - * Adds a Thunder-Active minefield to the hex. - */ - private void deliverThunderActiveMinefield(Coords coords, int playerId, int damage) { - Minefield minefield = null; - Enumeration minefields = game.getMinefields(coords).elements(); - // Check if there already are Thunder minefields in the hex. - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - if (mf.getType() == Minefield.TYPE_THUNDER_ACTIVE) { - minefield = mf; - break; - } - } - - // Create a new Thunder-Active minefield - if (minefield == null) { - minefield = Minefield.createThunderActiveMF(coords, playerId, damage); - // Add to the old one - game.addMinefield(minefield); - revealMinefield(minefield); - } else if (minefield.getDamage() < Minefield.MAX_DAMAGE) { - removeMinefield(minefield); - int oldDamage = minefield.getDamage(); - damage += oldDamage; - damage = (damage > Minefield.MAX_DAMAGE) ? Minefield.MAX_DAMAGE : damage; - minefield.setDamage(damage); - game.addMinefield(minefield); - revealMinefield(minefield); - } - } - - /** - * Adds a Thunder-Vibrabomb minefield to the hex. - */ - private void deliverThunderVibraMinefield(Coords coords, int playerId, int damage, int sensitivity) { - Minefield minefield = null; - Enumeration minefields = game.getMinefields(coords).elements(); - // Check if there already are Thunder minefields in the hex. - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - if (mf.getType() == Minefield.TYPE_THUNDER_VIBRABOMB) { - minefield = mf; - break; - } - } - - // Create a new Thunder-Vibra minefield - if (minefield == null) { - minefield = Minefield.createThunderVibrabombMF(coords, playerId, damage, sensitivity); - // Add to the old one - game.addVibrabomb(minefield); - revealMinefield(minefield); - } else if (minefield.getDamage() < Minefield.MAX_DAMAGE) { - removeMinefield(minefield); - int oldDamage = minefield.getDamage(); - damage += oldDamage; - damage = (damage > Minefield.MAX_DAMAGE) ? Minefield.MAX_DAMAGE : damage; - minefield.setDamage(damage); - game.addVibrabomb(minefield); - revealMinefield(minefield); - } - } - - /** - * Creates a flare above the target - */ - private void deliverFlare(Coords coords, int rackSize) { - Flare flare = new Flare(coords, Math.max(1, rackSize / 5), 3, 0); - game.addFlare(flare); - } - - private void deliverArtilleryFlare(Coords coords, int radius) { - Flare flare = new Flare(coords, 12, radius, Flare.F_DRIFTING); - game.addFlare(flare); - } - - private void deliverArtillerySmoke(Coords coords) { - if(game.getOptions().booleanOption("maxtech_fire")) { - IHex h = game.getBoard().getHex(coords); - //Unless there is a heavy smoke in the hex already, add one. - if ( h.terrainLevel( Terrains.SMOKE ) < 2 ) { - Report r = new Report(5185, Report.PUBLIC); - r.indent(2); - r.add(coords.getBoardNum()); - addReport(r); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.SMOKE, 2)); - sendChangedHex(coords); - } - } - } - - private void deliverArtilleryInferno(Coords coords, int subjectId) { - IHex h = game.getBoard().getHex(coords); - Report r; - //Unless there is a fire in the hex already, start one. - if ( !h.containsTerrain( Terrains.FIRE ) ) { - r = new Report(3005); - r.subject = subjectId; - r.indent(2); - r.add(coords.getBoardNum()); - addReport(r); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - } - game.getBoard().addInfernoTo( coords, InfernoTracker.INFERNO_IV_ROUND, 1 ); - sendChangedHex(coords); - for(Enumeration impactHexHits = game.getEntities(coords);impactHexHits.hasMoreElements();) { - Entity entity = (Entity)impactHexHits.nextElement(); - entity.infernos.add( InfernoTracker.INFERNO_IV_ROUND, 1 ); - //entity on fire now - r = new Report(3205); - r.indent(2); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(entity.infernos.getTurnsLeftToBurn()); - addReport(r); - } - for(int dir=0;dir<=5;dir++) { - Coords tempcoords=coords.translated(dir); - if(!game.getBoard().contains(tempcoords)) { - continue; - } - if(coords.equals(tempcoords)) { - continue; - } - h = game.getBoard().getHex(tempcoords); - // Unless there is a fire in the hex already, start one. - if ( !h.containsTerrain( Terrains.FIRE ) ) { - r = new Report(3005); - r.subject = subjectId; - r.indent(2); - r.add(tempcoords.getBoardNum()); - addReport(r); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - } - game.getBoard().addInfernoTo( tempcoords, InfernoTracker.INFERNO_IV_ROUND, 1 ); - sendChangedHex(tempcoords); - for (Enumeration splashHexHits = game.getEntities(tempcoords);splashHexHits.hasMoreElements();) { - Entity entity = (Entity)splashHexHits.nextElement(); - entity.infernos.add( InfernoTracker.INFERNO_IV_ROUND, 1 ); - //entity on fire - r = new Report(3205); - r.indent(2); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(entity.infernos.getTurnsLeftToBurn()); - addReport(r); - } - } - } - - /** - * When an entity enters a conventional or Thunder minefield. - */ - private void enterMinefield(Entity entity, Minefield mf, Coords src, Coords dest, boolean resolvePSRNow) { - enterMinefield(entity, mf, src, dest, resolvePSRNow, 0); - } - - /** - * When an entity enters a conventional or Thunder minefield. - * @param entity - * - * @param mf - * @param src - * @param dest - * @param resolvePSRNow - * @param hitMod - */ - private void enterMinefield(Entity entity, Minefield mf, Coords src, Coords dest, boolean resolvePSRNow, int hitMod) { - Report r; - // Bug 954272: Mines shouldn't work underwater - if (!game.getBoard().getHex(mf.getCoords()).containsTerrain(Terrains.WATER) - || game.getBoard().getHex(mf.getCoords()).containsTerrain(Terrains.PAVEMENT) - || game.getBoard().getHex(mf.getCoords()).containsTerrain(Terrains.ICE)) { - switch (mf.getType()) { - case (Minefield.TYPE_CONVENTIONAL) : - case (Minefield.TYPE_THUNDER) : - case (Minefield.TYPE_THUNDER_ACTIVE) : - if (mf.getTrigger() != Minefield.TRIGGER_NONE && - Compute.d6(2) < (mf.getTrigger()+hitMod)) { - return; - } - - r = new Report(2150); - r.subject = entity.getId(); - r.add(entity.getShortName(), true); - r.add(mf.getCoords().getBoardNum(), true); - addReport(r); - HitData hit = entity.rollHitLocation(Minefield.TO_HIT_TABLE, Minefield.TO_HIT_SIDE); - addReport( damageEntity(entity, hit, mf.getDamage())); - addNewLines(); - - if (resolvePSRNow) { - resolvePilotingRolls(entity, true, src, dest); - } - - if (!mf.isOneUse()) { - revealMinefield(mf); - } else { - removeMinefield(mf); - } - break; - - case (Minefield.TYPE_THUNDER_INFERNO) : - if (mf.getTrigger() != Minefield.TRIGGER_NONE && - Compute.d6(2) < (mf.getTrigger()+hitMod)) { - return; - } - entity.infernos.add( InfernoTracker.STANDARD_ROUND, mf.getDamage() ); - //report hitting an inferno mine - r = new Report(2155); - r.subject = entity.getId(); - r.add(entity.getShortName(), true); - r.add(mf.getCoords().getBoardNum(), true); - r.addDesc(entity); - r.add(entity.infernos.getTurnsLeftToBurn()); - addReport(r); - - // start a fire in the targets hex - IHex h = game.getBoard().getHex(dest); - - // Unless there a fire in the hex already, start one. - if ( !h.containsTerrain( Terrains.FIRE ) ) { - r = new Report(3005); - r.subject = entity.getId(); - r.add(dest.getBoardNum(), true); - addReport(r); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - } - game.getBoard().addInfernoTo(dest, InfernoTracker.STANDARD_ROUND, 1); - sendChangedHex(dest); - break; - } - } - } - - /** - * Checks to see if an entity sets off any vibrabombs. - */ - private void checkVibrabombs(Entity entity, Coords coords, boolean displaced) { - checkVibrabombs(entity, coords, displaced, null, null); - } - - private void checkVibrabombs(Entity entity, Coords coords, boolean displaced, Coords lastPos, Coords curPos) { - // Only mechs can set off vibrabombs. - if (!(entity instanceof Mech)) { - return; - } - - int mass = (int) entity.getWeight(); - - Enumeration e = game.getVibrabombs().elements(); - - while (e.hasMoreElements()) { - Minefield mf = (Minefield) e.nextElement(); - - // Bug 954272: Mines shouldn't work underwater, and BMRr says Vibrabombs are mines - if (game.getBoard().getHex(mf.getCoords()).containsTerrain(Terrains.WATER) - && !game.getBoard().getHex(mf.getCoords()).containsTerrain(Terrains.PAVEMENT) - && !game.getBoard().getHex(mf.getCoords()).containsTerrain(Terrains.ICE)) { - continue; - } - - // Mech weighing 10 tons or less can't set off the bomb - if (mass <= mf.getSetting() - 10) { - continue; - } - - int effectiveDistance = (mass - mf.getSetting()) / 10; - int actualDistance = coords.distance(mf.getCoords()); - - if (actualDistance <= effectiveDistance) { - Report r = new Report(2156); - r.subject = entity.getId(); - r.add(entity.getShortName(), true); - r.add(mf.getCoords().getBoardNum(), true); - addReport(r); - explodeVibrabomb(mf); - } - - // Hack; when moving, the Mech isn't in the hex during - // the movement. - if (!displaced && actualDistance == 0) { - //report getting hit by vibrabomb - Report r = new Report(2160); - r.subject = entity.getId(); - r.add(entity.getShortName(), true); - addReport(r); - HitData hit = entity.rollHitLocation(Minefield.TO_HIT_TABLE, Minefield.TO_HIT_SIDE); - addReport( damageEntity(entity, hit, mf.getDamage())); - addNewLines(); - resolvePilotingRolls(entity, true, lastPos, curPos); - // we need to apply Damage now, in case the entity lost a leg, - // otherwise it won't get a leg missing mod if it hasn't yet - // moved and lost a leg, see bug 1071434 for an example - entity.applyDamage(); - } - } - } - /** - * Remove all minefields in the specified coords from the game - * @param coords The Coords from which to remove minefields - */ - private void removeMinefieldsFrom(Coords coords) { - Vector v = game.getMinefields(coords); - while (v.elements().hasMoreElements()) { - Minefield mf = (Minefield)v.elements().nextElement(); - removeMinefield(mf); - } - - } - - /** - * Removes the minefield from the game. - * @param mf The Minefield to remove - */ - private void removeMinefield(Minefield mf) { - if (game.containsVibrabomb(mf)) { - game.removeVibrabomb(mf); - } - game.removeMinefield(mf); - - Enumeration players = game.getPlayers(); - while (players.hasMoreElements()) { - Player player = (Player) players.nextElement(); - removeMinefield(player, mf); - } - } - - /** - * Removes the minfield from a player. - * @param player The Player who's minefield should be removed - * @param mf The Minefield to be removed - */ - private void removeMinefield(Player player, Minefield mf) { - if (player.containsMinefield(mf)) { - player.removeMinefield(mf); - send(player.getId(), new Packet(Packet.COMMAND_REMOVE_MINEFIELD, mf)); - } - } - - /** - * Reveals a minefield for all players. - * @param mf The Minefield to be revealed - */ - private void revealMinefield(Minefield mf) { - Enumeration players = game.getPlayers(); - while (players.hasMoreElements()) { - Player player = (Player) players.nextElement(); - revealMinefield(player, mf); - } - } - - /** - * Reveals a minefield for a player. - * @param player The Player who's minefiled should be revealed - * @param mf The Minefield to be revealed - */ - private void revealMinefield(Player player, Minefield mf) { - if (!player.containsMinefield(mf)) { - player.addMinefield(mf); - send(player.getId(), new Packet(Packet.COMMAND_REVEAL_MINEFIELD, mf)); - } - } - - /** - * Explodes a vibrabomb. - * @param mf The Minefield to explode - */ - private void explodeVibrabomb(Minefield mf) { - Enumeration targets = game.getEntities(mf.getCoords()); - Report r; - - while (targets.hasMoreElements()) { - Entity entity = (Entity) targets.nextElement(); - - // check for the "no_premove_vibra" option - // If it's set, and the target has not yet moved, - // it doesn't get damaged. - if (!entity.isDone() && game.getOptions().booleanOption("no_premove_vibra")) { - r = new Report(2157); - r.subject = entity.getId(); - r.add(entity.getShortName(), true); - addReport(r); - continue; - } - //report hitting vibrabomb - r = new Report(2160); - r.subject = entity.getId(); - r.add(entity.getShortName(), true); - addReport(r); - - if (mf.getType() == Minefield.TYPE_VIBRABOMB) { - // normal vibrabombs do all damage in one pack - HitData hit = entity.rollHitLocation(Minefield.TO_HIT_TABLE, Minefield.TO_HIT_SIDE); - addReport( damageEntity(entity, hit, mf.getDamage())); - addNewLines(); - } else if (mf.getType() == Minefield.TYPE_THUNDER_VIBRABOMB) { - int damage = mf.getDamage(); - HitData hit = entity.rollHitLocation(Minefield.TO_HIT_TABLE, Minefield.TO_HIT_SIDE); - addReport( damageEntity(entity, hit, damage)); - } - - resolvePilotingRolls(entity, true, entity.getPosition(), entity.getPosition()); - // we need to apply Damage now, in case the entity lost a leg, - // otherwise it won't get a leg missing mod if it hasn't yet - // moved and lost a leg, see bug 1071434 for an example - game.resetPSRs(entity); - entity.applyDamage(); - addNewLines(); - entityUpdate(entity.getId()); - } - - if (!mf.isOneUse()) { - revealMinefield(mf); - } else { - removeMinefield(mf); - } - } - - /** - * drowns any units swarming the entity - * @param entity The Entity that is being swarmed - * @param pos The Coords the entity is at - */ - private void drownSwarmer(Entity entity, Coords pos) { - // Any swarming infantry will be destroyed. - final int swarmerId = entity.getSwarmAttackerId(); - if ( Entity.NONE != swarmerId ) { - final Entity swarmer = game.getEntity( swarmerId ); - // Only *platoons* drown while swarming. - if (!(swarmer instanceof BattleArmor)) { - swarmer.setSwarmTargetId( Entity.NONE ); - entity.setSwarmAttackerId( Entity.NONE ); - swarmer.setPosition( pos ); - Report r = new Report(2165); - r.subject = entity.getId(); - r.indent(); - r.add(entity.getShortName(), true); - addReport(r); - addReport( destroyEntity(swarmer, "a watery grave", false)); - entityUpdate( swarmerId ); - } - } - } - - /** - * Checks to see if we may have just washed off infernos. Call after - * a step which may have done this. - * - * @param entity The Entity that is being checked - * @param coords The Coords the entity is at - */ - void checkForWashedInfernos(Entity entity, Coords coords) { - IHex hex = game.getBoard().getHex(coords); - int waterLevel = hex.terrainLevel(Terrains.WATER); - // Mech on fire with infernos can wash them off. - if (!(entity instanceof Mech) || !entity.infernos.isStillBurning()) { - return; - } - // Check if entering depth 2 water or prone in depth 1. - if (waterLevel > 0 && entity.absHeight() < 0) { - washInferno(entity, coords); - } - } - - /** - * Washes off an inferno from a mech and adds it to the (water) hex. - * - * @param entity The Entity that is taking a bath - * @param coords The Coords the entity is at - */ - void washInferno(Entity entity, Coords coords) { - game.getBoard().addInfernoTo( coords, InfernoTracker.STANDARD_ROUND, 1 ); - entity.infernos.clear(); - - // Start a fire in the hex? - IHex hex = game.getBoard().getHex(coords); - Report r = new Report(2170); - r.subject = entity.getId(); - r.addDesc(entity); - if ( hex.containsTerrain(Terrains.FIRE) ) { - } else { - r.messageId = 2175; - hex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - } - addReport(r); - sendChangedHex(coords); - } - - /** - * Add heat from the movement phase - */ - public void addMovementHeat() { - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - Entity entity = (Entity)i.nextElement(); - // build up heat from movement - if (entity.moved == IEntityMovementType.MOVE_NONE) { - entity.heatBuildup += entity.getStandingHeat(); - } else if (entity.moved == IEntityMovementType.MOVE_WALK - || entity.moved == IEntityMovementType.MOVE_VTOL_WALK) { - entity.heatBuildup += entity.getWalkHeat(); - } else if (entity.moved == IEntityMovementType.MOVE_RUN - || entity.moved == IEntityMovementType.MOVE_VTOL_RUN - || entity.moved == IEntityMovementType.MOVE_SKID) { - entity.heatBuildup += entity.getRunHeat(); - } else if (entity.moved == IEntityMovementType.MOVE_JUMP) { - entity.heatBuildup += entity.getJumpHeat(entity.delta_distance); - } - } - } - - /** - * Set the locationsexposure of an entity - * - * @param entity The Entity who's exposure is being set - * @param hex The IHex the entity is in - * @param isJump a boolean value wether the entity is jumping - * @param elevation the elevation the entity should be at. - */ - - public void doSetLocationsExposure(Entity entity, IHex hex, boolean isJump, int elevation) { - if ( hex.terrainLevel(Terrains.WATER) > 0 - && !isJump - && elevation < 0) { - if (entity instanceof Mech - && !entity.isProne() - && hex.terrainLevel(Terrains.WATER) == 1) { - for (int loop = 0; loop < entity.locations(); loop++) { - if (game.getOptions().booleanOption("vacuum")) - entity.setLocationStatus(loop, ILocationExposureStatus.VACUUM); - else entity.setLocationStatus(loop, ILocationExposureStatus.NORMAL); - } - entity.setLocationStatus(Mech.LOC_RLEG, ILocationExposureStatus.WET); - entity.setLocationStatus(Mech.LOC_LLEG, ILocationExposureStatus.WET); - addReport( - breachCheck(entity, Mech.LOC_RLEG, hex)); - addReport( - breachCheck(entity, Mech.LOC_LLEG, hex)); - if (entity instanceof QuadMech) { - entity.setLocationStatus(Mech.LOC_RARM, ILocationExposureStatus.WET); - entity.setLocationStatus(Mech.LOC_LARM, ILocationExposureStatus.WET); - addReport( - breachCheck(entity, Mech.LOC_RARM, hex)); - addReport( - breachCheck(entity, Mech.LOC_LARM, hex)); - } - } else { - for (int loop = 0; loop < entity.locations(); loop++) { - entity.setLocationStatus(loop, ILocationExposureStatus.WET); - addReport( breachCheck(entity, loop, hex)); - } - } - } else { - for (int loop = 0; loop < entity.locations(); loop++) { - if (game.getOptions().booleanOption("vacuum")) - entity.setLocationStatus(loop, ILocationExposureStatus.VACUUM); - else entity.setLocationStatus(loop, ILocationExposureStatus.NORMAL); - } - } - - } - - /** - * Do a piloting skill check while standing still (during the - * movement phase). - * - * @param entity The Entity that should make the PSR - * @param roll The PilotingRollData to be used for this PSR. - * - *@param Returns true if check succeeds, false otherwise. - * - */ - private boolean doSkillCheckInPlace(Entity entity, PilotingRollData roll) { - if (roll.getValue() == TargetRoll.AUTOMATIC_SUCCESS) { - return true; - } - - // non-mechs should never get here - if (! (entity instanceof Mech) || entity.isProne()) { - return true; - } - - // okay, print the info - Report r = new Report(2180); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(roll.getLastPlainDesc(), true); - addReport(r); - - // roll - final int diceRoll = Compute.d6(2); - r = new Report(2185); - r.subject = entity.getId(); - r.add(roll.getValueAsString()); - r.add(roll.getDesc()); - r.add(diceRoll); - boolean suc; - if (diceRoll < roll.getValue()) { - r.choose(false); - addReport(r); - doEntityFall(entity, roll); - suc = false; - } else { - r.choose(true); - addReport(r); - suc = true; - } - - return suc; - } - - /** - * Do a Piloting Skill check to dislogde swarming infantry. - * - * @param entity The Entity that is doing the dislodging. - * @param roll The PilotingRollData for this PSR. - * @param curPos The Coords the entity is at. - * @return true if the dislodging is successful. - */ - private boolean doDislodgeSwarmerSkillCheck - (Entity entity, PilotingRollData roll, Coords curPos) - { - // okay, print the info - Report r = new Report(2180); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(roll.getLastPlainDesc(), true); - addReport(r); - - // roll - final int diceRoll = Compute.d6(2); - r = new Report(2190); - r.subject = entity.getId(); - r.add(roll.getValueAsString()); - r.add(roll.getDesc()); - r.add(diceRoll); - if (diceRoll < roll.getValue()) { - r.choose(false); - addReport(r); - return false; - } else { - // Dislodged swarmers don't get turns. - int swarmerId = entity.getSwarmAttackerId(); - final Entity swarmer = game.getEntity( swarmerId ); - game.removeTurnFor( swarmer ); - send( createTurnVectorPacket() ); - - // Update the report and cause a fall. - r.choose(true); - addReport(r); - entity.setPosition( curPos ); - doEntityFallsInto(entity, curPos, curPos, roll, false); - return true; - } - } - - /** - * Do a piloting skill check while moving. - * - * @param entity - the Entity that must roll. - * @param src - the Coords the entity is moving from. - * @param dest - the Coords the entity is moving to. - * This value can be the same as src for in-place checks. - * @param reason - the PilotingRollData that is causing - * this check. - * @param isFallRoll - a boolean flag that indicates that - * failure will result in a fall or not. Falls will be processed. - * @return true if the pilot passes the skill check. - */ - private boolean doSkillCheckWhileMoving( Entity entity, - Coords src, - Coords dest, - PilotingRollData roll, - boolean isFallRoll ) { - boolean result = true; - boolean fallsInPlace; - - // Start the info for this roll. - Report r = new Report(1210); - r.subject = entity.getId(); - r.addDesc(entity); - - // Will the entity fall in the source or destination hex? - if ( src.equals(dest) ) { - fallsInPlace = true; - r.messageId = 2195; - r.add(src.getBoardNum(), true); - } else { - fallsInPlace = false; - r.messageId = 2200; - r.add(src.getBoardNum(), true); - r.add(dest.getBoardNum(), true); - } - - // Finish the info. - r.add(roll.getLastPlainDesc(), true); - addReport(r); - - // roll - final int diceRoll = Compute.d6(2); - r = new Report(2185); - r.subject = entity.getId(); - r.add(roll.getValueAsString()); - r.add(roll.getDesc()); - r.add(diceRoll); - if (diceRoll < roll.getValue()) { - // Does failing the PSR result in a fall. - if ( isFallRoll ) { - r.choose(false); - addReport(r); - doEntityFallsInto( entity, - (fallsInPlace ? dest : src), - (fallsInPlace ? src : dest), - roll ); - } else { - r.messageId = 2190; - r.choose(false); - addReport(r); - entity.setPosition( fallsInPlace ? src : dest ); - } - result = false; - } else { - r.choose(true); - addReport(r); - } - return result; - } - - - /** - * The entity falls into the hex specified. Check for any conflicts and - * resolve them. Deal damage to faller. - * - * @param entity The Entity that is falling. - * @param src The Coords of the source hex. - * @param dest The Coords of the destination hex. - * @param roll The PilotingRollData to be used for PSRs induced - * by the falling. - */ - private void doEntityFallsInto(Entity entity, Coords src, Coords dest, PilotingRollData roll) { - doEntityFallsInto(entity, src, dest, roll, true); - } - - /** - * The entity falls into the hex specified. Check for any conflicts and - * resolve them. Deal damage to faller. - * - * @param entity The Entity that is falling. - * @param src The Coords of the source hex. - * @param dest The Coords of the destination hex. - * @param roll The PilotingRollData to be used for PSRs induced - * by the falling. - * @param causeAffa The boolean value wether this fall should - * be able to cause an accidental fall from above - */ - private void doEntityFallsInto(Entity entity, Coords src, Coords dest, PilotingRollData roll, boolean causeAffa) { - final IHex srcHex = game.getBoard().getHex(src); - final IHex destHex = game.getBoard().getHex(dest); - final int srcHeightAboveFloor = entity.getElevation() + srcHex.depth(); - final int fallElevation = Math.max(0, srcHex.floor() + srcHeightAboveFloor - destHex.floor()); - int direction = src.direction(dest); - Report r; - // check entity in target hex - Entity affaTarget = game.getAffaTarget(dest, entity); - // falling mech falls - r = new Report(2205); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(fallElevation); - r.add(dest.getBoardNum(), true); - addReport(r); - - // if hex was empty, deal damage and we're done - if (affaTarget == null) { - doEntityFall(entity, dest, fallElevation, roll); - return; - } - - // hmmm... somebody there... problems. - if (fallElevation >= 2 && causeAffa && affaTarget != null) { - // accidental fall from above: havoc! - r = new Report(2210); - r.subject = entity.getId(); - r.addDesc(affaTarget); - addReport(r); - - // determine to-hit number - ToHitData toHit = new ToHitData(7, "base"); - if (affaTarget instanceof Tank ) { - toHit = new ToHitData(TargetRoll.AUTOMATIC_FAIL, "Target is a Tank"); - } else { - toHit.append(Compute.getTargetMovementModifier(game, affaTarget.getId())); - toHit.append(Compute.getTargetTerrainModifier(game, affaTarget)); - } - - if (toHit.getValue() != TargetRoll.AUTOMATIC_FAIL) { - // collision roll - final int diceRoll = Compute.d6(2); - r = new Report(2215); - r.subject = entity.getId(); - r.add(toHit.getValue()); - r.add(diceRoll); - if (diceRoll >= toHit.getValue()) { - r.choose(true); - addReport(r); - // deal damage to target - int damage = Compute.getAffaDamageFor(entity); - r = new Report(2220); - r.subject = affaTarget.getId(); - r.addDesc(affaTarget); - r.add(damage); - addReport(r); - while (damage > 0) { - int cluster = Math.min(5, damage); - HitData hit = affaTarget.rollHitLocation(ToHitData.HIT_PUNCH, ToHitData.SIDE_FRONT); - addReport( - damageEntity(affaTarget, hit, cluster)); - damage -= cluster; - } - addNewLines(); - - // attacker falls as normal, on his back - // only given a modifier, so flesh out into a full piloting roll - PilotingRollData pilotRoll = entity.getBasePilotingRoll(); - pilotRoll.append(roll); - entity.addPilotingModifierForTerrain(pilotRoll, dest); - doEntityFall(entity, dest, fallElevation, 3, pilotRoll); - doEntityDisplacementMinefieldCheck(entity, src, dest); - - // defender pushed away, or destroyed, if there is a stacking violation - Entity violation = Compute.stackingViolation(game, entity.getId(), dest); - if (violation != null) { - Coords targetDest = Compute.getValidDisplacement(game, violation.getId(), dest, direction); - if (targetDest != null) { - doEntityDisplacement(affaTarget, dest, targetDest, new PilotingRollData(violation.getId(), 2, "fallen on")); - // Update the violating entity's postion on the client. - entityUpdate( affaTarget.getId() ); - } else { - // ack! automatic death! Tanks - // suffer an ammo/power plant hit. - // TODO : a Mech suffers a Head Blown Off crit. - addReport( - destroyEntity(affaTarget, "impossible displacement", (violation instanceof Mech), (violation instanceof Mech))); - } - } - return; - } else { - r.choose(false); - addReport(r); - } - } else { - //automatic miss - r = new Report(2225); - r.add(toHit.getDesc()); - addReport(r); - } - // ok, we missed, let's fall into a valid other hex and not cause an AFFA while doing so - Coords targetDest = Compute.getValidDisplacement(game, entity.getId(), dest, direction); - if (targetDest != null) { - doEntityFallsInto(entity, src, targetDest, new PilotingRollData(entity.getId(), PilotingRollData.IMPOSSIBLE, "pushed off a cliff"), false); - // Update the entity's postion on the client. - entityUpdate( entity.getId() ); - } else { - // ack! automatic death! Tanks - // suffer an ammo/power plant hit. - // TODO : a Mech suffers a Head Blown Off crit. - addReport( destroyEntity(entity, "impossible displacement", (entity instanceof Mech), (entity instanceof Mech))); - } - } else { - // damage as normal - doEntityFall(entity, dest, fallElevation, roll); - Entity violation = Compute.stackingViolation(game, entity.getId(), dest); - if(violation != null) { - // target gets displaced, because of low elevation - Coords targetDest = Compute.getValidDisplacement(game, entity.getId(), dest, direction); - doEntityDisplacement(violation, dest, targetDest, new PilotingRollData(violation.getId(), 0, "domino effect")); - // Update the violating entity's postion on the client. - entityUpdate( violation.getId() ); - } - } - } - - /** - * Displace a unit in the direction specified. The unit moves in that - * direction, and the piloting skill roll is used to determine if it - * falls. The roll may be unnecessary as certain situations indicate an - * automatic fall. Rolls are added to the piloting roll list. - */ - private void doEntityDisplacement(Entity entity, Coords src, Coords dest, - PilotingRollData roll) { - Report r; - if (!game.getBoard().contains(dest)) { - // set position anyway, for pushes moving through and stuff like - // that - entity.setPosition(dest); - if (!entity.isDoomed()) { - game.removeEntity(entity.getId(), - IEntityRemovalConditions.REMOVE_PUSHED); - send(createRemoveEntityPacket(entity.getId(), - IEntityRemovalConditions.REMOVE_PUSHED)); - //entity forced from the field - r = new Report(2230); - r.addDesc(entity); - addReport(r); - // TODO: remove passengers and swarmers. - } - return; - } - final IHex srcHex = game.getBoard().getHex(src); - final IHex destHex = game.getBoard().getHex(dest); - final int direction = src.direction(dest); - - // Handle null hexes. - if ( srcHex == null || destHex == null ) { - System.err.println( "Can not displace " + entity.getShortName() + - " from " + src + - " to " + dest + "." ); - return; - } - int fallElevation = entity.elevationOccupied(srcHex) - entity.elevationOccupied(destHex); - if (fallElevation > 1) { - if(roll == null) - roll = entity.getBasePilotingRoll(); - doEntityFallsInto(entity, src, dest, roll); - return; - } else { - //move the entity into the new location gently - entity.setPosition(dest); - entity.setElevation(entity.elevationOccupied(destHex) - destHex.surface()); - Entity violation = Compute.stackingViolation(game, entity.getId(), dest); - if (violation == null) { - // move and roll normally - r = new Report(2235); - r.indent(); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(dest.getBoardNum(), true); - addReport(r); - } else { - // domino effect: move & displace target - r = new Report(2240); - r.indent(); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(dest.getBoardNum(), true); - r.addDesc(violation); - addReport(r); - } - // trigger any special things for moving to the new hex - doEntityDisplacementMinefieldCheck(entity, src, dest); - doSetLocationsExposure(entity, destHex, false, entity.getElevation()); - if (roll != null) { - game.addPSR(roll); - } - // Update the entity's postion on the client. - entityUpdate( entity.getId() ); - - if(violation != null) { - doEntityDisplacement(violation, dest, dest.translated(direction), new PilotingRollData(violation.getId(), 0, "domino effect")); - // Update the violating entity's postion on the client, - // if it didn't get displaced off the board. - if ( !game.isOutOfGame(violation) ) { - entityUpdate( violation.getId() ); - } - } - } - } - - private void doEntityDisplacementMinefieldCheck(Entity entity, Coords src, Coords dest) { - if (game.containsMinefield(dest)) { - Enumeration minefields = game.getMinefields(dest).elements(); - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - enterMinefield(entity, mf, src, dest, false); - } - } - checkVibrabombs(entity, dest, true); - } - - /** - * Receive a deployment packet. If valid, execute it and end the current - * turn. - */ - private void receiveDeployment(Packet packet, int connId) { - Entity entity = game.getEntity(packet.getIntValue(0)); - Coords coords = (Coords)packet.getObject(1); - int nFacing = packet.getIntValue(2); - - // Handle units that deploy loaded with other units. - int loadedCount = packet.getIntValue(3); - Vector loadVector = new Vector(); - for ( int i = 0; i < loadedCount; i++ ){ - int loadedId = packet.getIntValue( 5 + i ); - loadVector.addElement(game.getEntity( loadedId )); - } - - // is this the right phase? - if (game.getPhase() != IGame.PHASE_DEPLOYMENT) { - System.err.println("error: server got deployment packet in wrong phase"); - return; - } - - // can this player/entity act right now? - final boolean assaultDrop = packet.getBooleanValue(4); - if ( !game.getTurn().isValid(connId, entity, game) - || !(game.getBoard().isLegalDeployment(coords, entity.getOwner()) - ||(assaultDrop && game.getOptions().booleanOption("assault_drop") && entity.canAssaultDrop()))) { - System.err.println("error: server got invalid deployment packet"); - return; - } - - // looks like mostly everything's okay - processDeployment(entity, coords, nFacing, loadVector, assaultDrop); - - // Update visibility indications if using double blind. - if (doBlind()) { - updateVisibilityIndicator(); - } - - endCurrentTurn(entity); - } - - /** - * Process a deployment packet by... deploying the entity! We load any - * other specified entities inside of it too. Also, check that the - * deployment is valid. - */ - private void processDeployment(Entity entity, Coords coords, int nFacing, Vector loadVector, boolean assaultDrop) { - for (Enumeration i = loadVector.elements(); i.hasMoreElements();) { - Entity loaded = (Entity)i.nextElement(); - if ( loaded == null || loaded.getPosition() != null || - loaded.getTransportId() != Entity.NONE ) { - // Something is fishy in Denmark. - System.err.println("error: " + entity + " can not load entity #" + loaded ); - break; - } - else { - // Have the deployed unit load the indicated unit. - this.loadUnit( entity, loaded ); - } - } - - entity.setPosition(coords); - entity.setFacing(nFacing); - entity.setSecondaryFacing(nFacing); - IHex hex = game.getBoard().getHex(coords); - if(assaultDrop) { - entity.setElevation(hex.ceiling() - hex.surface() + 100); //falling from the sky! - entity.setAssaultDropInProgress(true); - } else if (entity instanceof VTOL) { - // We should let players pick, but this simplifies a lot. - // Only do it for VTOLs, though; assume everything else is on the ground. - entity.setElevation(hex.ceiling()-hex.surface()+1); - while ((Compute.stackingViolation(game, entity, coords, null) != null) && (entity.getElevation() <= 50)) { - entity.setElevation(entity.getElevation() + 1); - } - if (entity.getElevation() > 50) { - throw new IllegalStateException("Entity #" + entity.getId() + " appears to be in an infinite loop trying to get a legal elevation."); - } - } else if (entity.getMovementMode() == IEntityMovementMode.SUBMARINE) { - // TODO: Submarines should have a selectable height. - // For now, pretend they're regular naval. - entity.setElevation(0); - } else if ((entity.getMovementMode() == IEntityMovementMode.HOVER) - || (entity.getMovementMode() == IEntityMovementMode.NAVAL) - || (entity.getMovementMode() == IEntityMovementMode.HYDROFOIL)) { - // For now, assume they're on the surface. - // entity elevation is relative to hex surface - entity.setElevation(0); - } else if (hex.containsTerrain(Terrains.ICE) - || hex.containsTerrain(Terrains.BRIDGE)) { - entity.setElevation(0); - } else { - // For anything else, assume they're on the floor. - // entity elevation is relative to hex surface - entity.setElevation(hex.floor()-hex.surface()); - } - entity.setDone(true); - entity.setDeployed(true); - entityUpdate(entity.getId()); - } - - private void receiveArtyAutoHitHexes(Packet packet, int connId) { - Vector artyAutoHitHexes = (Vector) packet.getObject(0); - - Integer playerId = (Integer)artyAutoHitHexes.firstElement(); - artyAutoHitHexes.removeElementAt(0); - - // is this the right phase? - if (game.getPhase() != IGame.PHASE_SET_ARTYAUTOHITHEXES) { - System.err.println("error: server got set artyautohithexespacket in wrong phase"); - return; - } - game.getPlayer(playerId.intValue()).setArtyAutoHitHexes(artyAutoHitHexes); - endCurrentTurn(null); - } - - private void receiveDeployMinefields(Packet packet, int connId) { - Vector minefields = (Vector) packet.getObject(0); - - // is this the right phase? - if (game.getPhase() != IGame.PHASE_DEPLOY_MINEFIELDS) { - System.err.println("error: server got deploy minefields packet in wrong phase"); - return; - } - - // looks like mostly everything's okay - processDeployMinefields(minefields); - endCurrentTurn(null); - } - - private void processDeployMinefields(Vector minefields) { - int playerId = Player.PLAYER_NONE; - for (int i = 0; i < minefields.size(); i++) { - Minefield mf = (Minefield) minefields.elementAt(i); - playerId = mf.getPlayerId(); - - game.addMinefield(mf); - if (mf.getType() == Minefield.TYPE_VIBRABOMB) { - game.addVibrabomb(mf); - } - } - - Player player = game.getPlayer( playerId ); - if ( null != player ) { - int teamId = player.getTeam(); - - if (teamId != Player.TEAM_NONE) { - Enumeration teams = game.getTeams(); - while (teams.hasMoreElements()) { - Team team = (Team) teams.nextElement(); - if (team.getId() == teamId) { - Enumeration players = team.getPlayers(); - while (players.hasMoreElements()) { - Player teamPlayer = (Player) players.nextElement(); - if (teamPlayer.getId() != player.getId()) { - send(teamPlayer.getId(), new Packet(Packet.COMMAND_DEPLOY_MINEFIELDS, minefields)); - } - teamPlayer.addMinefields(minefields); - } - break; - } - } - } else { - player.addMinefields(minefields); - } - } - } - /** - * Gets a bunch of entity attacks from the packet. If valid, processess - * them and ends the current turn. - */ - private void receiveAttack(Packet packet, int connId) { - Entity entity = game.getEntity(packet.getIntValue(0)); - Vector vector = (Vector)packet.getObject(1); - - // is this the right phase? - if (game.getPhase() != IGame.PHASE_FIRING - && game.getPhase() != IGame.PHASE_PHYSICAL - && game.getPhase() != IGame.PHASE_TARGETING - && game.getPhase() != IGame.PHASE_OFFBOARD) { - System.err.println("error: server got attack packet in wrong phase"); - return; - } - - // can this player/entity act right now? - if (!game.getTurn().isValid(connId, entity, game)) { - System.err.println("error: server got invalid attack packet"); - return; - } - - // looks like mostly everything's okay - processAttack(entity, vector); - - // Update visibility indications if using double blind. - if (doBlind()) { - updateVisibilityIndicator(); - } - - endCurrentTurn(entity); - } - - /** - * Process a batch of entity attack (or twist) actions by adding them to - * the proper list to be processed later. - */ - private void processAttack(Entity entity, Vector vector) { - - // Not **all** actions take up the entity's turn. - boolean setDone = - !(game.getTurn() instanceof GameTurn.TriggerAPPodTurn); - for (Enumeration i = vector.elements(); i.hasMoreElements();) { - EntityAction ea = (EntityAction)i.nextElement(); - - // is this the right entity? - if (ea.getEntityId() != entity.getId()) { - System.err.println("error: attack packet has wrong attacker"); - continue; - } - - // Anti-mech and pointblank attacks from - // hiding may allow the target to respond. - if ( ea instanceof WeaponAttackAction ) { - final WeaponAttackAction waa = (WeaponAttackAction) ea; - final String weaponName = entity.getEquipment - ( waa.getWeaponId() ).getType().getInternalName(); - - if ( Infantry.SWARM_MEK.equals(weaponName) || - Infantry.LEG_ATTACK.equals(weaponName) ) { - - // Does the target have any AP Pods available? - final Entity target = game.getEntity( waa.getTargetId() ); - Enumeration misc = target.getMisc(); - while ( misc.hasMoreElements() ) { - final Mounted equip = (Mounted) misc.nextElement(); - if ( equip.getType().hasFlag(MiscType.F_AP_POD) && - equip.canFire()) { - - // Yup. Insert a game turn to handle AP pods. - // ASSUMPTION : AP pod declarations come - // immediately after the attack declaration. - game.insertNextTurn( new GameTurn.TriggerAPPodTurn - ( target.getOwnerId(), target.getId() ) ); - send(createTurnVectorPacket()); - - // We can stop looking. - break; - - } // end found-available-ap-pod - - } // Check the next piece of equipment on the target. - - } // End check-for-available-ap-pod - } - - // The equipment type of a club needs to be restored. - if (ea instanceof ClubAttackAction) { - ClubAttackAction caa = (ClubAttackAction) ea; - Mounted club = caa.getClub(); - club.restore(); - } - - if (ea instanceof PushAttackAction) { - // push attacks go the end of the displacement attacks - PushAttackAction paa = (PushAttackAction)ea; - entity.setDisplacementAttack(paa); - game.addCharge(paa); - } else if (ea instanceof DodgeAction) { - entity.dodging = true; - } else if (ea instanceof SpotAction) { - entity.setSpotting(true); - } else { - // add to the normal attack list. - game.addAction(ea); - } - - // Mark any AP Pod as used in this turn. - if ( ea instanceof TriggerAPPodAction ) { - TriggerAPPodAction tapa = (TriggerAPPodAction) ea; - Mounted pod = entity.getEquipment( tapa.getPodId() ); - pod.setUsedThisRound( true ); - } - } - - // Unless otherwise stated, - // this entity is done for the round. - if ( setDone ) { - entity.setDone(true); - } - entityUpdate(entity.getId()); - - // update all players on the attacks. Don't worry about pushes being a - // "charge" attack. It doesn't matter to the client. - send(createAttackPacket(vector, 0)); - } - - /** - * Auto-target active AMS systems - */ - private void assignAMS() { - - // sort all missile-based attacks by the target - Hashtable htAttacks = new Hashtable(); - for (Enumeration i = game.getActions(); i.hasMoreElements(); ) { - Object o = i.nextElement(); - if (o instanceof WeaponAttackAction) { - WeaponAttackAction waa = (WeaponAttackAction)o; - Mounted weapon = game.getEntity(waa.getEntityId()).getEquipment(waa.getWeaponId()); - - // Only entities can have AMS. - if ( Targetable.TYPE_ENTITY != waa.getTargetType() ) { - continue; - } - - // Can only use AMS versus missles. - if (((WeaponType)weapon.getType()).getDamage() == WeaponType.DAMAGE_MISSILE) { - Entity target = game.getEntity(waa.getTargetId()); - Vector v = (Vector)htAttacks.get(target); - if (v == null) { - v = new Vector(); - htAttacks.put(target, v); - } - v.addElement(waa); - } - } - } - - // let each target assign its AMS - for (Enumeration i = htAttacks.keys(); i.hasMoreElements(); ) { - Entity e = (Entity)i.nextElement(); - Vector vAttacks = (Vector)htAttacks.get(e); - e.assignAMS(vAttacks); - } - } - - /** - * Called during the weapons fire phase. Resolves anything other than - * weapons fire that happens. Torso twists, for example. - */ - private void resolveAllButWeaponAttacks() { - if (game.getPhase()==IGame.PHASE_FIRING) { - //Phase report header - addReport(new Report(3000, Report.PUBLIC)); - Report r; - for (Enumeration e = game.getLayMinefieldActions(); e.hasMoreElements();) { - LayMinefieldAction lma = (LayMinefieldAction)e.nextElement(); - Entity ent = game.getEntity(lma.getEntityId()); - Mounted mine = ent.getEquipment(lma.getMineId()); - if (!mine.isMissing()) { - switch (mine.getMineType()) { - case 0: - deliverThunderMinefield(ent.getPosition(), ent.getOwnerId(), 10); - mine.setMissing(true); - r = new Report(3500); - r.subject = ent.getId(); - r.addDesc(ent); - r.add(ent.getPosition().getBoardNum()); - addReport(r); - break; - case 1: - deliverThunderVibraMinefield(ent.getPosition(), ent.getOwnerId(), 10, mine.getVibraSetting()); - mine.setMissing(true); - r = new Report(3505); - r.subject = ent.getId(); - r.addDesc(ent); - r.add(ent.getPosition().getBoardNum()); - addReport(r); - break; - //TODO: command-detonated mines - // case 2: - } - } - } - game.resetLayMinefieldActions(); - } - - Vector clearAttempts = new Vector(); - Vector triggerPodActions = new Vector(); - // loop thru actions and handle everything we expect except attacks - for (Enumeration i = game.getActions(); i.hasMoreElements();) { - EntityAction ea = (EntityAction)i.nextElement(); - Entity entity = game.getEntity(ea.getEntityId()); - if (ea instanceof TorsoTwistAction) { - TorsoTwistAction tta = (TorsoTwistAction)ea; - if ( entity.canChangeSecondaryFacing() ) { - entity.setSecondaryFacing(tta.getFacing()); - } - } - else if (ea instanceof FlipArmsAction) { - FlipArmsAction faa = (FlipArmsAction)ea; - entity.setArmsFlipped(faa.getIsFlipped()); - } - else if (ea instanceof FindClubAction) { - resolveFindClub(entity); - } - else if (ea instanceof UnjamAction) { - resolveUnjam(entity); - } - else if (ea instanceof ClearMinefieldAction) { - clearAttempts.addElement(entity); - } - else if (ea instanceof TriggerAPPodAction) { - TriggerAPPodAction tapa = (TriggerAPPodAction) ea; - - // Don't trigger the same pod twice. - if ( !triggerPodActions.contains( tapa ) ) { - triggerAPPod(entity, tapa.getPodId()); - triggerPodActions.addElement( tapa ); - } else { - System.err.print( "AP Pod #" ); - System.err.print( tapa.getPodId() ); - System.err.print( " on " ); - System.err.print( entity.getDisplayName() ); - System.err.println(" was already triggered this round!!"); - } - } - else if (ea instanceof SearchlightAttackAction) { - SearchlightAttackAction saa = (SearchlightAttackAction)ea; - addReport( - saa.resolveAction(game)); - } - } - - resolveClearMinefieldAttempts(clearAttempts); - } - - private void resolveClearMinefieldAttempts(Vector clearAttempts) { - - for (int i = 0; i < clearAttempts.size(); i++) { - Vector temp = new Vector(); - Entity e = (Entity) clearAttempts.elementAt(i); - Coords pos = e.getPosition(); - temp.addElement(e); - - for (int j = i + 1; j < clearAttempts.size(); j++) { - Entity ent = (Entity) clearAttempts.elementAt(j); - if (ent.getPosition().equals(pos)) { - temp.addElement(ent); - clearAttempts.removeElement(ent); - } - } - - boolean accident = false; - boolean cleared = false; - for (int j = 0; j < temp.size(); j++) { - Entity ent = (Entity) temp.elementAt(j); - int roll = Compute.d6(2); - int clear = Minefield.CLEAR_NUMBER_INFANTRY; - int boom = Minefield.CLEAR_NUMBER_INFANTRY_ACCIDENT; - - // Does the entity has a minesweeper? - Enumeration equip = ent.getMisc(); - while ( equip.hasMoreElements() ) { - Mounted mounted = (Mounted) equip.nextElement(); - if ( mounted.getType().hasFlag(MiscType.F_TOOLS) - && mounted.getType().hasSubType(MiscType.S_MINESWEEPER) ) { - int sweeperType = mounted.getType().getToHitModifier(); - clear = Minefield.CLEAR_NUMBER_SWEEPER[sweeperType]; - boom = Minefield.CLEAR_NUMBER_SWEEPER_ACCIDENT[sweeperType]; - break; - } - } - //mine clearing roll - Report r = new Report(2245); - r.subject = ent.getId(); - r.add(ent.getShortName(), true); - r.add(pos.getBoardNum(), true); - r.add(clear); - r.add(roll); - r.newlines = 0; - addReport(r); - - if (roll >= clear) { - //success - r = new Report(2250); - r.subject = ent.getId(); - addReport(r); - cleared = true; - } else if (roll <= boom) { - //"click"...oops! - r = new Report(2255); - r.subject = ent.getId(); - addReport(r); - accident = true; - } else { - //failure - r = new Report(2260); - r.subject = ent.getId(); - addReport(r); - } - } - if (accident) { - Enumeration minefields = game.getMinefields(pos).elements(); - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - switch (mf.getType()) { - case (Minefield.TYPE_CONVENTIONAL) : - case (Minefield.TYPE_THUNDER) : - for (int j = 0; j < temp.size(); j++) { - Entity entity = (Entity) temp.elementAt(j); - Report r = new Report(2265); - r.subject = entity.getId(); - r.add(entity.getShortName(), true); - addReport(r); - HitData hit = entity.rollHitLocation(Minefield.TO_HIT_TABLE, Minefield.TO_HIT_SIDE); - addReport( damageEntity(entity, hit, mf.getDamage())); - addNewLines(); - } - break; - case (Minefield.TYPE_VIBRABOMB) : - explodeVibrabomb(mf); - break; - } - } - } - if (cleared) { - removeMinefieldsFrom(pos); - } - } - } - - /** - * Called during the fire phase to resolve all (and only) weapon attacks - */ - private void resolveOnlyWeaponAttacks() { - Vector results = new Vector(game.actionsSize()); - - // loop thru received attack actions, getting weapon results - for (Enumeration i = game.getActions(); i.hasMoreElements();) { - Object o = i.nextElement(); - if (o instanceof WeaponAttackAction) { - WeaponAttackAction waa = (WeaponAttackAction)o; - results.addElement(preTreatWeaponAttack(waa)); - } - } - - // loop through weapon results and resolve - int cen = Entity.NONE; - for (Enumeration i = results.elements(); i.hasMoreElements();) { - WeaponResult wr = (WeaponResult)i.nextElement(); - resolveWeaponAttack(wr, cen); - cen = wr.waa.getEntityId(); - } - - // and clear the attacks Vector - game.resetActions(); - } - - /** - * Trigger the indicated AP Pod of the entity. - * - * @param entity the Entity triggering the AP Pod. - * @param podId the int ID of the AP Pod. - */ - private void triggerAPPod( Entity entity, int podId ) { - - // Get the mount for this pod. - Mounted mount = entity.getEquipment( podId ); - - // Confirm that this is, indeed, an AP Pod. - if ( null == mount ) { - System.err.print( "Expecting to find an AP Pod at " ); - System.err.print( podId ); - System.err.print( " on the unit, " ); - System.err.print( entity.getDisplayName() ); - System.err.println( " but found NO equipment at all!!!" ); - return; - } - EquipmentType equip = mount.getType(); - if ( !(equip instanceof MiscType) || - !equip.hasFlag(MiscType.F_AP_POD) ) { - System.err.print( "Expecting to find an AP Pod at " ); - System.err.print( podId ); - System.err.print( " on the unit, " ); - System.err.print( entity.getDisplayName() ); - System.err.print( " but found " ); - System.err.print( equip.getName() ); - System.err.println( " instead!!!" ); - return; - } - - // Now confirm that the entity can trigger the pod. - // Ignore the "used this round" flag. - boolean oldFired = mount.isUsedThisRound(); - mount.setUsedThisRound( false ); - boolean canFire = mount.canFire(); - mount.setUsedThisRound( oldFired ); - if ( !canFire ) { - System.err.print( "Can not trigger the AP Pod at " ); - System.err.print( podId ); - System.err.print( " on the unit, " ); - System.err.print( entity.getDisplayName() ); - System.err.println( "!!!" ); - return; - } - - Report r; - - // Mark the pod as fired and log the action. - mount.setFired( true ); - r = new Report(3010); - r.newlines = 0; - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - - // Walk through ALL entities in the triggering entity's hex. - Enumeration targets = game.getEntities( entity.getPosition() ); - while ( targets.hasMoreElements() ) { - final Entity target = (Entity) targets.nextElement(); - - // Is this an unarmored infantry platoon? - if ( target instanceof Infantry && - !(target instanceof BattleArmor) ) { - - // Roll d6-1 for damage. - final int damage = Compute.d6() - 1; - - // If the platoon took no damage, log it and go no further - if ( 0 == damage ) { - r = new Report(3015); - r.indent(2); - r.subject = target.getId(); - r.addDesc(target); - addReport(r); - } - else { - // Damage the platoon. - addReport( damageEntity( target, new HitData(Infantry.LOC_INFANTRY),damage )); - - // Damage from AP Pods is applied immediately. - target.applyDamage(); - } - - } // End target-is-unarmored - - // Nope, the target is immune. - // Don't make a log entry for the triggering entity. - else if ( !entity.equals( target ) ) { - r = new Report(3020); - r.indent(2); - r.subject = target.getId(); - r.addDesc(target); - addReport(r); - } - - } // Check the next entity in the triggering entity's hex. - } - - /** - * Resolve an Unjam Action object - */ - private void resolveUnjam(Entity entity) { - Report r; - final int TN = entity.getCrew().getGunnery() + 3; - r = new Report(3025); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - for (Enumeration i = entity.getWeapons(); i.hasMoreElements();) { - Mounted mounted = (Mounted)i.nextElement(); - if(mounted.isJammed()) { - WeaponType wtype = (WeaponType)mounted.getType(); - if (wtype.getAmmoType() == AmmoType.T_AC_ROTARY) { - int roll = Compute.d6(2); - r = new Report(3030); - r.indent(); - r.subject = entity.getId(); - r.add(wtype.getName()); - r.add(TN); - r.add(roll); - if(roll >= TN) { - r.choose(true); - mounted.setJammed(false); - } else { - r.choose(false); - } - addReport(r); - } - } - } - } - - private void resolveFindClub(Entity entity) { - EquipmentType clubType = null; - - entity.setFindingClub(true); - - // Get the entity's current hex. - Coords coords = entity.getPosition(); - IHex curHex = game.getBoard().getHex( coords ); - - Report r; - - // Is there a blown off arm in the hex? - if (curHex.terrainLevel(Terrains.ARMS) > 0) { - clubType = EquipmentType.get("Limb Club"); - curHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.ARMS, curHex.terrainLevel(Terrains.ARMS)-1)); - sendChangedHex(entity.getPosition()); - r = new Report(3035); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - } - // Is there a blown off leg in the hex? - else if (curHex.terrainLevel(Terrains.LEGS) > 0) { - clubType = EquipmentType.get("Limb Club"); - curHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.LEGS, curHex.terrainLevel(Terrains.LEGS)-1)); - sendChangedHex(entity.getPosition()); - r = new Report(3040); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - } - - // Is there the rubble of a medium, heavy, - // or hardened building in the hex? - else if ( Building.LIGHT < curHex.terrainLevel( Terrains.RUBBLE ) ) { - - // Finding a club is not guaranteed. The chances are - // based on the type of building that produced the - // rubble. - boolean found = false; - int roll = Compute.d6(2); - switch ( curHex.terrainLevel( Terrains.RUBBLE ) ) { - case Building.MEDIUM: - if ( roll >= 7 ) { - found = true; - } - break; - case Building.HEAVY: - if ( roll >= 6 ) { - found = true; - } - break; - case Building.HARDENED: - if ( roll >= 5 ) { - found = true; - } - break; - } - - // Let the player know if they found a club. - if ( found ) { - clubType = EquipmentType.get("Girder Club"); - r = new Report(3045); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - } else { - // Sorry, no club for you. - clubType = null; - r = new Report(3050); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - } - } - - // Are there woods in the hex? - else if ( curHex.containsTerrain( Terrains.WOODS ) - || curHex.containsTerrain( Terrains.JUNGLE ) ) { - clubType = EquipmentType.get("Tree Club"); - r = new Report(3055); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - } - - // add the club - try { - if (clubType != null) { - entity.addEquipment(clubType, Mech.LOC_NONE); - } - } catch (LocationFullException ex) { - // unlikely... - r = new Report(3060); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - } - } - - /** - * Generates a WeaponResult object for a WeaponAttackAction. Adds heat, - * depletes ammo, sets weapons used. - */ - private WeaponResult preTreatWeaponAttack(WeaponAttackAction waa) { - final Entity ae = game.getEntity(waa.getEntityId()); - final Mounted weapon = ae.getEquipment(waa.getWeaponId()); - final WeaponType wtype = (WeaponType)weapon.getType(); - // 2003-01-02 BattleArmor MG and Small Lasers have unlimited ammo. - final boolean usesAmmo = wtype.getAmmoType() != AmmoType.T_NA && - wtype.getAmmoType() != AmmoType.T_BA_MG && - wtype.getAmmoType() != AmmoType.T_BA_SMALL_LASER && - !wtype.hasFlag(WeaponType.F_INFANTRY); - - Mounted ammo = null; - if (usesAmmo) { - if (waa.getAmmoId() > -1) { - ammo = ae.getEquipment(waa.getAmmoId()); - weapon.setLinked(ammo); - } else { - ammo = weapon.getLinked(); - } - } - boolean streakMiss; - - WeaponResult wr = new WeaponResult(); - wr.waa = waa; - - // has this weapon fired already? - if (weapon.isUsedThisRound()) { - wr.toHit = new ToHitData(TargetRoll.IMPOSSIBLE, "Weapon has already been used this round"); - return wr; - } - // is the weapon functional? - if (weapon.isDestroyed()) { - wr.toHit = new ToHitData(TargetRoll.IMPOSSIBLE, "Weapon was destroyed in a previous round"); - return wr; - } - // is it jammed? - if (weapon.isJammed()) { - wr.toHit = new ToHitData(TargetRoll.IMPOSSIBLE, "Weapon is jammed"); - return wr; - } - // make sure ammo is loaded - if (usesAmmo && (ammo == null || ammo.getShotsLeft() == 0 || ammo.isDumping())) { - ae.loadWeaponWithSameAmmo(weapon); - ammo = weapon.getLinked(); - } - - // store the ammo type for later use (needed for artillery attacks) - waa.setAmmoId(ae.getEquipmentNum(ammo)); - - // compute to-hit - wr.toHit = waa.toHit(game); - - if (waa.isNemesisConfused()) { - wr.toHit.addModifier(1, "iNarc Nemesis pod"); - } - // roll dice - wr.roll = Compute.d6(2); - - // if the shot is possible and not a streak miss - // and not a nemesis-confused shot, add heat and use ammo - streakMiss = (((wtype.getAmmoType() == AmmoType.T_SRM_STREAK) - || (wtype.getAmmoType() == AmmoType.T_LRM_STREAK)) - && wr.roll < wr.toHit.getValue()); - if (wr.toHit.getValue() != TargetRoll.IMPOSSIBLE - && (!streakMiss || Compute.isAffectedByAngelECM(ae, ae.getPosition(), waa.getTarget(game).getPosition())) - && !waa.isNemesisConfused()) { - wr = addHeatUseAmmoFor(waa, wr); - } - - // set the weapon as having fired - weapon.setUsedThisRound(true); - - // if not streak miss, resolve any AMS attacks on this attack - if (!streakMiss) { - wr = resolveAmsFor(waa, wr); - } - - return wr; - } - - /** - * Adds heat and uses ammo appropriate for a single attack of this weapon. - * Call only on a valid attack (and with a streak weapon, only on hits.) - * - * @returns modified WeaponResult - */ - private WeaponResult addHeatUseAmmoFor(WeaponAttackAction waa, WeaponResult wr) { - if (waa.isSwarmingMissiles()) return wr; - - final Entity ae = game.getEntity(waa.getEntityId()); - final Mounted weapon = ae.getEquipment(waa.getWeaponId()); - final WeaponType wtype = (WeaponType)weapon.getType(); - // 2003-01-02 BattleArmor MG and Small Lasers have unlimited ammo. - final boolean usesAmmo = wtype.getAmmoType() != AmmoType.T_NA && - wtype.getAmmoType() != AmmoType.T_BA_MG && - wtype.getAmmoType() != AmmoType.T_BA_SMALL_LASER && - !wtype.hasFlag(WeaponType.F_INFANTRY); - - Mounted ammo = weapon.getLinked(); - - // how many shots are we firing? - int nShots = weapon.howManyShots(); - - // do we need to revert to single shot? - if (usesAmmo && nShots > 1) { - int nAvail = ae.getTotalAmmoOfType(ammo.getType()); - if (nAvail < nShots) { - wr.revertsToSingleShot = true; - nShots = 1; - } - } - - // use up ammo - if (usesAmmo) { - for (int i = 0; i < nShots; i++) { - if (ammo.getShotsLeft() <= 0) { - ae.loadWeaponWithSameAmmo(weapon); - ammo = weapon.getLinked(); - } - ammo.setShotsLeft(ammo.getShotsLeft() - 1); - } - } - - // build up some heat - ae.heatBuildup += (wtype.getHeat() * nShots); - - return wr; - } - - /** - * Resolves any AMS fire for this weapon attack, adding AMS heat, depleting - * AMS ammo. - * @returns the appropriately modified WeaponResult - */ - private WeaponResult resolveAmsFor(WeaponAttackAction waa, WeaponResult wr) { - final Entity te = game.getEntity(waa.getTargetId()); - - // any AMS attacks by the target? - Vector vCounters = waa.getCounterEquipment(); - if (null != vCounters) { - // resolve AMS counter-fire - wr.amsShotDown = new int[vCounters.size()]; - for (int x = 0; x < vCounters.size(); x++) { - wr.amsShotDown[x] = 0; - - Mounted counter = (Mounted)vCounters.elementAt(x); - Mounted mAmmo = counter.getLinked(); - if ((!(counter.getType() instanceof WeaponType)) - || (!(counter.getType().hasFlag(WeaponType.F_AMS))) - || (!counter.isReady()) - || (counter.isMissing())) { - continue; - } - // roll hits - int amsHits = Compute.d6(((WeaponType)counter.getType()).getDamage()); - - // build up some heat (assume target is ams owner) - if (counter.getType().hasFlag(WeaponType.F_HEATASDICE)) - te.heatBuildup += Compute.d6(((WeaponType)counter.getType()).getHeat()); - else - te.heatBuildup += ((WeaponType)counter.getType()).getHeat(); - - // decrement the ammo - if (mAmmo != null) - mAmmo.setShotsLeft(Math.max(0, mAmmo.getShotsLeft() - amsHits)); - - // set the ams as having fired - counter.setUsedThisRound(true); - - wr.amsShotDown[x] = amsHits; - wr.amsShotDownTotal += amsHits; - } - } - - return wr; - } - - /** - * Try to ignite the hex, taking into account exisiting fires and the - * effects of Inferno rounds. - * - * @param c - the Coords of the hex being lit. - * @param bInferno - true if the weapon igniting the - * hex is an Inferno round. If some other weapon or ammo - * is causing the roll, this should be false. - * @param nTargetRoll - the int target number for the - * ignition roll. - * @param nTargetRoll - the int roll target for the attempt. - * @param bReportAttempt - true if the attempt roll should - * be added to the report. - */ - private boolean tryIgniteHex( Coords c, int entityId, boolean bInferno, - int nTargetRoll, boolean bReportAttempt ) { - - IHex hex = game.getBoard().getHex(c); - boolean bAnyTerrain = false; - Report r; - - // Ignore bad coordinates. - if ( hex == null ) { - return false; - } - - // inferno always ignites - if (bInferno) { - game.getBoard().addInfernoTo(c, InfernoTracker.STANDARD_ROUND, 1); - nTargetRoll = 0; - bAnyTerrain = true; - } - - // The hex may already be on fire. - if ( hex.containsTerrain( Terrains.FIRE ) ) { - if ( bReportAttempt ) { - r = new Report(3065); - r.indent(3); - r.subject = entityId; - addReport(r); - } - return true; - } - else if ( ignite(hex, nTargetRoll, bAnyTerrain, entityId) ) { - //hex ignites - r = new Report(3070); - r.indent(3); - r.subject = entityId; - addReport(r); - sendChangedHex(c); - return true; - } - return false; - } - - /** - * Try to ignite the hex, taking into account exisiting fires and the - * effects of Inferno rounds. This version of the method will not report - * the attempt roll. - * - * @param c - the Coords of the hex being lit. - * @param bInferno - true if the weapon igniting the - * hex is an Inferno round. If some other weapon or ammo - * is causing the roll, this should be false. - * @param nTargetRoll - the int roll target for the attempt. - */ - private boolean tryIgniteHex(Coords c, int entityId, boolean bInferno, - int nTargetRoll) { - return tryIgniteHex(c, entityId, bInferno, nTargetRoll, false); - } - - private void tryClearHex(Coords c, int nTarget, int entityId) { - IHex h = game.getBoard().getHex(c); - int woods = h.terrainLevel(Terrains.WOODS); - int jungle = h.terrainLevel(Terrains.JUNGLE); - boolean ice = h.containsTerrain(Terrains.ICE); - Report r; - if (woods == ITerrain.LEVEL_NONE && jungle == ITerrain.LEVEL_NONE && !ice) { - //woods already cleared - r = new Report(3075); - r.indent(3); - r.subject = entityId; - addReport(r); - } else { - int woodsRoll = Compute.d6(2); - r = new Report(3080); - r.indent(3); - r.subject = entityId; - r.add(nTarget); - r.add(woodsRoll); - r.newlines = 0; - addReport(r); - if(woodsRoll >= nTarget) { - if(woods > 2) { - h.removeTerrain(Terrains.WOODS); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.WOODS, woods - 1)); - //ultra heavy converted to heavy - r = new Report(3082); - r.subject = entityId; - addReport(r); - } - else if(woods == 2) { - h.removeTerrain(Terrains.WOODS); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.WOODS, woods - 1)); - //heavy converted to light - r = new Report(3085); - r.subject = entityId; - addReport(r); - } - else if(woods == 1) { - h.removeTerrain(Terrains.WOODS); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.ROUGH, 1)); - //light converted to rough - r = new Report(3090); - r.subject = entityId; - addReport(r); - } - else if(jungle > 2) { - h.removeTerrain(Terrains.JUNGLE); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.JUNGLE, jungle - 1)); - //ultra heavy converted to heavy - r = new Report(3083); - r.subject = entityId; - addReport(r); - } - else if(jungle == 2) { - h.removeTerrain(Terrains.JUNGLE); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.JUNGLE, jungle - 1)); - //heavy converted to light - r = new Report(3086); - r.subject = entityId; - addReport(r); - } - else if(jungle == 1) { - h.removeTerrain(Terrains.JUNGLE); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.ROUGH, 1)); - //light converted to rough - r = new Report(3091); - r.subject = entityId; - addReport(r); - } - else if(ice) { - h.removeTerrain(Terrains.ICE); - r = new Report(3092); - r.subject = entityId; - addReport(r); - resolveIceBroken(c); - } - sendChangedHex(c); - } else { - //fails to clear woods - r = new Report(3095); - r.subject = entityId; - addReport(r); - } - } - } - - private void resolveWeaponAttack(WeaponResult wr, int lastEntityId) { - resolveWeaponAttack(wr, lastEntityId, false); - } - - private boolean resolveWeaponAttack(WeaponResult wr, int lastEntityId, boolean isNemesisConfused) { - return resolveWeaponAttack(wr, lastEntityId, isNemesisConfused, 0); - } - - /** - * Resolve a single Weapon Attack object - * @param wr The WeaponResult to resolve - * @param lastEntityId The int ID of the last - * resolved weaponattack's attacking entity - * @param isNemesisConfused The boolean value of wether - * this attack is one caused by homing in on a iNarc Nemesis pod - * and so should not be further diverted - * @param swarmMissilesLeft The int number of remaining swarm - * missiles this attack has, 0 if this is not a remaining swarm - * missile attack - * @return wether we hit or not, only needed for nemesis pod stuff - */ - private boolean resolveWeaponAttack(WeaponResult wr, int lastEntityId, boolean isNemesisConfused, int swarmMissilesLeft) { - // If it's an artillery shot, the shooting entity - // might have died in the meantime - Entity ae = game.getEntity( wr.waa.getEntityId() ); - if (ae == null) { - ae = game.getOutOfGameEntity( wr.waa.getEntityId() ); - } - final Targetable target = game.getTarget(wr.waa.getTargetType(), - wr.waa.getTargetId()); - Report r; - boolean throughFront; - if (target instanceof Mech) { - throughFront = Compute.isThroughFrontHex(game, wr.waa.getEntityId(), (Entity)target); - } else { - throughFront = true; - } - - int subjectId = Entity.NONE; - Entity entityTarget = null; - if (target.getTargetType() == Targetable.TYPE_ENTITY) { - entityTarget = (Entity) target; - // The target of the attack should definately see the report. - // The attacker usually will, but they might not if the attack - // was indirect without a spotter. - subjectId = entityTarget.getId(); - } else { - //The target is not an entity, so we will show the report to - // the attacker instead. - subjectId = ae.getId(); - } - final Mounted weapon = ae.getEquipment(wr.waa.getWeaponId()); - final WeaponType wtype = (WeaponType) weapon.getType(); - final boolean isWeaponInfantry = wtype.hasFlag(WeaponType.F_INFANTRY); - // 2002-09-16 Infantry weapons have unlimited ammo. - final boolean usesAmmo = wtype.getAmmoType() != AmmoType.T_NA && - wtype.getAmmoType() != AmmoType.T_BA_MG && - wtype.getAmmoType() != AmmoType.T_BA_SMALL_LASER && - !isWeaponInfantry; - //retrieve ammo from the WeaponAttackAction rather than weapon.getLinked, because selected ammo may have changed - //in the case of artillery attacks - Mounted ammo = usesAmmo ? ae.getEquipment(wr.waa.getAmmoId()) : null; - final AmmoType atype = ammo == null ? null : (AmmoType) ammo.getType(); - Infantry platoon = null; - final boolean isBattleArmorAttack = wtype.hasFlag(WeaponType.F_BATTLEARMOR); - ToHitData toHit = wr.toHit; - boolean bInferno = (usesAmmo - && ((atype.getAmmoType() == AmmoType.T_SRM) - || (atype.getAmmoType() == AmmoType.T_BA_INFERNO)) - && atype.getMunitionType() == AmmoType.M_INFERNO); - boolean bFragmentation = (usesAmmo - && ((atype.getAmmoType() == AmmoType.T_LRM) || (atype.getAmmoType() == AmmoType.T_SRM)) - && atype.getMunitionType() == AmmoType.M_FRAGMENTATION); - boolean bAcidHead = (usesAmmo - && atype.getAmmoType() == AmmoType.T_SRM - && atype.getMunitionType() == AmmoType.M_AX_HEAD); - boolean bFlechette = (usesAmmo && (atype.getAmmoType() == AmmoType.T_AC) - && atype.getMunitionType() == AmmoType.M_FLECHETTE); - boolean bArtillery = target.getTargetType() == Targetable.TYPE_HEX_ARTILLERY; - boolean bArtilleryFLAK = target.getTargetType() == Targetable.TYPE_ENTITY - && wtype.hasFlag(WeaponType.F_ARTILLERY) - && (usesAmmo && atype.getMunitionType() == AmmoType.M_STANDARD) - && entityTarget.getMovementMode() == IEntityMovementMode.VTOL - && entityTarget.getElevation() > 0; - boolean bIncendiary = (usesAmmo && atype.getAmmoType() == AmmoType.T_AC && - (atype.getMunitionType() == AmmoType.M_INCENDIARY_AC)); - boolean bTracer = (usesAmmo && atype.getAmmoType() == AmmoType.T_AC && - (atype.getMunitionType() == AmmoType.M_TRACER)); - boolean bAntiTSM = (usesAmmo - && ((atype.getAmmoType() == AmmoType.T_LRM) || (atype.getAmmoType() == AmmoType.T_SRM)) - && atype.getMunitionType() == AmmoType.M_ANTI_TSM); - boolean bSwarm = (usesAmmo - && (atype.getAmmoType() == AmmoType.T_LRM) - && atype.getMunitionType() == AmmoType.M_SWARM); - boolean bSwarmI = (usesAmmo - && (atype.getAmmoType() == AmmoType.T_LRM) - && atype.getMunitionType() == AmmoType.M_SWARM_I); - boolean isIndirect = ((wtype.getAmmoType() == AmmoType.T_LRM) || (wtype.getAmmoType() == AmmoType.T_LRM_TORPEDO)) - && weapon.curMode().equals("Indirect"); - boolean isHotLoaded = ((wtype.getAmmoType() == AmmoType.T_LRM) || - (wtype.getAmmoType() == AmmoType.T_LRM_STREAK) || - (wtype.getAmmoType() == AmmoType.T_LRM_TORPEDO) || - (wtype.getAmmoType() == AmmoType.T_LRM_TORPEDO_COMBO)) - && weapon.curMode().equals("Hot Load"); - boolean isAngelECMAffected = Compute.isAffectedByAngelECM(ae, ae.getPosition(), target.getPosition()); - if (isIndirect && game.getOptions().booleanOption("indirect_fire") && - !game.getOptions().booleanOption("indirect_always_possible") && - LosEffects.calculateLos(game, ae.getId(), target).canSee()) { - r = new Report(3470); - r.subject = subjectId; - r.addDesc(ae); - addReport(r); - return false; - } - boolean bGlancing = false; // For Glancing Hits Rule - int swarmMissilesNowLeft = 0; - int hits = 1, glancingMissileMod = 0; - int glancingCritMod = 0; - - if (!bInferno) { - // also check for inferno infantry - bInferno = (isWeaponInfantry && wtype.hasFlag(WeaponType.F_INFERNO)); - } - final boolean targetInBuilding = - Compute.isInBuilding(game, entityTarget); - if ((bArtillery||bArtilleryFLAK) && game.getPhase()==IGame.PHASE_FIRING) { //if direct artillery - wr.artyAttackerCoords=ae.getPosition(); - } - if ( (bSwarm || bSwarmI) && entityTarget != null) { - entityTarget.addTargetedBySwarm(ae.getId(), wr.waa.getWeaponId()); - } - - // Which building takes the damage? - Building bldg = game.getBoard().getBuildingAt(target.getPosition()); - - // Are we iNarc Nemesis Confusable? - boolean isNemesisConfusable = false; - Mounted mLinker = weapon.getLinkedBy(); - if ( wtype.getAmmoType() == AmmoType.T_ATM || - ( mLinker != null && - mLinker.getType() instanceof MiscType && - !mLinker.isDestroyed() && !mLinker.isMissing() && !mLinker.isBreached() && - mLinker.getType().hasFlag(MiscType.F_ARTEMIS) ) ) { - if ((!weapon.getType().hasModes() || - !weapon.curMode().equals("Indirect")) && - ( ((atype.getAmmoType() == AmmoType.T_ATM) && - (atype.getMunitionType() == AmmoType.M_STANDARD || - atype.getMunitionType() == AmmoType.M_EXTENDED_RANGE || - atype.getMunitionType() == AmmoType.M_HIGH_EXPLOSIVE) ) || - ((atype.getAmmoType() == AmmoType.T_LRM || - atype.getAmmoType() == AmmoType.T_SRM) && - atype.getMunitionType() == AmmoType.M_ARTEMIS_CAPABLE))) { - isNemesisConfusable = true; - } - } else if (wtype.getAmmoType() == AmmoType.T_LRM || - wtype.getAmmoType() == AmmoType.T_SRM) { - if (usesAmmo && atype.getMunitionType() == AmmoType.M_NARC_CAPABLE) { - isNemesisConfusable = true; - } - } - - if (lastEntityId != ae.getId()) { - //report who is firing - r = new Report(3100); - r.subject = subjectId; - r.addDesc(ae); - addReport(r); - } - - // Swarming infantry can stop during any weapons phase after start. - if (Infantry.STOP_SWARM.equals(wtype.getInternalName())) { - // ... but only as their *only* attack action. - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - r = new Report(3105); - r.subject = subjectId; - r.add(toHit.getDesc()); - addReport(r); - return true; - } else { - //swarming ended succesfully - r = new Report(3110); - r.subject = subjectId; - addReport(r); - // Only apply the "stop swarm 'attack'" to the swarmed Mek. - if (ae.getSwarmTargetId() != target.getTargetId()) { - Entity other = game.getEntity(ae.getSwarmTargetId()); - other.setSwarmAttackerId(Entity.NONE); - } - else { - entityTarget.setSwarmAttackerId(Entity.NONE); - } - ae.setSwarmTargetId(Entity.NONE); - return true; - } - } - - // Report weapon attack and its to-hit value. - r = new Report(3115); - r.indent(); - r.newlines = 0; - r.subject = subjectId; - r.add(wtype.getName()); - if (entityTarget != null) { - r.addDesc(entityTarget); - } else { - r.messageId = 3120; - r.add(target.getDisplayName(), true); - } - addReport(r); - - boolean shotAtNemesisTarget = false; - // check for nemesis - if (isNemesisConfusable && !isNemesisConfused) { - // loop through nemesis targets - for (Enumeration e = game.getNemesisTargets(ae, target.getPosition());e.hasMoreElements();) { - Entity entity = (Entity)e.nextElement(); - //friendly unit with attached iNarc Nemesis pod standing in the way - r = new Report(3125); - r.subject = subjectId; - addReport(r); - weapon.setUsedThisRound(false); - WeaponAttackAction newWaa = new WeaponAttackAction(ae.getId(), - entity.getTargetId(), wr.waa.getWeaponId()); - newWaa.setNemesisConfused(true); - WeaponResult newWr = preTreatWeaponAttack(newWaa); - // attack the new target, and if we hit it, return; - if (resolveWeaponAttack(newWr, ae.getId(), true)) return true; - shotAtNemesisTarget = true; - } - } - if (shotAtNemesisTarget) { - //back to original target - r = new Report(3130); - r.subject = subjectId; - r.newlines = 0; - addReport(r); - } - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - r = new Report(3135); - r.subject = subjectId; - r.add(toHit.getDesc()); - addReport(r); - return false; - } - else if (toHit.getValue() == ToHitData.AUTOMATIC_FAIL) { - r = new Report(3140); - r.newlines = 0; - r.subject = subjectId; - r.add(toHit.getDesc()); - addReport(r); - } - else if (toHit.getValue() == ToHitData.AUTOMATIC_SUCCESS) { - r = new Report(3145); - r.newlines = 0; - r.subject = subjectId; - r.add(toHit.getDesc()); - addReport(r); - } - else { - //roll to hit - r = new Report(3150); - r.newlines = 0; - r.subject = subjectId; - r.add(toHit.getValue()); - addReport(r); - } - - // if firing an HGR unbraced, schedule a PSR - if (wtype.getAmmoType() == AmmoType.T_GAUSS_HEAVY && ae.mpUsed > 0) { - // the mod is weight-based - int nMod; - switch (ae.getWeightClass()) { - case EntityWeightClass.WEIGHT_LIGHT: - nMod = 2; - break; - case EntityWeightClass.WEIGHT_MEDIUM: - nMod = 1; - break; - case EntityWeightClass.WEIGHT_HEAVY: - nMod = 0; - break; - default: - nMod = -1; - } - PilotingRollData psr = new PilotingRollData(ae.getId(), nMod, - "fired HeavyGauss unbraced"); - psr.setCumulative(false); - game.addPSR(psr); - } - - // dice have been rolled, thanks - r = new Report(3155); - r.newlines = 0; - r.subject = subjectId; - r.add(wr.roll); - addReport(r); - - // check for AC or Prototype jams - int nShots = weapon.howManyShots(); - if (nShots > 1 || - (wtype.hasFlag(WeaponType.F_PROTOTYPE) && - wtype.getAmmoType() != AmmoType.T_NA) ) { - int jamCheck = 0; - if ((((wtype.getAmmoType() == AmmoType.T_AC_ULTRA) - || (wtype.getAmmoType() == AmmoType.T_AC_ULTRA_THB)) - && weapon.curMode().equals("Ultra")) || - wtype.hasFlag(WeaponType.F_PROTOTYPE)) { - jamCheck = 2; - if (weapon.getType().hasModes() && - weapon.curMode().equals("Ultra") && - wtype.hasFlag(WeaponType.F_PROTOTYPE)) { - jamCheck = 4; - } - } else if (wtype.getAmmoType() == AmmoType.T_AC_ROTARY) { - if (nShots == 2) { - jamCheck = 2; - } else if (nShots == 4) { - jamCheck = 3; - } else if (nShots == 6) { - jamCheck = 4; - } - } - - if (jamCheck > 0 && wr.roll <= jamCheck) { - r = new Report(1210); - // ultras and prototypes are destroyed by jamming - if ((wtype.getAmmoType() == AmmoType.T_AC_ULTRA) - || (wtype.getAmmoType() == AmmoType.T_AC_ULTRA_THB)) { - r.messageId = 3160; - weapon.setJammed(true); - weapon.setHit(true); - } else if (wtype.hasFlag(WeaponType.F_PROTOTYPE)) { - r.messageId = 3165; - weapon.setJammed(true); - weapon.setHit(true); - } else { - r.messageId = 3170; - weapon.setJammed(true); - } - r.subject = subjectId; - addReport(r); - return true; - } - } - - // Resolve roll for disengaged field inhibitors on PPCs, if needed - if (game.getOptions().booleanOption("maxtech_ppc_inhibitors") - && wtype.hasModes() - && weapon.curMode().equals("Field Inhibitor OFF") ) { - int rollTarget = 0; - int dieRoll = Compute.d6(2); - int distance = Compute.effectiveDistance(game, ae, target); - - if (distance>=3) { - rollTarget = 3; - } else if (distance == 2) { - rollTarget = 6; - } else if (distance == 1) { - rollTarget = 10; - } - //roll to avoid damage - r = new Report(3175); - r.subject = ae.getId(); - r.indent(); - addReport(r); - r = new Report(3180); - r.subject = ae.getId(); - r.indent(); - r.add(rollTarget); - r.add(dieRoll); - if (dieRoll0) { - for (int i=0; i 0) { - r = new Report(3230); - r.indent(); - r.subject = subjectId; - r.add(wr.amsShotDown[i]); - addReport(r); - } - } - - // Figure out the maximum number of missile hits. - // TODO: handle this in a different place. - int maxMissiles = 0; - if ( usesAmmo ) { - maxMissiles = wtype.getRackSize(); - if ( wtype.hasFlag(WeaponType.F_DOUBLE_HITS) ) { - maxMissiles *= 2; - } - if ( ae instanceof BattleArmor ) { - platoon = (Infantry) ae; - maxMissiles *= platoon.getShootingStrength(); - } - } - if (bSwarm || bSwarmI) { - swarmMissilesNowLeft = swarmMissilesLeft > 0 ? swarmMissilesLeft : maxMissiles; - maxMissiles = swarmMissilesLeft > 0 ? swarmMissilesLeft : maxMissiles; - } - - // If the AMS shot down *all* incoming missiles, if - // the shot is an automatic failure, or if it's from - // a Streak rack, then Infernos can't ignite the hex - // and any building is safe from damage. - if ( (usesAmmo && wr.amsShotDownTotal >= maxMissiles) - || toHit.getValue() == TargetRoll.AUTOMATIC_FAIL - || ((wtype.getAmmoType() == AmmoType.T_SRM_STREAK - || wtype.getAmmoType() == AmmoType.T_LRM_STREAK) - && !isAngelECMAffected)) { - return !bMissed; - } - // If we're using swarm munition, set the number of missiles that - // are left - if ((bSwarm || bSwarmI) && entityTarget != null) { - swarmMissilesNowLeft -= wr.amsShotDownTotal; - Entity swarmTarget = Compute.getSwarmTarget(game, ae.getId(), entityTarget, wr.waa.getWeaponId()); - if (swarmTarget != null) { - r = new Report(3420); - r.subject = ae.getId(); - r.indent(); - r.add(swarmMissilesNowLeft); - addReport(r); - weapon.setUsedThisRound(false); - WeaponAttackAction newWaa = new WeaponAttackAction(ae.getId(), - swarmTarget.getTargetId(), wr.waa.getWeaponId()); - newWaa.setSwarmingMissiles(true); - newWaa.setOldTargetId(target.getTargetId()); - newWaa.setAmmoId(wr.waa.getAmmoId()); - WeaponResult newWr = preTreatWeaponAttack(newWaa); - resolveWeaponAttack(newWr, ae.getId(), false, swarmMissilesNowLeft); - } else { - r = new Report(3425); - r.subject = ae.getId(); - r.indent(); - addReport(r); - } - } - - // Shots that miss an entity can set fires. - // Infernos always set fires. Otherwise - // Buildings can't be accidentally ignited, - // and some weapons can't ignite fires. - if ( entityTarget != null && - ( bInferno || - ( bldg == null && - wtype.getFireTN() != TargetRoll.IMPOSSIBLE ) ) ) { - tryIgniteHex(target.getPosition(), ae.getId(), bInferno, 11); - } - - // BMRr, pg. 51: "All shots that were aimed at a target inside - // a building and miss do full damage to the building instead." - // BMRr, pg. 77: If the spotting unit successfully designates the target but - // the missile misses, it still detonates in the hex and causes 5 - // points of artillery damage each to all units in the target hex - if ( !targetInBuilding) { - return !bMissed; - } - } - - // special case NARC hits. No damage, but a beacon is appended - if (!bMissed && - wtype.getAmmoType() == AmmoType.T_NARC && - atype.getMunitionType() != AmmoType.M_NARC_EX) { - - if (wr.amsShotDownTotal > 0) { - r = new Report(3235); - r.subject = subjectId; - addReport(r); - for (int i=0; i < wr.amsShotDown.length; i++) { - r = new Report(3230); - r.indent(1); - r.subject = subjectId; - r.add(wr.amsShotDown[i]); - addReport(r); - } - r = new Report(3240); - r.subject = subjectId; - addReport(r); - } else if (entityTarget == null) { - r = new Report(3245); - r.subject = subjectId; - addReport(r); - } else { - entityTarget.setNarcedBy(ae.getOwner().getTeam()); - //narced - r = new Report(3250); - r.subject = subjectId; - addReport(r); - } - return !bMissed; - } - - // special case iNARC hits. No damage, but a beacon is appended - if (!bMissed && - wtype.getAmmoType() == AmmoType.T_INARC && - atype.getMunitionType() != AmmoType.M_EXPLOSIVE) { - - if (wr.amsShotDownTotal > 0) { - r = new Report(3235); - r.subject = subjectId; - addReport(r); - for (int i=0; i < wr.amsShotDown.length; i++) { - r = new Report(3230); - r.indent(1); - r.subject = subjectId; - r.add(wr.amsShotDown[i]); - addReport(r); - } - r = new Report(3240); - r.subject = subjectId; - addReport(r); - } else if (entityTarget == null) { - r = new Report(3245); - r.subject = subjectId; - addReport(r); - } else { - INarcPod pod = null; - if (atype.getMunitionType() == AmmoType.M_ECM) { - pod = new INarcPod( ae.getOwner().getTeam(), - INarcPod.ECM ); - r = new Report(3251); - r.subject = subjectId; - addReport(r); - } else if (atype.getMunitionType() == AmmoType.M_HAYWIRE) { - pod = new INarcPod( ae.getOwner().getTeam(), - INarcPod.HAYWIRE ); - r = new Report(3252); - r.subject = subjectId; - addReport(r); - } else if (atype.getMunitionType() == AmmoType.M_NEMESIS) { - pod = new INarcPod( ae.getOwner().getTeam(), - INarcPod.NEMESIS ); - r = new Report(3253); - r.subject = subjectId; - addReport(r); - } else { - pod = new INarcPod( ae.getOwner().getTeam(), - INarcPod.HOMING ); - r = new Report(3254); - r.subject = subjectId; - addReport(r); - } - entityTarget.attachINarcPod(pod); - } - return !bMissed; - } - - // attempt to clear minefield by LRM/MRM fire. - if (!bMissed && target.getTargetType() == Targetable.TYPE_MINEFIELD_CLEAR) { - int clearAttempt = Compute.d6(2); - - if (clearAttempt >= Minefield.CLEAR_NUMBER_WEAPON) { - //minefield cleared - r = new Report(3255); - r.indent(1); - r.subject = subjectId; - addReport(r); - Coords coords = target.getPosition(); - - Enumeration minefields = game.getMinefields(coords).elements(); - while (minefields.hasMoreElements()) { - Minefield mf = (Minefield) minefields.nextElement(); - - removeMinefield(mf); - } - } else { - //fails to clear - r = new Report(3260); - r.indent(1); - r.subject = subjectId; - addReport(r); - } - return !bMissed; - } - - // yeech. handle damage. . different weapons do this in very different ways - int nCluster = 1, nSalvoBonus = 0; - boolean bSalvo = false; - // ecm check is heavy, so only do it once - boolean bCheckedECM = false; - boolean bECMAffected = false; - boolean bMekStealthActive = false; - String sSalvoType = " shot(s) "; - boolean bAllShotsHit = false; - int nRange = ae.getPosition().distance(target.getPosition()); - int nMissilesModifier = 0; - boolean maxtechmissiles = game.getOptions().booleanOption("maxtech_mslhitpen"); - if (maxtechmissiles) { - if (nRange<=1) { - nMissilesModifier = +1; - } else if (nRange <= wtype.getShortRange()) { - nMissilesModifier = 0; - } else if (nRange <= wtype.getMediumRange()) { - nMissilesModifier = -1; - } else { - nMissilesModifier = -2; - } - } - // All shots fired by a Streak SRM weapon, during - // a Mech Swarm hit, or at an adjacent building. - if (((wtype.getAmmoType() == AmmoType.T_SRM_STREAK - || wtype.getAmmoType() == AmmoType.T_LRM_STREAK) - && !isAngelECMAffected) - || wtype.getAmmoType() == AmmoType.T_NARC - || ae.getSwarmTargetId() == wr.waa.getTargetId() - || ((target.getTargetType() == Targetable.TYPE_BLDG_IGNITE - || target.getTargetType() == Targetable.TYPE_BUILDING) - && ae.getPosition().distance(target.getPosition()) <= 1)) { - bAllShotsHit = true; - } - - // Mek swarms attach the attacker to the target. - if ( !bMissed && Infantry.SWARM_MEK.equals( wtype.getInternalName() ) ) { - // Is the target already swarmed? - if ( Entity.NONE != entityTarget.getSwarmAttackerId() ) { - r = new Report(3265); - r.subject = subjectId; - addReport(r); - } - // Did the target get destroyed by weapons fire? - else if ( entityTarget.isDoomed() || entityTarget.isDestroyed() || - entityTarget.getCrew().isDead() ) { - r = new Report(3270); - r.subject = subjectId; - addReport(r); - } else { - //success - r = new Report(3275); - r.subject = subjectId; - addReport(r); - ae.setSwarmTargetId( wr.waa.getTargetId() ); - entityTarget.setSwarmAttackerId( wr.waa.getEntityId() ); - } - return !bMissed; - } - - // Magnetic Mine Launchers roll number of hits on battle armor - // hits table but use # mines firing instead of men shooting. - else if ( wtype.getInternalName().equals(BattleArmor.MINE_LAUNCHER) ) { - hits = nShots; - if ( !bAllShotsHit ) { - hits = Compute.getBattleArmorHits( hits ); - } - bSalvo = true; - sSalvoType = " mine(s) "; - } - - // Other battle armor attacks use # of men firing to determine hits. - // Each hit can be in a new location. The damage per shot comes from - // the "racksize", or from the ammo, for ammo weapons - else if ( isBattleArmorAttack ) { - bSalvo = true; - platoon = (Infantry) ae; - nCluster = 1; - if (usesAmmo) { - nDamPerHit = atype.getDamagePerShot(); - } - nDamPerHit = wtype.getRackSize(); - hits = platoon.getShootingStrength(); - // All attacks during Mek Swarms hit; all - // others use the Battle Armor hits table. - if ( !bAllShotsHit ) { - hits = Compute.getBattleArmorHits( hits ); - } - - // Handle Inferno SRM squads. - if (bInferno) { - nCluster = hits; - nDamPerHit = 0; - sSalvoType = " Inferno missle(s) "; - bSalvo = false; - } - if (ae.getSwarmTargetId() == wr.waa.getTargetId()) - nDamPerHit += ((BattleArmor)ae).getVibroClawDamage(); - } - - // Infantry damage depends on # men left in platoon. - else if (isWeaponInfantry) { - bSalvo = true; - platoon = (Infantry)ae; - nCluster = 5; - nDamPerHit = 1; - hits = platoon.getDamage(platoon.getShootingStrength()); - //TODO: Hmm, this should be localizable - sSalvoType = " damage are inflicted by the shots that "; - - // Handle Inferno SRM infantry. - if (bInferno) { - nCluster = hits; - nDamPerHit = 0; - sSalvoType = " Inferno missile(s) "; - bSalvo = false; - } - } else if (wtype.getDamage() == WeaponType.DAMAGE_MISSILE || - wtype.hasFlag(WeaponType.F_MISSILE_HITS) ) { - bSalvo = true; - - // Weapons with ammo type T_BA_MG or T_BA_SMALL_LASER - // don't have an atype object. - if ( wtype.getAmmoType() == AmmoType.T_BA_MG || - wtype.getAmmoType() == AmmoType.T_BA_SMALL_LASER ) { - nDamPerHit = Math.abs( wtype.getAmmoType() ); - } else { - sSalvoType = " missile(s) "; - // Get the damage from the linked ammo. - nDamPerHit = atype.getDamagePerShot(); - if ((wtype.getAmmoType() == AmmoType.T_TBOLT5 - || wtype.getAmmoType() == AmmoType.T_TBOLT10 - || wtype.getAmmoType() == AmmoType.T_TBOLT15 - || wtype.getAmmoType() == AmmoType.T_TBOLT20 - ) && nRange <= wtype.getMinimumRange()) { - nDamPerHit /= 2; - } - } - - if ( wtype.getAmmoType() == AmmoType.T_LRM || - wtype.getAmmoType() == AmmoType.T_LRM_STREAK || - wtype.getAmmoType() == AmmoType.T_MRM || - wtype.getAmmoType() == AmmoType.T_ATM || - wtype.getAmmoType() == AmmoType.T_EXLRM || - wtype.getAmmoType() == AmmoType.T_ROCKET_LAUNCHER ) { - nCluster = 5; - } - - // calculate # of missiles hitting - if ( wtype.getAmmoType() == AmmoType.T_LRM || - wtype.getAmmoType() == AmmoType.T_SRM || - wtype.getAmmoType() == AmmoType.T_ATM ) { - - // check for artemis, else check for narc and similar things - mLinker = weapon.getLinkedBy(); - if ( wtype.getAmmoType() == AmmoType.T_ATM || - ( mLinker != null && - mLinker.getType() instanceof MiscType && - !mLinker.isDestroyed() && !mLinker.isMissing() && !mLinker.isBreached() && - mLinker.getType().hasFlag(MiscType.F_ARTEMIS) ) && - atype.getMunitionType() == AmmoType.M_ARTEMIS_CAPABLE) { - - // check ECM interference - if (!bCheckedECM) { - // Attacking Meks using stealth suffer ECM effects. - if ( ae instanceof Mech ) { - bMekStealthActive = ae.isStealthActive(); - } - //if the attacker is effected by ECM or the target is protected by ECM then - //act as if effected. - if (Compute.isAffectedByECM(ae, ae.getPosition(), target.getPosition()) || - Compute.isAffectedByAngelECM(ae, ae.getPosition(), target.getPosition())) - bECMAffected = true; - else if ( Compute.isProtectedByECM((Entity)target,target.getPosition(),ae.getPosition()) || - Compute.isProtectedByAngelECM((Entity)target,target.getPosition(),ae.getPosition())) - bECMAffected = true; - else - bECMAffected = false; - bCheckedECM = true; - } - // also no artemis for IDF, and only use standard ammo (excepot for ATMs) - if (!bECMAffected && !bMekStealthActive - && (!weapon.getType().hasModes() - || !weapon.curMode().equals("Indirect")) - && ( (atype.getAmmoType() == AmmoType.T_ATM && - (atype.getMunitionType() == AmmoType.M_STANDARD|| - atype.getMunitionType() == AmmoType.M_EXTENDED_RANGE || - atype.getMunitionType() == AmmoType.M_HIGH_EXPLOSIVE)) || - ( (atype.getAmmoType() == AmmoType.T_LRM || - atype.getAmmoType() == AmmoType.T_SRM) && - atype.getMunitionType() == AmmoType.M_ARTEMIS_CAPABLE))) { - nSalvoBonus += 2; - } - } else if (entityTarget != null && - (entityTarget.isNarcedBy(ae.getOwner().getTeam()) || - entityTarget.isINarcedBy(ae.getOwner().getTeam()))) { - // check ECM interference - if (!bCheckedECM) { - // Attacking Meks using stealth suffer ECM effects. - if ( ae instanceof Mech ) { - bMekStealthActive = ae.isStealthActive(); - } - - //if the attacker is effected by ECM or the target is protected by ECM then - //act as if effected. - if (Compute.isAffectedByECM(ae, ae.getPosition(), target.getPosition()) || - Compute.isAffectedByAngelECM(ae, ae.getPosition(), target.getPosition())) - bECMAffected = true; - else if ( Compute.isProtectedByECM((Entity)target,target.getPosition(),ae.getPosition()) || - Compute.isProtectedByAngelECM((Entity)target,target.getPosition(),ae.getPosition())) - bECMAffected = true; - else - bECMAffected = false; - bCheckedECM = true; - } - // only apply Narc bonus if we're not suffering ECM effect - // and we are using narc ammo. - if (!bECMAffected - && !bMekStealthActive - && ((atype.getAmmoType() == AmmoType.T_LRM) || (atype.getAmmoType() == AmmoType.T_SRM)) - && atype.getMunitionType() == AmmoType.M_NARC_CAPABLE) { - nSalvoBonus += 2; - } - } - } - - // If dealing with Inferno rounds set damage to zero and reset - // all salvo bonuses (cannot mix with other special munitions). - if (bInferno) { - nDamPerHit = 0; - nSalvoBonus = 0; - sSalvoType = " inferno missile(s) "; - bSalvo = false; - } - if (bSwarm) { - sSalvoType = " swarm missile(s) "; - } - if (bSwarmI) { - sSalvoType = " swarm-I missile(s) "; - } - if (bAntiTSM) { - sSalvoType = " anti-TSM missile(s) "; - } - - // If dealing with fragmentation missiles, - // it does double damage to infantry... - if (bFragmentation) { - sSalvoType = " fragmentation missile(s) "; - } - - // Acid-heads, like infernos, can't mix with any other munitions type. - if (bAcidHead) { - nDamPerHit = 1; - nSalvoBonus = -2; - sSalvoType = " acid-head missile(s) "; - } - - // Large MRM missile racks roll twice. - // MRM missiles never recieve hit bonuses. - if ( wtype.getRackSize() == 30 || wtype.getRackSize() == 40 ) { - hits = Compute.missilesHit(wtype.getRackSize() / 2, nMissilesModifier+glancingMissileMod, maxtechmissiles | bGlancing) + - Compute.missilesHit(wtype.getRackSize() / 2, nMissilesModifier+glancingMissileMod, maxtechmissiles | bGlancing); - } - - // Battle Armor units multiply their racksize by the number - // of men shooting and they can't get missile hit bonuses. - else if ( ae instanceof BattleArmor ) { - platoon = (Infantry) ae; - int temp = wtype.getRackSize() * platoon.getShootingStrength(); - - // Do all shots hit? - if ( bAllShotsHit ) { - hits = temp; - } else { - // Account for more than 20 missles hitting. - hits = 0; - while ( temp > 20 ) { - hits += Compute.missilesHit( 20, nMissilesModifier+glancingMissileMod, maxtechmissiles | bGlancing ); - temp -= 20; - } - hits += Compute.missilesHit( temp, nMissilesModifier+glancingMissileMod, maxtechmissiles | bGlancing ); - } // End not-all-shots-hit - } - - // If all shots hit, use the full racksize. - else if ( bAllShotsHit ) { - hits = wtype.getRackSize(); - } - // In all other circumstances, roll for hits. - else { - hits = Compute.missilesHit(wtype.getRackSize(), nSalvoBonus + nMissilesModifier + glancingMissileMod, maxtechmissiles | bGlancing); - // swarm missiles that didn't hit continue - if ( (bSwarm || bSwarmI) && swarmMissilesLeft == 0) { - swarmMissilesNowLeft = wtype.getRackSize() - hits; - } - } - // anti TSM missiles hit with half the number, round up - if (bAntiTSM) { - hits = (int)Math.ceil((double)hits/2); - } - // swarm or swarm-I shots may just hit with the remaining missiles - if ((bSwarm || bSwarmI) && (swarmMissilesLeft > 0)) { - int swarmsForHitTable = 5; - if (swarmMissilesLeft > 5 && swarmMissilesLeft <= 10) - swarmsForHitTable = 10; - else if (swarmMissilesLeft > 10 && swarmMissilesLeft <= 15) - swarmsForHitTable = 15; - else if (swarmMissilesLeft > 15 && swarmMissilesLeft <= 20) - swarmsForHitTable = 20; - hits = Compute.missilesHit(swarmsForHitTable, nSalvoBonus + nMissilesModifier + glancingMissileMod, maxtechmissiles | bGlancing); - if (hits > swarmMissilesLeft) { - hits = swarmMissilesLeft; - } - swarmMissilesNowLeft = swarmMissilesLeft - hits; - } - - // Advanced SRMs may get additional missiles - if ( usesAmmo && - atype.getAmmoType() == AmmoType.T_SRM_ADVANCED) { - int tmp = wtype.getRackSize() * platoon.getShootingStrength(); - if (hits%2 == 1 && hits < tmp) { - hits++; - } - } - - } else if (usesAmmo - && ((atype.getAmmoType() == AmmoType.T_AC_LBX) - || (atype.getAmmoType() == AmmoType.T_AC_LBX_THB)) - && atype.getMunitionType() == AmmoType.M_CLUSTER) { - // Cluster shots break into single point clusters. - bSalvo = true; - hits = wtype.getRackSize(); - // war of 3039 prototype LBXs get -1 mod on missile chart - int nMod = wtype.hasFlag(WeaponType.F_PROTOTYPE) ? 0 : -1; - if ( !bAllShotsHit ) { - if (!bGlancing) { - hits = Compute.missilesHit( hits, nMod ); - } else { - // if glancing blow, half the number of missiles that hit, - // that halves damage. do this, and not adjust number of - // pellets, because maxtech only talks about missile weapons - hits = Compute.missilesHit(hits, nMod)/2; - } - } - nDamPerHit = 1; - } else if (nShots > 1) { - // this should handle multiple attacks from ultra and rotary ACs - bSalvo = true; - hits = nShots; - if ( !bAllShotsHit ) { - hits = Compute.missilesHit( hits ); - } - } - else if (wtype.getAmmoType() == AmmoType.T_GAUSS_HEAVY) { - // HGR does range-dependent damage - if (nRange <= wtype.getShortRange()) { - nDamPerHit = 25; - } else if (nRange <= wtype.getMediumRange()) { - nDamPerHit = 20; - } else { - nDamPerHit = 10; - } - } else if (wtype.hasFlag(WeaponType.F_ENERGY)) { - // Check for Altered Damage from Energy Weapons (MTR, pg.22) - nDamPerHit = wtype.getDamage(); - if (game.getOptions().booleanOption("maxtech_altdmg")) { - if (nRange<=1) { - nDamPerHit++; - } else if (nRange <= wtype.getMediumRange()) { - // Do Nothing for Short and Medium Range - } else if (nRange <= wtype.getLongRange()) { - nDamPerHit--; - } else if (nRange <= wtype.getExtremeRange()) { - nDamPerHit = (int)Math.floor(nDamPerHit/2.0); - } - } - } else if (weapon.isRapidfire() && - !(target instanceof Infantry && - !(target instanceof BattleArmor)) ){ - // Check for rapid fire Option. Only MGs can be rapidfire. - nDamPerHit = Compute.d6(); - ammoUsage = 3*nDamPerHit; - if (ae.getTotalAmmoOfType(ammo.getType())>0) { - for (int i=0; i 0) { - for (int i=0; i < wr.amsShotDown.length; i++) { - int shotDown = Math.min(wr.amsShotDown[i], hits); - r = new Report(3280); - r.indent(1); - r.subject = subjectId; - r.add(shotDown); - addReport(r); - } - hits -= wr.amsShotDownTotal; - } - - // Is the building hit by Inferno rounds? - if ( bInferno && hits > 0 ) { - - // start a fire in the targets hex - Coords c = target.getPosition(); - IHex h = game.getBoard().getHex(c); - - // Is there a fire in the hex already? - if ( h.containsTerrain( Terrains.FIRE ) ) { - r = new Report(3285); - r.indent(2); - r.subject = subjectId; - r.add(hits); - r.add(c.getBoardNum()); - addReport(r); - } else { - r = new Report(3290); - r.indent(2); - r.subject = subjectId; - r.add(hits); - r.add(c.getBoardNum()); - addReport(r); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - } - game.getBoard().addInfernoTo - ( c, InfernoTracker.STANDARD_ROUND, hits ); - sendChangedHex(c); - - } - - // Damage the building in one big lump. - else { - - // Only report if damage was done to the building. - int toBldg = hits * nDamPerHit; - if ( toBldg > 0 ) { - Report buildingReport = damageBuilding( bldg, toBldg ); - buildingReport.indent(2); - buildingReport.newlines = 1; - buildingReport.subject = subjectId; - addReport(buildingReport); - } - - } // End rounds-hit - - } // End missed-target-in-building - return !bMissed; - - } // End missed-target - - // The building shields all units from a certain amount of damage. - // The amount is based upon the building's CF at the phase's start. - int bldgAbsorbs = 0; - if ( targetInBuilding && bldg != null ) { - bldgAbsorbs = (int) Math.ceil( bldg.getPhaseCF() / 10.0 ); - } - - // All attacks (except from infantry weapons) - // during Mek Swarms hit the same location. - if ( !isWeaponInfantry && - ae.getSwarmTargetId() == wr.waa.getTargetId() ) { - nCluster = hits; - } - - // Battle Armor MGs do one die of damage per hit to PBI. - if ( wtype.getAmmoType() == AmmoType.T_BA_MG && - (target instanceof Infantry) && - !(target instanceof BattleArmor) ) { - - // ASSUMPTION: Building walls protect infantry from BA MGs. - if ( bldgAbsorbs > 0 ) { - int toBldg = nDamPerHit * hits; - r = new Report(3295); - r.newlines = 0; - r.subject = subjectId; - r.add(hits); - r.add(sSalvoType); - addReport(r); - - Report buildingReport = - damageBuilding( bldg, - Math.min( toBldg, bldgAbsorbs ), - " absorbs the shots, taking " ); - buildingReport.newlines = 1; - buildingReport.subject = subjectId; - addReport(buildingReport); - return !bMissed; - } - nDamPerHit = Compute.d6(hits); - r = new Report(3300); - r.newlines = 0; - r.subject = subjectId; - r.add(nDamPerHit); - r.add(sSalvoType); - addReport(r); - hits = 1; - } - - // Mech and Vehicle MGs do *DICE* of damage to PBI. - else if (usesAmmo && atype.hasFlag(AmmoType.F_MG) && - !isWeaponInfantry && (target instanceof Infantry) && - !(target instanceof BattleArmor) && !weapon.isRapidfire()) { - - int dice = wtype.getDamage(); - - // A building may absorb the entire shot. - if ( nDamPerHit <= bldgAbsorbs ) { - int toBldg = nDamPerHit * hits; - int curCF = bldg.getCurrentCF(); - curCF = Math.min( curCF, toBldg ); - bldg.setCurrentCF( curCF ); - if ( bSalvo ) { - r = new Report(3305); - r.subject = subjectId; - r.add(hits); - r.add(sSalvoType); - addReport(r); - } else{ - r = new Report(3310); - r.subject = subjectId; - addReport(r); - } - r = new Report(3315); - r.indent(2); - r.subject = subjectId; - addReport(r); - Report buildingReport = - damageBuilding( bldg, - Math.min( toBldg, bldgAbsorbs ), - " absorbs the shots, taking " ); - buildingReport.newlines = 1; - buildingReport.subject = subjectId; - addReport(buildingReport); - return !bMissed; - } - - // If a building absorbs partial damage, reduce the dice of damage. - else if ( bldgAbsorbs > 0 ) { - dice -= bldgAbsorbs; - } - - nDamPerHit = Compute.d6( dice ); - r = new Report(3320); - r.subject = subjectId; - r.add(nDamPerHit); - r.add(sSalvoType); - addReport(r); - bSalvo = true; - - // If a building absorbed partial damage, report it now - // instead of later and then clear the variable. - if ( bldgAbsorbs > 0 ) { - Report buildingReport = damageBuilding( bldg, bldgAbsorbs ); - buildingReport.indent(2); - buildingReport.subject = subjectId; - addReport(buildingReport); - bldgAbsorbs = 0; - } - - } - - // Report the number of hits. Infernos have their own reporting - else if (bSalvo && !bInferno) { - r = new Report(3325); - r.subject = subjectId; - r.add(hits); - r.add(sSalvoType); - r.add(toHit.getTableDesc()); - r.newlines = 0; - addReport(r); - if (bECMAffected) { - //ECM prevents bonus - r = new Report(3330); - r.subject = subjectId; - r.newlines = 0; - addReport(r); - } - else if (bMekStealthActive) { - //stealth prevents bonus - r = new Report(3335); - r.subject = subjectId; - r.newlines = 0; - addReport(r); - } - if (nSalvoBonus > 0) { - r = new Report(3340); - r.subject = subjectId; - r.add(nSalvoBonus); - r.newlines = 0; - addReport(r); - } - r = new Report(3345); - r.subject = subjectId; - r.newlines = 0; - addReport(r); - - if (wr.amsShotDownTotal > 0) { - for (int i=0; i < wr.amsShotDown.length; i++) { - int shotDown = Math.min(wr.amsShotDown[i], hits); - r = new Report(3350); - r.indent(); - r.subject = subjectId; - r.add(wr.amsShotDown[i]); - r.add(shotDown); - r.newlines = 0; - addReport(r); - } - hits -= wr.amsShotDownTotal; - - addNewLines(); - if (hits < 1) { - //all missiles shot down - r = new Report(3355); - r.indent(); - r.subject = subjectId; - r.newlines = 0; - addReport(r); - } else { - r = new Report(3360); - r.indent(); - r.subject = subjectId; - r.add(hits); - r.newlines = 0; - addReport(r); - } - } - } - - // convert the ATM missile damages to LRM type 5 point cluster damage - // done here after AMS has been performed - if (wtype.getAmmoType() == AmmoType.T_ATM) { - hits = nDamPerHit * hits; - nDamPerHit = 1; - } - - // Make sure the player knows when his attack causes no damage. - if ( hits == 0 ) { - r = new Report(3365); - r.subject = subjectId; - addReport(r); - } - - // for each cluster of hits, do a chunk of damage - while (hits > 0) { - int nDamage; - - // If the attack was with inferno rounds then - // do heat and fire instead of damage. - if ( bInferno ) { - // AMS can shoot down infernos, too. - if (wr.amsShotDownTotal > 0) { - for (int i=0; i < wr.amsShotDown.length; i++) { - int shotDown = Math.min(wr.amsShotDown[i], hits); - r = new Report(3350); - r.indent(); - r.subject = subjectId; - r.add(wr.amsShotDown[i]); - r.add(shotDown); - r.newlines = 0; - addReport(r); - } - hits -= wr.amsShotDownTotal; - - addNewLines(); - if (hits < 1) { - //all missiles shot down - r = new Report(3355); - r.indent(); - r.subject = subjectId; - r.newlines = 0; - addReport(r); - } else { - r = new Report(3360); - r.indent(); - r.subject = subjectId; - r.add(hits); - r.newlines = 0; - addReport(r); - } - if ( hits <= 0 ) { - continue; - } - } - - // targeting a hex for ignition - if( target.getTargetType() == Targetable.TYPE_HEX_IGNITE || - target.getTargetType() == Targetable.TYPE_BLDG_IGNITE ) { - - //inferno missiles hit - r = new Report(3370); - r.subject = subjectId; - r.add(hits); - addReport(r); - - // Unless there a fire in the hex already, start one. - Coords c = target.getPosition(); - IHex h = game.getBoard().getHex(c); - if ( !h.containsTerrain( Terrains.FIRE ) ) { - r = new Report(3005); - r.subject = subjectId; - r.add(c.getBoardNum()); - addReport(r); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - } - game.getBoard().addInfernoTo - ( c, InfernoTracker.STANDARD_ROUND, hits ); - sendChangedHex(c); - - return !bMissed; - } - - // Targeting an entity - if (entityTarget != null ) { - r = new Report(3375); - r.subject = subjectId; - r.add(hits); - addReport(r); - - if(game.getOptions().booleanOption("vehicle_fires") - && entityTarget instanceof Tank) { - checkForVehicleFire((Tank)entityTarget, true); - } else { - entityTarget.infernos.add( InfernoTracker.STANDARD_ROUND, - hits ); - r = new Report(3205); - r.indent(2); - r.subject = subjectId; - r.addDesc(entityTarget); - r.add(entityTarget.infernos.getTurnsLeftToBurn()); - addReport(r); - } - - // Start a fire in the targets hex, unless already on fire. - Coords c = target.getPosition(); - IHex h = game.getBoard().getHex(c); - - // Unless there a fire in the hex already, start one. - if ( !h.containsTerrain( Terrains.FIRE ) ) { - r = new Report(3005); - r.subject = subjectId; - r.add(c.getBoardNum()); - addReport(r); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - } - game.getBoard().addInfernoTo - ( c, InfernoTracker.STANDARD_ROUND, 1 ); - sendChangedHex(c); - - return !bMissed; - } - - } // End is-inferno - - // targeting a hex for igniting - if( target.getTargetType() == Targetable.TYPE_HEX_IGNITE || - target.getTargetType() == Targetable.TYPE_BLDG_IGNITE ) { - if ( !bSalvo ) { - //hits! - r = new Report(2270); - r.subject = subjectId; - r.newlines = 0; - addReport(r); - } - // We handle Inferno rounds above. - int tn = wtype.getFireTN(); - if(bIncendiary) { - tn = 5; // Incendiary AC and LRM - } - if (tn != TargetRoll.IMPOSSIBLE) { - if ( bldg != null ) { - tn += bldg.getType() - 1; - } - addNewLines(); - tryIgniteHex( target.getPosition(), ae.getId(), bInferno, tn, true ); - } - return !bMissed; - } - - // targeting a hex for clearing - if (target.getTargetType() == Targetable.TYPE_HEX_CLEAR) { - - nDamage = nDamPerHit * hits; - if ( !bSalvo ) { - //hits! - r = new Report(2270); - r.subject = subjectId; - r.newlines = 0; - addReport(r); - } - if (ae instanceof Infantry) { - //infantry cannot clear hexes - r = new Report(3380); - r.indent(); - r.subject = subjectId; - addReport(r); - return !bMissed; - } - - - //report that damge was "applied" to terrain - r = new Report(3385); - r.indent(); - r.subject = subjectId; - r.add(nDamage); - addReport(r); - - // Any clear attempt can result in accidental ignition, even - // weapons that can't normally start fires. that's weird. - // Buildings can't be accidentally ignited. - if ( bldg == null) { - boolean alreadyIgnited = game.getBoard().getHex(target.getPosition()).containsTerrain(Terrains.FIRE); - boolean ignited = tryIgniteHex(target.getPosition(), subjectId, bInferno, 9); - if (!alreadyIgnited && ignited) return !bMissed; - } - - int tn = 14 - nDamage; - tryClearHex(target.getPosition(), tn, ae.getId()); - - return !bMissed; - } - - // Targeting a building. - if ( target.getTargetType() == Targetable.TYPE_BUILDING ) { - - // Is the building hit by Inferno rounds? - if ( bInferno ) { - - // start a fire in the targets hex - Coords c = target.getPosition(); - IHex h = game.getBoard().getHex(c); - - // Is there a fire in the hex already? - if ( h.containsTerrain( Terrains.FIRE ) ) { - r = new Report(3285); - r.subject = subjectId; - r.add(hits); - r.add(c.getBoardNum()); - addReport(r); - } else { - r = new Report(3290); - r.subject = subjectId; - r.add(hits); - r.add(c.getBoardNum()); - addReport(r); - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - } - game.getBoard().addInfernoTo - ( c, InfernoTracker.STANDARD_ROUND, hits ); - sendChangedHex(c); - - } else { - // The building takes the full brunt of the attack. - nDamage = nDamPerHit * hits; - if ( !bSalvo ) { - //hits! - r = new Report(3390); - r.subject = subjectId; - addReport(r); - } - addNewLines(); - Report buildingReport = damageBuilding( bldg, nDamage ); - buildingReport.indent(2); - buildingReport.newlines = 1; - buildingReport.subject = subjectId; - addReport(buildingReport); - - // Damage any infantry in the hex. - this.damageInfantryIn( bldg, nDamage ); - } - - // And we're done! - return !bMissed; - } - - // Battle Armor squads equipped with fire protection - // gear automatically avoid flaming death. - if ( wtype.hasFlag(WeaponType.F_FLAMER) && - target instanceof BattleArmor ) { - - for ( Enumeration iter = entityTarget.getMisc(); - iter.hasMoreElements(); ) { - Mounted mount = (Mounted) iter.nextElement(); - EquipmentType equip = mount.getType(); - if ( BattleArmor.FIRE_PROTECTION.equals - (equip.getInternalName()) ) { - if ( !bSalvo ) { - //hits - r = new Report(3390); - r.subject = subjectId; - addReport(r); - } - r = new Report(3395); - r.indent(2); - r.subject = subjectId; - r.addDesc(entityTarget); - addReport(r); - - // A building may be damaged, even if the squad is not. - if ( bldgAbsorbs > 0 ) { - int toBldg = nDamPerHit * Math.min( bldgAbsorbs, - hits ); - Report buildingReport = damageBuilding( bldg, toBldg ); - buildingReport.indent(2); - buildingReport.newlines = 1; - buildingReport.subject = subjectId; - addReport(buildingReport); - } - - return !bMissed; - } - } - } // End target-may-be-immune - - // Flamers do heat to mechs instead damage if the option is - // available and the mode is set. - if (entityTarget != null - && (entityTarget instanceof Mech) - && wtype.hasFlag(WeaponType.F_FLAMER) - && game.getOptions().booleanOption("flamer_heat") - && wtype.hasModes() - && weapon.curMode().equals("Heat")) { - nDamage = nDamPerHit * hits; - if ( !bSalvo ) { - //hits - r = new Report(3390); - r.subject = subjectId; - addReport(r); - } - r = new Report(3400); - r.subject = subjectId; - r.indent(2); - r.add(nDamage); - r.newlines = 0; - addReport(r); - entityTarget.heatBuildup += nDamage; - hits = 0; - } else if (entityTarget != null) { - HitData hit = entityTarget.rollHitLocation - ( toHit.getHitTable(), - toHit.getSideTable(), - wr.waa.getAimedLocation(), - wr.waa.getAimingMode() ); - - if (wtype.hasFlag(WeaponType.F_PLASMA_MFUK) - && (entityTarget instanceof Mech)) { - nDamage = nDamPerHit * hits; - if (!bSalvo) { - //hits - r = new Report(3390); - r.subject = subjectId; - addReport(r); - } - r = new Report(3400); - r.subject = subjectId; - r.indent(2); - r.add(5); - r.newlines = 0; - addReport(r); - entityTarget.heatBuildup += 5; - } - - // If a leg attacks hit a leg that isn't - // there, then hit the other leg. - if ( wtype.getInternalName().equals("LegAttack") && - entityTarget.getInternal(hit) <= 0 ) { - if ( hit.getLocation() == Mech.LOC_RLEG ) { - hit = new HitData( Mech.LOC_LLEG ); - } - else { - hit = new HitData( Mech.LOC_RLEG ); - } - } - - // Mine Launchers automatically hit the - // CT of a Mech or the front of a Tank. - if ( wtype.getInternalName() - .equals(BattleArmor.MINE_LAUNCHER) ) { - if ( target instanceof Mech ) { - hit = new HitData( Mech.LOC_CT ); - } - else { // te instanceof Tank - hit = new HitData( Tank.LOC_FRONT ); - } - } - - // Each hit in the salvo get's its own hit location. - if (!bSalvo) { - r = new Report(3405); - r.subject = subjectId; - r.add(toHit.getTableDesc()); - r.add(entityTarget.getLocationAbbr(hit)); - r.newlines = 0; - addReport(r); - if (hit.hitAimedLocation()) { - r = new Report(3410); - r.subject = subjectId; - r.newlines = 0; - addReport(r); - } - } - - // Special weapons do criticals instead of damage. - if ( nDamPerHit == WeaponType.DAMAGE_SPECIAL ) { - // Do criticals. - //String specialDamage = criticalEntity( entityTarget, hit.getLocation() ); - Vector specialDamageReport = criticalEntity( entityTarget, hit.getLocation() ); - - // Replace "no effect" results with 4 points of damage. - //if ( specialDamage.endsWith(" no effect.") ) { - if (((Report)specialDamageReport.lastElement()).messageId == 6005) { - int damage = 4; - if (ae instanceof BattleArmor) - damage += ((BattleArmor)ae).getVibroClawDamage(); - // ASSUMPTION: buildings CAN'T absorb *this* damage. - //specialDamage = damageEntity(entityTarget, hit, damage); - specialDamageReport = damageEntity(entityTarget, hit, damage, false, 0, false, false, throughFront); - } - else { - //add newline _before_ last report - try { - ((Report) specialDamageReport.elementAt(specialDamageReport.size() - 2)).newlines++; - } catch (ArrayIndexOutOfBoundsException aiobe) { - System.err.println("ERROR: no previous report when trying to add newline"); - } - } - - // Report the result - addReport( specialDamageReport); - } - else if(game.getOptions().booleanOption("maxtech_partial_cover") && - toHit.getHitTable() == ToHitData.HIT_PARTIAL_COVER && - entityTarget.removePartialCoverHits(hit.getLocation(), toHit.getCover(), toHit.getSideTable())) { - r = new Report(3460); - r.subject = entityTarget.getId(); - r.indent(2); - r.add(entityTarget.getDisplayName()); - r.add(entityTarget.getLocationAbbr(hit)); - r.newlines = 0; - addReport(r); - } - else { - // Resolve damage normally. - nDamage = nDamPerHit * Math.min(nCluster, hits); - - // A building may be damaged, even if the squad is not. - if ( bldgAbsorbs > 0 ) { - int toBldg = Math.min( bldgAbsorbs, nDamage ); - nDamage -= toBldg; - addNewLines(); - Report buildingReport = damageBuilding( bldg, toBldg ); - buildingReport.indent(2); - buildingReport.subject = subjectId; - addReport(buildingReport); - } - - // A building may absorb the entire shot. - if ( nDamage == 0 ) { - r = new Report(3415); - r.subject = subjectId; - r.indent(2); - r.addDesc(entityTarget); - r.newlines = 0; - addReport(r); - } else if (bFragmentation) { - // If it's a frag missile... - if (bGlancing) { - hit.makeGlancingBlow(); - } - addReport( - damageEntity(entityTarget, hit, nDamage, false, 1, false, false, throughFront)); - } else if (bFlechette) { - // If it's a frag missile... - if (bGlancing) { - hit.makeGlancingBlow(); - } - addReport( - damageEntity(entityTarget, hit, nDamage, false, 2, false, false, throughFront)); - } else if (bAcidHead) { - // If it's an acid-head warhead... - if (bGlancing) { - hit.makeGlancingBlow(); - } - addReport( - damageEntity(entityTarget, hit, nDamage, false, 3, false, false, throughFront) ); - } else if(bIncendiary && usesAmmo && atype.getAmmoType() == AmmoType.T_AC) { - //incendiary AC ammo - if (bGlancing) { - hit.makeGlancingBlow(); - } - addReport( - damageEntity(entityTarget, hit, nDamage, false, 4, false, false, throughFront)); - } else { - if (usesAmmo - && (atype.getAmmoType() == AmmoType.T_AC) - && (atype.getMunitionType() == AmmoType.M_ARMOR_PIERCING) - && !(entityTarget.getArmorType() == EquipmentType.T_ARMOR_HARDENED)) - hit.makeArmorPiercing(atype); - if (bGlancing) { - hit.makeGlancingBlow(); - } - if (bAntiTSM) { - entityTarget.hitThisRoundByAntiTSM = true; - } - addReport( - damageEntity(entityTarget, hit, nDamage, false, 0, false, false, throughFront)); - } - } - hits -= nCluster; - creditKill(entityTarget, ae); - } else { - System.err.println("Unable to resolve hit against "+target.getDisplayName()); - if(entityTarget == null) { - System.err.println(" entityTarget is null"); - } - hits = 0; //prevents server lock-up - } - } // Handle the next cluster. - - //deal with splash damage from Arrow IV homing - if(atype != null && atype.getMunitionType() == AmmoType.M_HOMING) { - artilleryDamageHex(target.getPosition(), wr.artyAttackerCoords, 5, atype, subjectId, ae, entityTarget, false, 0); - } - - addNewLines(); - - if (swarmMissilesNowLeft > 0 && entityTarget != null) { - Entity swarmTarget = Compute.getSwarmTarget(game, ae.getId(), entityTarget, wr.waa.getWeaponId()); - if (swarmTarget != null) { - //missiles keep swarming - r = new Report(3420); - r.subject = swarmTarget.getId(); - r.indent(); - r.add(swarmMissilesNowLeft); - addReport(r); - weapon.setUsedThisRound(false); - WeaponAttackAction newWaa = new WeaponAttackAction(ae.getId(), - swarmTarget.getTargetId(), wr.waa.getWeaponId()); - newWaa.setSwarmingMissiles(true); - newWaa.setOldTargetId(target.getTargetId()); - newWaa.setAmmoId(wr.waa.getAmmoId()); - WeaponResult newWr = preTreatWeaponAttack(newWaa); - resolveWeaponAttack(newWr, ae.getId(), false, swarmMissilesNowLeft); - } else { - //missiles can't find another target - r = new Report(3425); - r.subject = ae.getId(); - r.indent(); - addReport(r); - } - } - - return !bMissed; - } - - /** - * Handle all physical attacks for the round - */ - private void resolvePhysicalAttacks() { - //Physical phase header - addReport(new Report(4000, Report.PUBLIC)); - - // add any pending charges - for (Enumeration i = game.getCharges(); i.hasMoreElements();) { - game.addAction((EntityAction)i.nextElement()); - } - game.resetCharges(); - - // remove any duplicate attack declarations - cleanupPhysicalAttacks(); - - // loop thru received attack actions - for (Enumeration i = game.getActions(); i.hasMoreElements();) { - Object o = i.nextElement(); - - // verify that the attacker is still active - AttackAction aa = (AttackAction)o; - if (!(game.getEntity(aa.getEntityId()).isActive()) - && !(o instanceof DfaAttackAction)) { - continue; - } - AbstractAttackAction aaa = (AbstractAttackAction)o; - // do searchlights immediately - if (aaa instanceof SearchlightAttackAction) { - SearchlightAttackAction saa = (SearchlightAttackAction)aaa; - addReport( - saa.resolveAction(game)); - } else { - physicalResults.addElement(preTreatPhysicalAttack(aaa)); - } - } - int cen = Entity.NONE; - for (Enumeration i = physicalResults.elements(); i.hasMoreElements();) { - PhysicalResult pr = (PhysicalResult)i.nextElement(); - resolvePhysicalAttack(pr, cen); - cen = pr.aaa.getEntityId(); - } - physicalResults.removeAllElements(); - } - - /** - * Cleans up the attack declarations for the physical phase by removing - * all attacks past the first for any one mech. Also clears out attacks - * by dead or disabled mechs. - */ - private void cleanupPhysicalAttacks() { - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - Entity entity = (Entity)i.nextElement(); - removeDuplicateAttacks(entity.getId()); - } - removeDeadAttacks(); - } - - /** - * Removes any actions in the attack queue beyond the first by the - * specified entity. - */ - private void removeDuplicateAttacks(int entityId) { - boolean attacked = false; - Vector toKeep = new Vector(/*game.actionsSize()*/); - - for (Enumeration i = game.getActions(); i.hasMoreElements();) { - EntityAction action = (EntityAction)i.nextElement(); - if (action.getEntityId() != entityId) { - toKeep.addElement(action); - } else if (!attacked) { - toKeep.addElement(action); - if(!(action instanceof SearchlightAttackAction)) { - attacked = true; - } - } else { - System.err.println("server: removing duplicate phys attack for id#" + entityId); - System.err.println(" action was "+ action.toString()); - } - } - - // reset actions and re-add valid elements - game.resetActions(); - for (Enumeration i = toKeep.elements(); i.hasMoreElements();) { - game.addAction((EntityAction)i.nextElement()); - } - } - - /** - * Removes all attacks by any dead entities. It does this by going through - * all the attacks and only keeping ones from active entities. DFAs are - * kept even if the pilot is unconscious, so that he can fail. - */ - private void removeDeadAttacks() { - Vector toKeep = new Vector(game.actionsSize()); - - for (Enumeration i = game.getActions(); i.hasMoreElements();) { - EntityAction action = (EntityAction)i.nextElement(); - Entity entity = game.getEntity(action.getEntityId()); - if (entity != null && !entity.isDestroyed() - && (entity.isActive() || action instanceof DfaAttackAction)) { - toKeep.addElement(action); - } - } - - // reset actions and re-add valid elements - game.resetActions(); - for (Enumeration i = toKeep.elements(); i.hasMoreElements();) { - game.addAction((EntityAction)i.nextElement()); - } - } - - /** - * Handle a punch attack - */ - private void resolvePunchAttack(PhysicalResult pr, int lastEntityId) { - final PunchAttackAction paa = (PunchAttackAction)pr.aaa; - final Entity ae = game.getEntity(paa.getEntityId()); - final Targetable target = game.getTarget(paa.getTargetType(), paa.getTargetId()); - Entity te = null; - if (target.getTargetType() == Targetable.TYPE_ENTITY) { - te = (Entity)target; - } - boolean throughFront = true; - if (te!=null) { - throughFront = Compute.isThroughFrontHex(game, paa.getEntityId(), te); - } - final String armName = paa.getArm() == PunchAttackAction.LEFT - ? "Left Arm" : "Right Arm"; - // get damage, ToHitData and roll from the PhysicalResult - int damage = paa.getArm() == PunchAttackAction.LEFT - ? pr.damage : pr.damageRight; - final ToHitData toHit = paa.getArm() == PunchAttackAction.LEFT - ? pr.toHit : pr.toHitRight; - int roll = paa.getArm() == PunchAttackAction.LEFT - ? pr.roll : pr.rollRight; - final boolean targetInBuilding = Compute.isInBuilding( game, te ); - final boolean glancing = (game.getOptions().booleanOption("maxtech_glancing_blows") && (roll == toHit.getValue())); - Report r; - - // Which building takes the damage? - Building bldg = game.getBoard().getBuildingAt( target.getPosition() ); - - if (lastEntityId != paa.getEntityId()) { - //report who is making the attacks - r = new Report(4005); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - } - - r = new Report(4010); - r.subject = ae.getId(); - r.indent(); - r.add(armName); - r.add(target.getDisplayName()); - r.newlines = 0; - addReport(r); - - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - r = new Report(4015); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - return; - } else if (toHit.getValue() == ToHitData.AUTOMATIC_SUCCESS) { - r = new Report(4020); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - r.newlines = 0; - addReport(r); - roll = Integer.MAX_VALUE; - } else { - r = new Report(4025); - r.subject = ae.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - if (glancing) { - r = new Report(4030); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - } - } - - // do we hit? - if (roll < toHit.getValue()) { - //nope - r = new Report(4035); - r.subject = ae.getId(); - addReport(r); - - // If the target is in a building, the building absorbs the damage. - if ( targetInBuilding && bldg != null ) { - - // Only report if damage was done to the building. - if ( damage > 0 ) { - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - } - - } - return; - } - - // Targeting a building. - if ( target.getTargetType() == Targetable.TYPE_BUILDING ) { - - // The building takes the full brunt of the attack. - r = new Report(4040); - r.subject = ae.getId(); - addReport(r); - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - - // Damage any infantry in the hex. - this.damageInfantryIn( bldg, damage ); - - // And we're done! - return; - } - - HitData hit = te.rollHitLocation(toHit.getHitTable(), toHit.getSideTable()); - r = new Report(4045); - r.subject = ae.getId(); - r.add(toHit.getTableDesc()); - r.add(te.getLocationAbbr(hit)); - r.newlines = 0; - addReport(r); - - // The building shields all units from a certain amount of damage. - // The amount is based upon the building's CF at the phase's start. - if ( targetInBuilding && bldg != null ) { - int bldgAbsorbs = (int) Math.ceil( bldg.getPhaseCF() / 10.0 ); - int toBldg = Math.min( bldgAbsorbs, damage ); - damage -= toBldg; - addNewLines(); - Report buildingReport = damageBuilding( bldg, toBldg ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - } - - // A building may absorb the entire shot. - if ( damage == 0 ) { - r = new Report(4050); - r.subject = ae.getId(); - r.add(te.getShortName()); - r.add(te.getOwner().getName()); - r.newlines = 0; - addReport(r); - } else { - if (glancing) { - damage = (int)Math.floor(damage/2.0); - } - addReport(damageEntity(te, hit, damage, false, 0, false, false, throughFront)); - } - - addNewLines(); - } - - /** - * Handle a kick attack - */ - private void resolveKickAttack(PhysicalResult pr, int lastEntityId) { - KickAttackAction kaa = (KickAttackAction)pr.aaa; - final Entity ae = game.getEntity(kaa.getEntityId()); - final Targetable target = game.getTarget(kaa.getTargetType(), kaa.getTargetId()); - Entity te = null; - if (target.getTargetType() == Targetable.TYPE_ENTITY) { - te = (Entity)target; - } - boolean throughFront = true; - if (te!=null) { - throughFront = Compute.isThroughFrontHex(game, kaa.getEntityId(), te); - } - String legName = ( (kaa.getLeg() == KickAttackAction.LEFT) || - (kaa.getLeg() == KickAttackAction.LEFTMULE) ) - ? "Left " - : "Right "; - if (game.getOptions().booleanOption("maxtech_mulekicks")) { - if ( (kaa.getLeg() == KickAttackAction.LEFTMULE) || - (kaa.getLeg() == KickAttackAction.RIGHTMULE) ) { - legName.concat(" rear "); - } else { - legName.concat(" front "); - } - } - legName.concat("leg"); - Report r; - - // get damage, ToHitData and roll from the PhysicalResult - int damage = pr.damage; - final ToHitData toHit = pr.toHit; - int roll = pr.roll; - final boolean targetInBuilding = Compute.isInBuilding( game, te ); - final boolean glancing = (game.getOptions().booleanOption("maxtech_glancing_blows") && (roll == toHit.getValue())); - - // Which building takes the damage? - Building bldg = game.getBoard().getBuildingAt( target.getPosition() ); - - if (lastEntityId != ae.getId()) { - //who is making the attacks - r = new Report(4005); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - } - - r = new Report(4055); - r.subject = ae.getId(); - r.indent(); - r.add(legName); - r.add(target.getDisplayName()); - r.newlines = 0; - addReport(r); - - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - r = new Report(4060); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - game.addPSR(new PilotingRollData(ae.getId(), 0, "missed a kick")); - return; - } else if (toHit.getValue() == ToHitData.AUTOMATIC_SUCCESS) { - r = new Report(4065); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - r.newlines = 0; - addReport(r); - roll = Integer.MAX_VALUE; - } else { - r = new Report(4025); - r.subject = ae.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - if (glancing) { - r = new Report(4030); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - } - } - - // do we hit? - if (roll < toHit.getValue()) { - // miss - r = new Report(4035); - r.subject = ae.getId(); - addReport(r); - game.addPSR(new PilotingRollData(ae.getId(), 0, "missed a kick")); - - // If the target is in a building, the building absorbs the damage. - if ( targetInBuilding && bldg != null ) { - - // Only report if damage was done to the building. - if ( damage > 0 ) { - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - } - - } - return; - } - - // Targeting a building. - if ( target.getTargetType() == Targetable.TYPE_BUILDING ) { - - // The building takes the full brunt of the attack. - r = new Report(4040); - r.subject = ae.getId(); - addReport(r); - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - - // Damage any infantry in the hex. - this.damageInfantryIn( bldg, damage ); - - // And we're done! - return; - } - - HitData hit = te.rollHitLocation(toHit.getHitTable(), toHit.getSideTable()); - r = new Report(4045); - r.subject = ae.getId(); - r.add(toHit.getTableDesc()); - r.add(te.getLocationAbbr(hit)); - r.newlines = 0; - addReport(r); - - // The building shields all units from a certain amount of damage. - // The amount is based upon the building's CF at the phase's start. - if ( targetInBuilding && bldg != null ) { - int bldgAbsorbs = (int) Math.ceil( bldg.getPhaseCF() / 10.0 ); - int toBldg = Math.min( bldgAbsorbs, damage ); - damage -= toBldg; - addNewLines(); - Report buildingReport = damageBuilding( bldg, toBldg ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - } - - // A building may absorb the entire shot. - if ( damage == 0 ) { - r = new Report(4050); - r.subject = ae.getId(); - r.add(te.getShortName()); - r.add(te.getOwner().getName()); - r.newlines = 0; - addReport(r); - } else { - if (glancing) { - damage = (int)Math.floor(damage/2.0); - } - addReport(damageEntity(te, hit, damage, false, 0, false, false, throughFront)); - } - - if (te.getMovementMode() == IEntityMovementMode.BIPED || te.getMovementMode() == IEntityMovementMode.QUAD) { - PilotingRollData kickPRD = new PilotingRollData(te.getId(), getKickPushPSRMod(ae, te, 0), "was kicked"); - kickPRD.setCumulative(false); // see Bug# 811987 for more info - game.addPSR(kickPRD); - } - - addNewLines(); - } - - /** - * Handle a Protomech physicalattack - */ - - private void resolveProtoAttack(PhysicalResult pr, int lastEntityId) { - final ProtomechPhysicalAttackAction ppaa = (ProtomechPhysicalAttackAction)pr.aaa; - final Entity ae = game.getEntity(ppaa.getEntityId()); - // get damage, ToHitData and roll from the PhysicalResult - int damage = pr.damage; - final ToHitData toHit = pr.toHit; - int roll = pr.roll; - final Targetable target = game.getTarget(ppaa.getTargetType(), ppaa.getTargetId()); - Entity te = null; - if (target.getTargetType() == Targetable.TYPE_ENTITY) { - te = (Entity)target; - } - boolean throughFront = true; - if (te!=null) { - throughFront = Compute.isThroughFrontHex(game, ppaa.getEntityId(), te); - } - final boolean targetInBuilding = Compute.isInBuilding( game, te ); - final boolean glancing = (game.getOptions().booleanOption("maxtech_glancing_blows") && (roll == toHit.getValue())); - Report r; - - // Which building takes the damage? - Building bldg = game.getBoard().getBuildingAt( target.getPosition() ); - - if (lastEntityId != ae.getId()) { - //who is making the attacks - r = new Report(4005); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - } - - r = new Report(4070); - r.subject = ae.getId(); - r.indent(); - r.add(target.getDisplayName()); - r.newlines = 0; - addReport(r); - - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - r = new Report(4075); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - return; - } else if (toHit.getValue() == ToHitData.AUTOMATIC_SUCCESS) { - r = new Report(4080); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - r.newlines = 0; - addReport(r); - roll = Integer.MAX_VALUE; - } else { - // report the roll - r = new Report(4025); - r.subject = ae.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - if (glancing) { - r = new Report(4030); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - } - } - - // do we hit? - if (roll < toHit.getValue()) { - // miss - r = new Report(4035); - r.subject = ae.getId(); - addReport(r); - - // If the target is in a building, the building absorbs the damage. - if ( targetInBuilding && bldg != null ) { - - // Only report if damage was done to the building. - if ( damage > 0 ) { - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - } - - } - return; - } - - // Targeting a building. - if ( target.getTargetType() == Targetable.TYPE_BUILDING ) { - - // The building takes the full brunt of the attack. - r = new Report(4040); - r.subject = ae.getId(); - addReport(r); - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - - // Damage any infantry in the hex. - this.damageInfantryIn( bldg, damage ); - - // And we're done! - return; - } - - HitData hit = te.rollHitLocation(toHit.getHitTable(), toHit.getSideTable()); - r = new Report(4045); - r.subject = ae.getId(); - r.add(toHit.getTableDesc()); - r.add(te.getLocationAbbr(hit)); - r.newlines = 0; - addReport(r); - - // The building shields all units from a certain amount of damage. - // The amount is based upon the building's CF at the phase's start. - if ( targetInBuilding && bldg != null ) { - int bldgAbsorbs = (int) Math.ceil( bldg.getPhaseCF() / 10.0 ); - int toBldg = Math.min( bldgAbsorbs, damage ); - damage -= toBldg; - addNewLines(); - Report buildingReport = damageBuilding( bldg, toBldg ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - } - - // A building may absorb the entire shot. - if ( damage == 0 ) { - r = new Report(4050); - r.subject = ae.getId(); - r.add(te.getShortName()); - r.add(te.getOwner().getName()); - r.newlines = 0; - addReport(r); - } else { - if (glancing) { - damage = (int)Math.floor(damage/2.0); - } - addReport(damageEntity(te, hit, damage)); - } - - addNewLines(); - } - - - /** - * Handle a brush off attack - */ - private void resolveBrushOffAttack( PhysicalResult pr, - int lastEntityId ) { - final BrushOffAttackAction baa = (BrushOffAttackAction)pr.aaa; - final Entity ae = game.getEntity(baa.getEntityId()); - // PLEASE NOTE: buildings are *never* the target - // of a "brush off", but iNarc pods **are**. - Targetable target = game.getTarget( baa.getTargetType(), - baa.getTargetId() ); - Entity te = null; - final String armName = baa.getArm() == BrushOffAttackAction.LEFT - ? "Left Arm" : "Right Arm"; - Report r; - - if (target.getTargetType() == Targetable.TYPE_ENTITY) { - te = game.getEntity(baa.getTargetId()); - } - - // get damage, ToHitData and roll from the PhysicalResult - // ASSUMPTION: buildings can't absorb *this* damage. - int damage = baa.getArm() == BrushOffAttackAction.LEFT - ? pr.damage : pr.damageRight; - final ToHitData toHit = baa.getArm() == BrushOffAttackAction.LEFT - ? pr.toHit : pr.toHitRight; - int roll = baa.getArm() == BrushOffAttackAction.LEFT - ? pr.roll : pr.rollRight; - - if (lastEntityId != baa.getEntityId()) { - //who is making the attacks - r = new Report(4005); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - } - - r = new Report(4085); - r.subject = ae.getId(); - r.indent(); - r.add(target.getDisplayName()); - r.newlines = 0; - addReport(r); - - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - r = new Report(4090); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - return; - } - - // report the roll - r = new Report(4025); - r.subject = ae.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - - // do we hit? - if (roll < toHit.getValue()) { - //miss - r = new Report(4035); - r.subject = ae.getId(); - addReport(r); - - // Missed Brush Off attacks cause punch damage to the attacker. - toHit.setHitTable( ToHitData.HIT_PUNCH ); - toHit.setSideTable( ToHitData.SIDE_FRONT ); - HitData hit = ae.rollHitLocation( toHit.getHitTable(), - toHit.getSideTable() ); - r = new Report(4095); - r.subject = ae.getId(); - r.addDesc(ae); - r.add(ae.getLocationAbbr(hit)); - r.newlines = 0; - addReport(r); - addReport( - damageEntity(ae, hit, damage)); - addNewLines(); - return; - } - - // Different target types get different handling. - switch ( target.getTargetType() ) { - case Targetable.TYPE_ENTITY: - // Handle Entity targets. - HitData hit = te.rollHitLocation( toHit.getHitTable(), - toHit.getSideTable() ); - r = new Report(4045); - r.subject = ae.getId(); - r.add(toHit.getTableDesc()); - r.add(te.getLocationAbbr(hit)); - r.newlines = 0; - addReport(r); - addReport( - damageEntity(te, hit, damage)); - addNewLines(); - - // Dislodge the swarming infantry. - ae.setSwarmAttackerId( Entity.NONE ); - te.setSwarmTargetId( Entity.NONE ); - r = new Report(4100); - r.subject = ae.getId(); - r.add(te.getDisplayName()); - addReport(r); - break; - case Targetable.TYPE_INARC_POD: - // Handle iNarc pod targets. - // TODO : check the return code and handle false appropriately. - ae.removeINarcPod( (INarcPod) target ); -// // TODO : confirm that we don't need to update the attacker. //killme -// entityUpdate( ae.getId() ); // killme - r = new Report(4105); - r.subject = ae.getId(); - r.add(target.getDisplayName()); - addReport(r); - break; - // TODO : add a default: case and handle it appropriately. - } - } - - /** - * Handle a thrash attack - */ - private void resolveThrashAttack( PhysicalResult pr, - int lastEntityId ) { - final ThrashAttackAction taa = (ThrashAttackAction)pr.aaa; - final Entity ae = game.getEntity(taa.getEntityId()); - - // get damage, ToHitData and roll from the PhysicalResult - int hits = pr.damage; - final ToHitData toHit = pr.toHit; - int roll = pr.roll; - final boolean glancing = (game.getOptions().booleanOption("maxtech_glancing_blows") && (roll == toHit.getValue())); - - // PLEASE NOTE: buildings are *never* the target of a "thrash". - final Entity te = game.getEntity(taa.getTargetId()); - Report r; - - if (lastEntityId != taa.getEntityId()) { - //who is making the attacks - r = new Report(4005); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - } - - r = new Report(4110); - r.subject = ae.getId(); - r.indent(); - r.addDesc(te); - r.newlines = 0; - addReport(r); - - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - r = new Report(4115); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - return; - } - - // Thrash attack may hit automatically - if ( toHit.getValue() == ToHitData.AUTOMATIC_SUCCESS ) { - r = new Report(4120); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - } else { - // report the roll - r = new Report(4025); - r.subject = ae.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - - // do we hit? - if (roll < toHit.getValue()) { - //miss - r = new Report(4035); - r.subject = ae.getId(); - addReport(r); - return; - } - r = new Report(4125); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - } - - // Standard damage loop in 5 point clusters. - if (glancing) { - hits = (int)Math.floor(hits/2.0); - } - - r = new Report(4130); - r.subject = ae.getId(); - r.add(hits); - r.newlines = 0; - addReport(r); - if (glancing) { - r = new Report(4030); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - } - while ( hits > 0 ) { - int damage = Math.min(5, hits); - hits -= damage; - HitData hit = te.rollHitLocation( toHit.getHitTable(), - toHit.getSideTable() ); - r = new Report(4135); - r.subject = ae.getId(); - r.add(te.getLocationAbbr(hit)); - r.newlines = 0; - addReport(r); - addReport( - damageEntity(te, hit, damage)); - } - - addNewLines(); - - // Thrash attacks cause PSRs. Failed PSRs cause falling damage. - // This fall damage applies even though the Thrashing Mek is prone. - PilotingRollData rollData = ae.getBasePilotingRoll(); - ae.addPilotingModifierForTerrain(rollData); - rollData.addModifier( 0, "thrashing at infantry" ); - r = new Report(4140); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - final int diceRoll = Compute.d6(2); - r = new Report(2190); - r.subject = ae.getId(); - r.addDesc(ae); - r.add(rollData.getValueAsString()); - r.add(rollData.getDesc()); - r.add(diceRoll); - if (diceRoll < rollData.getValue()) { - r.choose(false); - addReport(r); - doEntityFall( ae, rollData ); - } else { - r.choose(true); - addReport(r); - } - - } - - /** - * Handle a club attack - */ - private void resolveClubAttack(PhysicalResult pr, int lastEntityId) { - final ClubAttackAction caa = (ClubAttackAction)pr.aaa; - final Entity ae = game.getEntity(caa.getEntityId()); - // get damage, ToHitData and roll from the PhysicalResult - int damage = pr.damage; - final ToHitData toHit = pr.toHit; - int roll = pr.roll; - final Targetable target = game.getTarget(caa.getTargetType(), caa.getTargetId()); - Entity te = null; - if (target.getTargetType() == Targetable.TYPE_ENTITY) { - te = (Entity)target; - } - boolean throughFront = true; - if (te!=null) { - throughFront = Compute.isThroughFrontHex(game, caa.getEntityId(), te); - } - final boolean targetInBuilding = Compute.isInBuilding( game, te ); - final boolean glancing = (game.getOptions().booleanOption("maxtech_glancing_blows") && (roll == toHit.getValue())); - Report r; - - // Which building takes the damage? - Building bldg = game.getBoard().getBuildingAt( target.getPosition() ); - - // restore club attack - caa.getClub().restore(); - - if (lastEntityId != caa.getEntityId()) { - //who is making the attacks - r = new Report(4005); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - } - - r = new Report(4145); - r.subject = ae.getId(); - r.indent(); - r.add(caa.getClub().getName()); - r.add(target.getDisplayName()); - r.newlines = 0; - addReport(r); - - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - r = new Report(4075); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - if (((MiscType)(caa.getClub().getType())).hasSubType(MiscType.S_MACE_THB)) { - game.addPSR(new PilotingRollData(ae.getId(), 0, "missed a mace attack")); - } - if (((MiscType)(caa.getClub().getType())).hasSubType(MiscType.S_MACE)) { - game.addPSR(new PilotingRollData(ae.getId(), 2, "missed a mace attack")); - } - return; - } else if (toHit.getValue() == ToHitData.AUTOMATIC_SUCCESS) { - r = new Report(4080); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - r.newlines = 0; - addReport(r); - roll = Integer.MAX_VALUE; - } else { - // report the roll - r = new Report(4025); - r.subject = ae.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - if (glancing) { - r = new Report(4030); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - } - } - - // do we hit? - if (roll < toHit.getValue()) { - //miss - r = new Report(4035); - r.subject = ae.getId(); - addReport(r); - if (((MiscType)(caa.getClub().getType())).hasSubType(MiscType.S_MACE_THB)) { - game.addPSR(new PilotingRollData(ae.getId(), 0, "missed a mace attack")); - } - if (((MiscType)(caa.getClub().getType())).hasSubType(MiscType.S_MACE)) { - game.addPSR(new PilotingRollData(ae.getId(), 2, "missed a mace attack")); - } - - // If the target is in a building, the building absorbs the damage. - if ( targetInBuilding && bldg != null ) { - - // Only report if damage was done to the building. - if ( damage > 0 ) { - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - } - - } - return; - } - - // Targeting a building. - if ( target.getTargetType() == Targetable.TYPE_BUILDING ) { - - // The building takes the full brunt of the attack. - r = new Report(4040); - r.subject = ae.getId(); - addReport(r); - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - - // Damage any infantry in the hex. - this.damageInfantryIn( bldg, damage ); - - // And we're done! - return; - } - - HitData hit = te.rollHitLocation(toHit.getHitTable(), toHit.getSideTable()); - r = new Report(4045); - r.subject = ae.getId(); - r.add(toHit.getTableDesc()); - r.add(te.getLocationAbbr(hit)); - r.newlines = 0; - addReport(r); - - // The building shields all units from a certain amount of damage. - // The amount is based upon the building's CF at the phase's start. - if ( targetInBuilding && bldg != null ) { - int bldgAbsorbs = (int) Math.ceil( bldg.getPhaseCF() / 10.0 ); - int toBldg = Math.min( bldgAbsorbs, damage ); - damage -= toBldg; - addNewLines(); - Report buildingReport = damageBuilding( bldg, toBldg ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - } - - // A building may absorb the entire shot. - if ( damage == 0 ) { - r = new Report(4050); - r.subject = ae.getId(); - r.add(te.getShortName()); - r.add(te.getOwner().getName()); - r.newlines = 0; - addReport(r); - } else { - if (glancing) { - damage = (int)Math.floor(damage/2.0); - } - addReport(damageEntity(te, hit, damage, false, 0, false, false, throughFront)); - } - - addNewLines(); - - if (((MiscType)caa.getClub().getType()).hasSubType(MiscType.S_TREE_CLUB)) { - //the club breaks - r = new Report(4150); - r.subject = ae.getId(); - r.add(caa.getClub().getName()); - addReport(r); - ae.removeMisc(caa.getClub().getName()); - } - } - - /** - * Handle a push attack - */ - private void resolvePushAttack(PhysicalResult pr, int lastEntityId) { - final PushAttackAction paa = (PushAttackAction)pr.aaa; - final Entity ae = game.getEntity(paa.getEntityId()); - // PLEASE NOTE: buildings are *never* the target of a "push". - final Entity te = game.getEntity(paa.getTargetId()); - // get roll and ToHitData from the PhysicalResult - int roll = pr.roll; - final ToHitData toHit = pr.toHit; - Report r; - - // was this push resolved earlier? - if (pr.pushBackResolved) { - return; - } - - if (lastEntityId != paa.getEntityId()) { - //who is making the attack - r = new Report(4005); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - } - - r = new Report(4155); - r.subject = ae.getId(); - r.indent(); - r.addDesc(te); - r.newlines = 0; - addReport(r); - - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - r = new Report(4160); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - return; - } - - // report the roll - r = new Report(4025); - r.subject = ae.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - - // check if our target has a push against us, too, and get it - PhysicalResult targetPushResult = null; - for (Enumeration i = physicalResults.elements(); i.hasMoreElements();) { - PhysicalResult tpr = (PhysicalResult)i.nextElement(); - if (tpr.aaa.getEntityId() == te.getId() && - tpr.aaa instanceof PushAttackAction && - tpr.aaa.getTargetId() == ae.getId() ) { - targetPushResult = tpr; - } - } - // if our target has a push against us, we need to resolve both now - if (targetPushResult != null) { - // do both hit? - if (targetPushResult.roll >= targetPushResult.toHit.getValue() && - roll >= toHit.getValue()) { - r = new Report(4165); - r.subject = ae.getId(); - r.addDesc(te); - r.addDesc(te); - r.addDesc(ae); - r.add(toHit.getValue()); - r.add(roll); - r.addDesc(ae); - addReport(r); - PilotingRollData targetPushPRD = new PilotingRollData(te.getId(), getKickPushPSRMod(ae, te, 0), "was pushed"); - targetPushPRD.setCumulative(false); // see Bug# 811987 for more info - PilotingRollData pushPRD = new PilotingRollData(ae.getId(), getKickPushPSRMod(ae, te, 0), "was pushed"); - pushPRD.setCumulative(false); // see Bug# 811987 for more info - game.addPSR(pushPRD); - game.addPSR(targetPushPRD); - targetPushResult.pushBackResolved = true; - return; - } - } - - // do we hit? - if (roll < toHit.getValue()) { - //miss - r = new Report(4035); - r.subject = ae.getId(); - addReport(r); - return; - } - - // we hit... - int direction = ae.getFacing(); - - Coords src = te.getPosition(); - Coords dest = src.translated(direction); - - PilotingRollData pushPRD = new PilotingRollData(te.getId(), getKickPushPSRMod(ae, te, 0), "was pushed"); - pushPRD.setCumulative(false); // see Bug# 811987 for more info - - if (Compute.isValidDisplacement(game, te.getId(), te.getPosition(), direction)) { - r = new Report(4170); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - if (game.getBoard().contains(dest)) { - r = new Report(4175); - r.subject = ae.getId(); - r.add(dest.getBoardNum(), true); - addReport(r); - } else { - //uh-oh, pushed off board - r = new Report(4180); - r.subject = ae.getId(); - addReport(r); - } - - doEntityDisplacement(te, src, dest, pushPRD); - - // if push actually moved the target, attacker follows thru - if (!te.getPosition().equals(src)) { - ae.setPosition(src); - } - } else { - //targe imovable - r = new Report(4185); - r.subject = ae.getId(); - addReport(r); - game.addPSR(pushPRD); - } - - addNewLines(); - } - - /** - * Handle a charge attack - */ - private void resolveChargeAttack(PhysicalResult pr, int lastEntityId) { - final ChargeAttackAction caa = (ChargeAttackAction)pr.aaa; - final Entity ae = game.getEntity(caa.getEntityId()); - final Targetable target = game.getTarget(caa.getTargetType(), caa.getTargetId()); - // get damage, ToHitData and roll from the PhysicalResult - int damage = pr.damage; - final ToHitData toHit = pr.toHit; - int roll = pr.roll; - Entity te = null; - if (target != null && target.getTargetType() == Targetable.TYPE_ENTITY) { - te = (Entity)target; - } - boolean throughFront = true; - if (te!=null) { - throughFront = Compute.isThroughFrontHex(game, caa.getEntityId(), te); - } - final boolean glancing = (game.getOptions().booleanOption("maxtech_glancing_blows") && (roll == toHit.getValue())); - Report r; - - // Which building takes the damage? - Building bldg = game.getBoard().getBuildingAt( caa.getTargetPos() ); - - // is the attacker dead? because that sure messes up the calculations - if (ae == null) { - return; - } - - final int direction = ae.getFacing(); - - // entity isn't charging any more - ae.setDisplacementAttack(null); - - if (lastEntityId != caa.getEntityId()) { - //who is making the attack - r = new Report(4005); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - } - - // should we even bother? - if (target == null || (target.getTargetType() == Targetable.TYPE_ENTITY - && (te.isDestroyed() || te.isDoomed() || te.crew.isDead()))) { - r = new Report(4190); - r.subject = ae.getId(); - r.indent(); - addReport(r); - // doEntityDisplacement(ae, ae.getPosition(), caa.getTargetPos(), null); - // Randall said that if a charge fails because of target destruction, - // the attacker stays in the hex he was in at the end of the movement phase - // See Bug 912094 - return; - } - - // attacker fell down? - if (ae.isProne()) { - r = new Report(4195); - r.subject = ae.getId(); - r.indent(); - addReport(r); - return; - } - - // attacker immobile? - if (ae.isImmobile()) { - r = new Report(4200); - r.subject = ae.getId(); - r.indent(); - addReport(r); - return; - } - - if (te.isProne()) { - r = new Report(4205); - r.subject = ae.getId(); - r.indent(); - addReport(r); - return; - } - - r = new Report(4210); - r.subject = ae.getId(); - r.indent(); - r.add(target.getDisplayName()); - r.newlines = 0; - addReport(r); - - // target still in the same position? - if (!target.getPosition().equals(caa.getTargetPos())) { - r = new Report(4215); - r.subject = ae.getId(); - addReport(r); - doEntityDisplacement(ae, ae.getPosition(), caa.getTargetPos(), null); - return; - } - - // if the attacker's prone, fudge the roll - if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - roll = -12; - r = new Report(4220); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - } else if (toHit.getValue() == ToHitData.AUTOMATIC_SUCCESS) { - roll = Integer.MAX_VALUE; - r = new Report(4225); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - } else { - // report the roll - r = new Report(4025); - r.subject = ae.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - if (glancing) { - r = new Report(4030); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - } - } - - // do we hit? - if (roll < toHit.getValue()) { - Coords src = ae.getPosition(); - Coords dest = Compute.getMissedChargeDisplacement(game, ae.getId(), src, direction); - - // TODO: handle movement into/out of/through a building. Do it here? - - //miss - r = new Report(4035); - r.subject = ae.getId(); - addReport(r); - // move attacker to side hex - doEntityDisplacement(ae, src, dest, null); - } - - // Targeting a building. - else if ( target.getTargetType() == Targetable.TYPE_BUILDING ) { - - // The building takes the full brunt of the attack. - r = new Report(4040); - r.subject = ae.getId(); - addReport(r); - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - - // Damage any infantry in the hex. - this.damageInfantryIn( bldg, damage ); - - // Apply damage to the attacker. - int toAttacker = ChargeAttackAction.getDamageTakenBy( ae, bldg ); - HitData hit = ae.rollHitLocation( ToHitData.HIT_NORMAL, - ae.sideTable(target.getPosition()) - ); - addReport( - damageEntity( ae, hit, toAttacker, false, 0, false, false, throughFront)); - addNewLines(); - entityUpdate( ae.getId() ); - - // TODO: Does the attacker enter the building? - // TODO: What if the building collapses? - } - else { - // Resolve the damage. - resolveChargeDamage( ae, te, toHit, direction, glancing, throughFront ); - } - return; - } - - /** - * Handle a charge's damage - */ - private void resolveChargeDamage(Entity ae, Entity te, ToHitData toHit, int direction) { - resolveChargeDamage (ae, te, toHit, direction, false, true); - } - - private void resolveChargeDamage(Entity ae, Entity te, ToHitData toHit, int direction, boolean glancing, boolean throughFront) { - - // we hit... - int damage = ChargeAttackAction.getDamageFor(ae); - int damageTaken = ChargeAttackAction.getDamageTakenBy(ae, te, game.getOptions().booleanOption("maxtech_charge_damage")); - PilotingRollData chargePSR = null; - if (glancing) { - // Glancing Blow rule doesn't state whether damage to attacker on charge - // or DFA is halved as well, assume yes. TODO: Check with PM - damage = (int)Math.floor(damage/2.0); - damageTaken = (int)Math.floor(damageTaken/2.0); - } - // Is the target inside a building? - final boolean targetInBuilding = Compute.isInBuilding( game, te ); - - // Which building takes the damage? - Building bldg = game.getBoard().getBuildingAt( te.getPosition() ); - - // The building shields all units from a certain amount of damage. - // The amount is based upon the building's CF at the phase's start. - int bldgAbsorbs = 0; - if ( targetInBuilding && bldg != null ) { - bldgAbsorbs = (int) Math.ceil( bldg.getPhaseCF() / 10.0 ); - } - - // If we're upright, we may fall down. - if ( !ae.isProne() ) { - chargePSR = new PilotingRollData(ae.getId(), 2, "charging"); - } - - Report r; - - - r = new Report(4230); - r.subject = ae.getId(); - r.add(damage); - r.add(toHit.getTableDesc()); - r.newlines = 0; - addReport(r); - while (damage > 0) { - int cluster = Math.min(5, damage); - damage -= cluster; - if ( bldgAbsorbs > 0 ) { - int toBldg = Math.min( bldgAbsorbs, cluster ); - cluster -= toBldg; - addNewLines(); - Report buildingReport = damageBuilding( bldg, toBldg ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - } - - // A building may absorb the entire shot. - if ( cluster == 0 ) { - r = new Report(4235); - r.subject = ae.getId(); - r.addDesc(te); - r.newlines = 0; - addReport(r); - } else { - HitData hit = te.rollHitLocation(toHit.getHitTable(), toHit.getSideTable()); - addReport( - damageEntity(te, hit, cluster, false, 0, false, false, throughFront)); - } - } - - //damage to attacker - r = new Report(4240); - r.subject = ae.getId(); - r.add(damageTaken); - r.newlines = 0; - addReport(r); - while (damageTaken > 0) { - int cluster = Math.min(5, damageTaken); - HitData hit = ae.rollHitLocation(ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT); - addReport( - damageEntity(ae, hit, cluster)); - damageTaken -= cluster; - } - // move attacker and target, if possible - Coords src = te.getPosition(); - Coords dest = src.translated(direction); - - if (Compute.isValidDisplacement(game, te.getId(), te.getPosition(), direction)) { - addNewLines(); - doEntityDisplacement(te, src, dest, new PilotingRollData(te.getId(), 2, "was charged")); - doEntityDisplacement(ae, ae.getPosition(), src, chargePSR); - } - - addNewLines(); - - } // End private void resolveChargeDamage( Entity, Entity, ToHitData ) - - private void resolveLayExplosivesAttack(PhysicalResult pr, int lastEntityId) { - final LayExplosivesAttackAction laa = (LayExplosivesAttackAction)pr.aaa; - final Entity ae = game.getEntity(laa.getEntityId()); - final Targetable target = game.getTarget(laa.getTargetType(), laa.getTargetId()); - if(ae instanceof Infantry) { - Infantry inf = (Infantry) ae; - if(inf.turnsLayingExplosives < 0) { - inf.turnsLayingExplosives = 0; - Report r = new Report(4270); - r.subject = inf.getId(); - r.addDesc(inf); - addReport(r); - } else { - Building building = game.getBoard().getBuildingAt(ae.getPosition()); - if(building != null) { - building.addDemolitionCharge(ae.getOwner().getId(), pr.damage); - Report r = new Report(4275); - r.subject = inf.getId(); - r.addDesc(inf); - r.add(pr.damage); - addReport(r); - } - inf.turnsLayingExplosives = -1; - } - } - } - - /** - * Handle a death from above attack - */ - private void resolveDfaAttack(PhysicalResult pr, int lastEntityId) { - final DfaAttackAction daa = (DfaAttackAction)pr.aaa; - final Entity ae = game.getEntity(daa.getEntityId()); - final Targetable target = game.getTarget(daa.getTargetType(), daa.getTargetId()); - // get damage, ToHitData and roll from the PhysicalResult - int damage = pr.damage; - final ToHitData toHit = pr.toHit; - int roll = pr.roll; - Entity te = null; - if (target != null && target.getTargetType() == Targetable.TYPE_ENTITY) { - // Lets re-write around that horrible hack that was here before. - // So instead of asking if a specific location is wet and praying - // that it won't cause an NPE... - // We'll check 1) if the hex has water, and 2) if it's deep enough - // to cover the unit in question at its current elevation. - // It's especially important to make sure it's done this way, - // because some units (Sylph, submarines) can be at ANY elevation - // underwater, and VTOLs can be well above the surface. - te = (Entity)target; - IHex hex = game.getBoard().getHex(te.getPosition()); - if (hex.containsTerrain(Terrains.WATER)) { - if (te.absHeight() < hex.getElevation()) - damage = (int)Math.ceil(damage * 0.5f); - } - } - boolean throughFront = true; - if (te!=null) { - throughFront = Compute.isThroughFrontHex(game, daa.getEntityId(), te); - } - final boolean glancing = (game.getOptions().booleanOption("maxtech_glancing_blows") && (roll == toHit.getValue())); - Report r; - - // Which building takes the damage? - Building bldg = game.getBoard().getBuildingAt( daa.getTargetPos() ); - - // is the attacker dead? because that sure messes up the calculations - if (ae == null) { - return; - } - - final int direction = ae.getFacing(); - - if (lastEntityId != daa.getEntityId()) { - //who is making the attack - r = new Report(4005); - r.subject = ae.getId(); - r.addDesc(ae); - addReport(r); - } - - // entity isn't DFAing any more - ae.setDisplacementAttack(null); - - // should we even bother? - if (target == null || (target.getTargetType() == Targetable.TYPE_ENTITY - && (te.isDestroyed() || te.isDoomed() || te.crew.isDead()))) { - r = new Report(4245); - r.subject = ae.getId(); - r.indent(); - addReport(r); - if (ae.isProne()) { - // attacker prone during weapons phase - doEntityFall(ae, daa.getTargetPos(), 2, 3, ae.getBasePilotingRoll()); - - } else { - // same effect as successful DFA - doEntityDisplacement(ae, ae.getPosition(), daa.getTargetPos(), new PilotingRollData(ae.getId(), 4, "executed death from above")); - } - return; - } - - r = new Report(4246); - r.subject = ae.getId(); - r.indent(); - r.add(target.getDisplayName()); - r.newlines = 0; - addReport(r); - - // target still in the same position? - if ( !target.getPosition().equals(daa.getTargetPos()) ) { - r = new Report(4215); - r.subject = ae.getId(); - addReport(r); - doEntityFallsInto(ae, ae.getPosition(), daa.getTargetPos(), ae.getBasePilotingRoll()); - return; - } - - // hack: if the attacker's prone, or incapacitated, fudge the roll - if (ae.isProne() || !ae.isActive()) { - roll = -12; - r = new Report(4250); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - } else if (toHit.getValue() == ToHitData.IMPOSSIBLE) { - roll = -12; - r = new Report(4255); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - } else if (toHit.getValue() == ToHitData.AUTOMATIC_SUCCESS) { - r = new Report(4260); - r.subject = ae.getId(); - r.add(toHit.getDesc()); - addReport(r); - roll = Integer.MAX_VALUE; - } else { - // report the roll - r = new Report(4025); - r.subject = ae.getId(); - r.add(toHit.getValue()); - r.add(roll); - r.newlines = 0; - addReport(r); - if (glancing) { - r = new Report(4030); - r.subject = ae.getId(); - r.newlines = 0; - addReport(r); - } - } - - // do we hit? - if (roll < toHit.getValue()) { - Coords dest = te.getPosition(); - Coords targetDest = Compute.getPreferredDisplacement(game, te.getId(), dest, direction); - //miss - r = new Report(4035); - r.subject = ae.getId(); - addReport(r); - if (targetDest != null) { - // attacker falls into destination hex - r = new Report(4265); - r.subject = ae.getId(); - r.addDesc(ae); - r.add(dest.getBoardNum(), true); - addReport(r); - doEntityFall(ae, dest, 2, 3, ae.getBasePilotingRoll()); - - // move target to preferred hex - doEntityDisplacement(te, dest, targetDest, null); - } else { - // attacker destroyed Tanks - // suffer an ammo/power plant hit. - // TODO : a Mech suffers a Head Blown Off crit. - addReport( - destroyEntity(ae, "impossible displacement", (ae instanceof Mech), (ae instanceof Mech))); - } - return; - } - - // we hit... - // Can't DFA a target inside of a building. - int damageTaken = DfaAttackAction.getDamageTakenBy(ae); - - r = new Report(4040); - r.subject = ae.getId(); - addReport(r); - - // Targeting a building. - if ( target.getTargetType() == Targetable.TYPE_BUILDING ) { - - // The building takes the full brunt of the attack. - Report buildingReport = damageBuilding( bldg, damage ); - buildingReport.indent(); - buildingReport.subject = ae.getId(); - addReport(buildingReport); - - // Damage any infantry in the hex. - this.damageInfantryIn( bldg, damage ); - - } - - // Target isn't building. - else { - if (glancing) { - damage = (int)Math.floor(damage/2.0); - } - //damage target - r = new Report(4230); - r.subject = ae.getId(); - r.add(damage); - r.add(toHit.getTableDesc()); - r.newlines = 0; - addReport(r); - while (damage > 0) { - int cluster = Math.min(5, damage); - HitData hit = te.rollHitLocation(toHit.getHitTable(), toHit.getSideTable()); - addReport( - damageEntity(te, hit, cluster, false, 0, false, false, throughFront)); - damage -= cluster; - } - } - - if (glancing) { - // Glancing Blow rule doesn't state whether damage to attacker on charge - // or DFA is halved as well, assume yes. TODO: Check with PM - damageTaken = (int)Math.floor(damageTaken/2.0); - } - - //damage attacker - r = new Report(4240); - r.subject = ae.getId(); - r.add(damageTaken); - r.newlines = 0; - addReport(r); - while (damageTaken > 0) { - int cluster = Math.min(5, damageTaken); - HitData hit = ae.rollHitLocation(ToHitData.HIT_KICK, ToHitData.SIDE_FRONT); - addReport( - damageEntity(ae, hit, cluster)); - damageTaken -= cluster; - } - - addNewLines(); - - // That's it for target buildings. - // TODO: where do I put the attacker?!? - if ( target.getTargetType() == Targetable.TYPE_BUILDING ) { - return; - } - - // Target entities are pushed away or destroyed. - Coords dest = te.getPosition(); - Coords targetDest = Compute.getValidDisplacement(game, te.getId(), dest, direction); - if (targetDest != null) { - doEntityDisplacement(te, dest, targetDest, new PilotingRollData(te.getId(), 2, "hit by death from above")); - } else { - // ack! automatic death! Tanks - // suffer an ammo/power plant hit. - // TODO : a Mech suffers a Head Blown Off crit. - addReport(destroyEntity(te, "impossible displacement", (te instanceof Mech), (te instanceof Mech))); - } - // HACK: to avoid automatic falls, displace from dest to dest - doEntityDisplacement(ae, dest, dest, new PilotingRollData(ae.getId(), 4, "executed death from above")); - } - - /** - * Get the modifier for a Kick or Push PSR - * @param attacker The attacking Entity> - * @param target The target Entity - * @param def The int default modifier - * @return The int modifier to the PSR - */ - private int getKickPushPSRMod(Entity attacker, Entity target, int def) { - int mod = def; - - if ( game.getOptions().booleanOption("maxtech_physical_psr") ) { - int attackerMod = 0; - int targetMod = 0; - - switch ( attacker.getWeightClass() ) { - case EntityWeightClass.WEIGHT_LIGHT: - attackerMod = 1; - break; - case EntityWeightClass.WEIGHT_MEDIUM: - attackerMod = 2; - break; - case EntityWeightClass.WEIGHT_HEAVY: - attackerMod = 3; - break; - case EntityWeightClass.WEIGHT_ASSAULT: - attackerMod = 4; - break; - } - switch ( target.getWeightClass() ) { - case EntityWeightClass.WEIGHT_LIGHT: - targetMod = 1; - break; - case EntityWeightClass.WEIGHT_MEDIUM: - targetMod = 2; - break; - case EntityWeightClass.WEIGHT_HEAVY: - targetMod = 3; - break; - case EntityWeightClass.WEIGHT_ASSAULT: - targetMod = 4; - break; - } - mod = attackerMod - targetMod; - } - return mod; - } - - /** - * Each mech sinks the amount of heat appropriate to its current heat - * capacity. - */ - private void resolveHeat() { - Report r; - //Heat phase header - addReport(new Report(5000, Report.PUBLIC)); - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - Entity entity = (Entity)i.nextElement(); - if ( null == entity.getPosition() ) { - continue; - } - IHex entityHex = game.getBoard().getHex(entity.getPosition()); - - // heat doesn't matter for non-mechs - if (!(entity instanceof Mech)) { - entity.heatBuildup = 0; - - if(game.getOptions().booleanOption("vehicle_fires") - && entity instanceof Tank) { - resolveVehicleFire((Tank)entity, true); - } - // If the unit is hit with an Inferno, do flaming death test. - else if ( entity.infernos.isStillBurning()) { - doFlamingDeath(entity); - } - continue; - } - else { - // Meks gain heat from inferno hits. - if ( entity.infernos.isStillBurning() ) { - int infernoHeat = entity.infernos.getHeat(); - entity.heatBuildup += infernoHeat; - r = new Report(5010); - r.subject = entity.getId(); - r.add(infernoHeat); - addReport(r); - } - } - - // should we even bother? - if ( entity.isDestroyed() || entity.isDoomed() || - entity.crew.isDoomed() || entity.crew.isDead() ) { - continue; - } - - // engine hits add a lot of heat, provided the engine is on - entity.heatBuildup += entity.getEngineCritHeat(); - - // If a Mek had an active Stealth suite, add 10 heat. - if ( entity instanceof Mech && entity.isStealthActive() ) { - entity.heatBuildup += 10; - r = new Report(5015); - r.subject = entity.getId(); - addReport(r); - } - - // If a Mek is in extreme Temperatures, add or subtract one - // heat per 10 degrees (or fraction of 10 degrees) above or - // below 50 or -30 degrees Celsius - if ( entity instanceof Mech && game.getTemperatureDifference() != 0 - && !((Mech)entity).hasLaserHeatSinks()) { - if (game.getOptions().intOption("temperature") > 50) { - entity.heatBuildup += game.getTemperatureDifference(); - r = new Report(5020); - r.subject = entity.getId(); - r.add(game.getTemperatureDifference()); - addReport(r); - } - else { - entity.heatBuildup -= game.getTemperatureDifference(); - r = new Report(5025); - r.subject = entity.getId(); - r.add(game.getTemperatureDifference()); - addReport(r); - } - } - - // Add +5 Heat if the hex you're in is on fire - // and was on fire for the full round. - if (entityHex != null) { - if (entityHex.terrainLevel(Terrains.FIRE) == 2) { - entity.heatBuildup += 5; - r = new Report(5030); - r.subject = entity.getId(); - addReport(r); - } - int magma = entityHex.terrainLevel(Terrains.MAGMA); - if(magma > 0) { - entity.heatBuildup += 5 * magma; - r = new Report(5032); - r.subject = entity.getId(); - r.add(5 * magma); - addReport(r); - } - } - - // if heatbuildup is negative due to temperature, set it to 0 - // for prettier turnreports - if (entity.heatBuildup < 0) { - entity.heatBuildup = 0; - } - - // add the heat we've built up so far. - entity.heat += entity.heatBuildup; - - // how much heat can we sink? - int tosink = entity.getHeatCapacityWithWater(); - - // should we use a coolant pod? - int safeHeat = entity.hasInfernoAmmo() ? 9 : 13; - int possibleSinkage = ((Mech)entity).getNumberOfSinks(); - for(Enumeration equip=entity.getEquipment();equip.hasMoreElements();) { - Mounted m = (Mounted)equip.nextElement(); - if(m.getType() instanceof AmmoType) { - AmmoType at = (AmmoType)(m.getType()); - if(at.getAmmoType() == AmmoType.T_COOLANT_POD && m.isAmmoUsable()) { - EquipmentMode mode = m.curMode(); - if(mode.equals("dump")) { - r = new Report(5260); - r.subject = entity.getId(); - addReport(r); - m.setShotsLeft(0); - tosink += possibleSinkage; - break; - } - if(mode.equals("safe") && entity.heat - tosink > safeHeat) { - r = new Report(5265); - r.subject = entity.getId(); - addReport(r); - m.setShotsLeft(0); - tosink += possibleSinkage; - break; - } - if(mode.equals("efficient") && entity.heat - tosink >= possibleSinkage) { - r = new Report(5270); - r.subject = entity.getId(); - addReport(r); - m.setShotsLeft(0); - tosink += possibleSinkage; - break; - } - } - } - } - - tosink = Math.min( tosink, entity.heat ); - entity.heat -= tosink; - r = new Report(5035); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(entity.heatBuildup); - r.add(tosink); - r.add(entity.heat); - addReport(r); - entity.heatBuildup = 0; - - // Does the unit have inferno ammo? - if( entity.hasInfernoAmmo() ) { - - // Roll for possible inferno ammo explosion. - if (entity.heat >= 10) { - int boom = 4 + (entity.heat >= 14 ? 2 : 0) + - (entity.heat >= 19 ? 2 : 0) + - (entity.heat >= 23 ? 2 : 0) + - (entity.heat >= 28 ? 2 : 0); - int boomroll = Compute.d6(2); - r = new Report(5040); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(boom); - r.add(boomroll); - - if (boomroll >= boom) { - //avoided - r.choose(true); - addReport(r); - } else { - r.choose(false); - addReport(r); - addReport( explodeInfernoAmmoFromHeat(entity)); - } - } - } // End avoid-inferno-explosion - int autoShutDownHeat; - boolean mtHeat; - - if (game.getOptions().booleanOption("maxtech_heat")) { - autoShutDownHeat = 50; - mtHeat = true; - } else { - autoShutDownHeat = 30; - mtHeat = false; - } - // heat effects: start up - if (entity.heat < autoShutDownHeat && entity.isShutDown()) { - if (entity.heat < 14) { - //automatically starts up again - entity.setShutDown(false); - r = new Report(5045); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - } else { - //roll for startup - int startup = 4 + (((entity.heat - 14) / 4) * 2); - if (mtHeat) { - startup = entity.crew.getPiloting() + startup - 8; - } - int suroll = Compute.d6(2); - r = new Report(5050); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(startup); - r.add(suroll); - if (suroll >= startup) { - //start 'er back up - entity.setShutDown(false); - r.choose(true); - } else { - r.choose(false); - } - addReport(r); - } - } - - // heat effects: shutdown! - // 2003-01-26 JAD - Don't shut down if you just restarted. - else if (entity.heat >= 14 && !entity.isShutDown()) { - if (entity.heat >= autoShutDownHeat) { - r = new Report(5055); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - // add a piloting roll and resolve immediately - game.addPSR(new PilotingRollData - ( entity.getId(), 3, "reactor shutdown" )); - resolvePilotingRolls(); - // okay, now mark shut down - entity.setShutDown(true); - } else if (entity.heat >= 14) { - int shutdown = 4 + (((entity.heat - 14) / 4) * 2); - if (mtHeat) { - shutdown = entity.crew.getPiloting() + shutdown - 8; - } - int sdroll = Compute.d6(2); - r = new Report(5060); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(shutdown); - r.add(sdroll); - if (sdroll >= shutdown) { - //avoided - r.choose(true); - addReport(r); - } else { - //shutting down... - r.choose(false); - addReport(r); - // add a piloting roll and resolve immediately - game.addPSR(new PilotingRollData - ( entity.getId(), 3, "reactor shutdown" )); - resolvePilotingRolls(); - // okay, now mark shut down - entity.setShutDown(true); - } - } - } - - // heat effects: ammo explosion! - if (entity.heat >= 19) { - int boom = 4 + (entity.heat >= 23 ? 2 : 0) + - (entity.heat >= 28 ? 2 : 0); - if (mtHeat) { - boom += - (entity.heat >= 35 ? 2 : 0) + - (entity.heat >= 40 ? 2 : 0) + - (entity.heat >= 45 ? 2 : 0); - // Last line is a crutch; 45 heat should be no roll - // but automatic explosion. - } - if(entity instanceof Mech && ((Mech)entity).hasLaserHeatSinks()) - boom--; - int boomroll = Compute.d6(2); - r = new Report(5065); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(boom); - r.add(boomroll); - if (boomroll >= boom) { - //mech is ok - r.choose(true); - addReport(r); - } else { - //boom! - r.choose(false); - addReport(r); - addReport( explodeAmmoFromHeat(entity)); - } - } - - // heat effects: mechwarrior damage - // N.B. The pilot may already be dead. - int lifeSupportCritCount = 0; - boolean torsoMountedCockpit = ((Mech)entity).getCockpitType() == Mech.COCKPIT_TORSO_MOUNTED; - if ((entity instanceof Mech) - && torsoMountedCockpit) { - lifeSupportCritCount = entity.getHitCriticals(CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_LIFE_SUPPORT, - Mech.LOC_RT); - lifeSupportCritCount += entity.getHitCriticals(CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_LIFE_SUPPORT, - Mech.LOC_LT); - } else { - lifeSupportCritCount = entity.getHitCriticals(CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_LIFE_SUPPORT, - Mech.LOC_HEAD); - } - if (lifeSupportCritCount > 0 - && ((entity.heat >= 15) || (torsoMountedCockpit && (entity.heat >= 0))) - && !entity.crew.isDead() && !entity.crew.isDoomed() - && !entity.crew.isEjected()) { - int heatLimitDesc = 1; - int damageToCrew = 0; - if (entity.heat >= 47 && mtHeat) { - // mechwarrior takes 5 damage - heatLimitDesc = 47; - damageToCrew = 5; - } else if (entity.heat >= 39 && mtHeat) { - // mechwarrior takes 4 damage - heatLimitDesc = 39; - damageToCrew = 4; - } else if (entity.heat >= 32 && mtHeat) { - // mechwarrior takes 3 damage - heatLimitDesc = 32; - damageToCrew = 3; - } else if (entity.heat >= 25) { - // mechwarrior takes 2 damage - heatLimitDesc = 25; - damageToCrew = 2; - } else if (entity.heat >= 15) { - // mechwarrior takes 1 damage - heatLimitDesc = 15; - damageToCrew = 1; - } - if (entity.heat > 0 - && (entity instanceof Mech) - && ((Mech)entity).getCockpitType() == Mech.COCKPIT_TORSO_MOUNTED) - damageToCrew += 1; - r = new Report(5070); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(heatLimitDesc); - r.add(damageToCrew); - addReport(r); - damageCrew(entity, damageToCrew); - } else if (mtHeat && entity.heat >= 32 - && !entity.crew.isDead() && !entity.crew.isDoomed() ) { - // Pilot may take damage from heat if MaxTech option is set - int heatroll = Compute.d6(2); - int avoidNumber = -1; - if (entity.heat >= 47) { - avoidNumber = 12; - } else if (entity.heat >= 39) { - avoidNumber = 10; - } else if (entity.heat >= 32) { - avoidNumber = 8; - } - r = new Report(5075); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(avoidNumber); - r.add(heatroll); - if (heatroll >= avoidNumber) { - //damage avoided - r.choose(true); - } else { - damageCrew(entity, 1); - r.choose(false); - } - addReport(r); - } - - // The pilot may have just expired. - if ( (entity.crew.isDead() || entity.crew.isDoomed() ) - && !entity.crew.isEjected() ) { - r = new Report(5080); - r.subject = entity.getId(); - r.addDesc(entity); - r.newlines = 0; - addReport(r); - addReport( destroyEntity(entity, "crew death", true)); - } - - // With MaxTech Heat Scale, there may occur critical damage - if (mtHeat) { - if (entity.heat >= 36) { - int damageroll = Compute.d6(2); - int damageNumber = -1; - if (entity.heat >= 44) { - damageNumber = 10; - } else if (entity.heat >= 36) { - damageNumber = 8; - } - r = new Report(5085); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(damageNumber); - r.add(damageroll); - r.newlines = 0; - if (damageroll >= damageNumber) { - r.choose(true); - addReport(r); - } else { - r.choose(false); - addReport(r); - addReport(oneCriticalEntity(entity, Compute.d6(2))); - //add an empty report, for linebreaking - r = new Report(1210); - addReport(r); - } - } - } - } - if (vPhaseReport.size() == 1) { - //I guess nothing happened... - addReport(new Report(1205, Report.PUBLIC)); - } - } - - /** - * check to see if unarmored infantry is outside in extreme temperatures - * (crude fix because infantry shouldn't be able to be deployed - * outside of vehicles or buildings, but we can't do that because - * we don't know wether the map has buildings or not or wether the - * player has an apc - */ - private void resolveExtremeTempInfantryDeath() { - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - Entity entity = (Entity)i.nextElement(); - if ( null == entity.getPosition() ) { - continue; - } - IHex entityHex = game.getBoard().getHex(entity.getPosition()); - if (entity instanceof Infantry && - !(entity instanceof BattleArmor) && - game.getTemperatureDifference() > 0 && - !(entityHex.containsTerrain(Terrains.BUILDING)) && - (entity.getTransportId() == Entity.NONE) ) { - Report r = new Report(5090); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - addReport(destroyEntity(entity, "heat/cold", false, false)); - } - } - } - - /** - * Resolve Flaming Death for the given Entity - * @param entity The Entity that may experience flaming death. - */ - private void doFlamingDeath(Entity entity) { - Report r; - int boomroll = Compute.d6(2); - // Infantry are unaffected by fire while they're still swarming. - if ( Entity.NONE != entity.getSwarmTargetId() ) { - return; - } - if (entity.getMovementMode() == IEntityMovementMode.VTOL - && !(entity.infernos.isStillBurning())) { - // VTOLs don't check as long as they are flying higher than - // the burning terrain. TODO: Check for rules conformity (ATPM?) - // according to maxtech, elevation 0 or 1 should be affected, - // this makes sense for level 2 as well - Coords c = entity.getPosition(); - IHex h = game.getBoard().getHex(c.x, c.y); - if (entity.getElevation() > 1) { - return; - } - } - // Battle Armor squads equipped with fire protection - // gear automatically avoid flaming death. - for ( Enumeration iter = entity.getMisc(); iter.hasMoreElements(); ) { - Mounted mount = (Mounted) iter.nextElement(); - EquipmentType equip = mount.getType(); - if ( BattleArmor.FIRE_PROTECTION.equals(equip.getInternalName()) ) { - r = new Report(5095); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - return; - } - } - - //Must roll 8+ to survive... - r = new Report(5100); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(boomroll); - if (boomroll >= 8) { - //phew! - r.choose(true); - addReport(r); - } else { - //eek - r.choose(false); - addReport(r); - addReport( destroyEntity(entity, "fire", false, false)); - } - } - - /** - * Checks to see if any entity has takes 20 damage. If so, they need a - * piloting skill roll. - */ - private void checkFor20Damage() { - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - final Entity entity = (Entity)i.nextElement(); - if (entity instanceof Mech) { - // if this mech has 20+ damage, add another roll to the list. - if (entity.damageThisPhase >= 20) { - if ( game.getOptions().booleanOption("maxtech_round_damage") ) { - int damMod = (entity.damageThisPhase / 20); - int weightMod = 0; - StringBuffer reportStr = new StringBuffer(); - reportStr.append(entity.damageThisPhase) - .append(" damage +").append(damMod); - - switch ( entity.getWeightClass() ) { - case EntityWeightClass.WEIGHT_LIGHT: - weightMod = 1; - break; - - case EntityWeightClass.WEIGHT_MEDIUM: - weightMod = 0; - break; - - case EntityWeightClass.WEIGHT_HEAVY: - weightMod = -1; - break; - - case EntityWeightClass.WEIGHT_ASSAULT: - weightMod = -2; - break; - } - - PilotingRollData damPRD = new PilotingRollData(entity.getId(), damMod + weightMod, reportStr.toString()); - damPRD.setCumulative(false); // see Bug# 811987 for more info - game.addPSR(damPRD); - } else { - game.addPSR(new PilotingRollData(entity.getId(), 1, "20+ damage")); - } - } - } - } - } - - /** - * Checks to see if any non-mech units are standing in fire. Called at the - * end of the movement phase - */ - public void checkForFlamingDeath() { - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - final Entity entity = (Entity)i.nextElement(); - if ( null == entity.getPosition() || - entity instanceof Mech || - entity.isDoomed() || - entity.isDestroyed() || - entity.isOffBoard()) { - continue; - } - final IHex curHex = game.getBoard().getHex(entity.getPosition()); - if (curHex.containsTerrain(Terrains.FIRE) - && entity.getElevation() <= 1) { - if(game.getOptions().booleanOption("vehicle_fires") - && entity instanceof Tank) { - checkForVehicleFire((Tank)entity, false); - } else { - doFlamingDeath(entity); - } - } - } - } - - /** - * Check to see if anyone dies due to being in a vacuum. - */ - private void checkForVacuumDeath() { - Report r; - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - final Entity entity = (Entity)i.nextElement(); - if (null == entity.getPosition() || entity.isOffBoard()) { - // If it's not on the board - aboard something else, for example... - continue; - } - if (entity.doomedInVacuum()) { - r = new Report(6015); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - addReport(destroyEntity(entity, "being in a vacuum where it can't survive", true, true)); - } - } - } - - /** - * Checks to see if any entities are underwater with damaged life support. - * Called during the end phase. - */ - private void checkForSuffocation() { - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - final Entity entity = (Entity)i.nextElement(); - if ( null == entity.getPosition() || - entity.isOffBoard()) { - continue; - } - final IHex curHex = game.getBoard().getHex(entity.getPosition()); - if (entity.getElevation()<0 && (curHex.terrainLevel(Terrains.WATER) > 1 - || (curHex.terrainLevel(Terrains.WATER) == 1 && entity.isProne())) - && entity.getHitCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_LIFE_SUPPORT, Mech.LOC_HEAD) > 0) { - Report r = new Report(6020); - r.subject = entity.getId(); - r.addDesc(entity); - addReport(r); - addReport(damageCrew(entity, 1)); - - } - } - } - - /** - * Resolves all built up piloting skill rolls. - * Used at end of weapons, physical phases. - */ - private void resolvePilotingRolls() { - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - resolvePilotingRolls((Entity)i.nextElement()); - } - game.resetPSRs(); - } - - /** - * Resolves and reports all piloting skill rolls for a single mech. - */ - void resolvePilotingRolls(Entity entity) { - resolvePilotingRolls(entity, false, null, null); - } - void resolvePilotingRolls( Entity entity, boolean moving, - Coords src, Coords dest ) { - // dead units don't need to. - if ( entity.isDoomed() || entity.isDestroyed() ) { - return; - } - Report r; - - // first, do extreme gravity PSR, because non-mechs do these, too - PilotingRollData rollTarget = null; - for (Enumeration i = game.getExtremeGravityPSRs();i.hasMoreElements();) { - final PilotingRollData roll = (PilotingRollData)i.nextElement(); - if (roll.getEntityId() != entity.getId()) { - continue; - } - // found a roll, use it (there can be only 1 per entity) - rollTarget = roll; - game.resetExtremeGravityPSRs(entity); - } - if (rollTarget != null && - rollTarget.getValue() != TargetRoll.CHECK_FALSE) { - // okay, print the info - r = new Report(2180); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(rollTarget.getLastPlainDesc()); - addReport(r); - // roll - final int diceRoll = Compute.d6(2); - r = new Report(2190); - r.subject = entity.getId(); - r.add(rollTarget.getValueAsString()); - r.add(rollTarget.getDesc()); - r.add(diceRoll); - if (diceRoll < rollTarget.getValue()) { - r.choose(false); - addReport(r); - // walking and running, 1 damage per MP used more than we would - // have normally - if (entity.moved == IEntityMovementType.MOVE_WALK - || entity.moved == IEntityMovementType.MOVE_VTOL_WALK - || entity.moved == IEntityMovementType.MOVE_RUN - || entity.moved == IEntityMovementType.MOVE_VTOL_RUN) { - if (entity instanceof Mech) { - int j = entity.mpUsed; - int damage = 0; - while (j > entity.getRunMP(false)) { - j--; - damage++; - } - // Wee, direct internal damage - doExtremeGravityDamage(entity, damage); - } else if (entity instanceof Tank) { - // if we got a pavement bonus, take care of it - int k = entity.gotPavementBonus ? 1 : 0; - if (!entity.gotPavementBonus) { - int j = entity.mpUsed; - int damage = 0; - while (j > entity.getRunMP(false) + k) { - j--; - damage++; - } - doExtremeGravityDamage(entity, damage); - } - } - } - // jumping - if (entity.moved == IEntityMovementType.MOVE_JUMP && entity instanceof Mech) { - // low g, 1 damage for each hex jumped further than - // possible normally - if (game.getOptions().floatOption("gravity") < 1) { - int j = entity.mpUsed; - int damage = 0; - while (j > entity.getOriginalJumpMP()) { - j--; - damage++; - } - // Wee, direct internal damage - doExtremeGravityDamage(entity, damage); - } - // high g, 1 damage for each MP we have less than normally - else if (game.getOptions().floatOption("gravity") > 1) { - int damage = entity.getWalkMP(false) - entity.getWalkMP(); - // Wee, direct internal damage - doExtremeGravityDamage(entity, damage); - } - } - } else { - r.choose(true); - addReport(r); - } - } - // non mechs and prone mechs can now return - if ( !(entity instanceof Mech) || entity.isProne()) { - return; - } - // add all cumulative rolls, count all rolls - Vector rolls = new Vector(); - StringBuffer reasons = new StringBuffer(); - PilotingRollData base = entity.getBasePilotingRoll(); - entity.addPilotingModifierForTerrain(base); - for (Enumeration i = game.getPSRs(); i.hasMoreElements();) { - final PilotingRollData modifier = (PilotingRollData)i.nextElement(); - if (modifier.getEntityId() != entity.getId()) { - continue; - } - // found a roll, add it - rolls.addElement(modifier); - if (reasons.length() > 0) { - reasons.append(", "); - } - reasons.append(modifier.getPlainDesc()); - // only cumulative rolls get added to the base roll - if (modifier.isCumulative()) { - base.append(modifier); - } - } - // any rolls needed? - if (rolls.size() == 0) { - return; - } - // is our base roll impossible? - if (base.getValue() == PilotingRollData.AUTOMATIC_FAIL || base.getValue() == PilotingRollData.IMPOSSIBLE) { - r = new Report(2275); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(rolls.size()); - r.add(reasons.toString()); //international issue - r.add(base.getDesc()); //international issue - addReport(r); - if (moving) { - doEntityFallsInto( entity, src, dest, base ); - } else { - doEntityFall(entity, base); - } - return; - } - // loop thru rolls we do have to make... - r = new Report(2280); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(rolls.size()); - r.add(reasons.toString()); //international issue - addReport(r); - r = new Report(2285); - r.subject = entity.getId(); - r.add(base.getValueAsString()); - r.add(base.getDesc()); //international issue - addReport(r); - for (int i = 0; i < rolls.size(); i++) { - PilotingRollData modifier = (PilotingRollData)rolls.elementAt(i); - PilotingRollData target = base; - r = new Report(2290); - r.subject = entity.getId(); - r.indent(); - r.newlines = 0; - r.add(i+1); - r.add(modifier.getPlainDesc()); //international issue - addReport(r); - if (!modifier.isCumulative()) { - // non-cumulative rolls only happen due to weight class adj. - r = new Report(2295); - r.subject = entity.getId(); - r.newlines = 0; - r.add(modifier.getValueAsString()); //international issue - target = new PilotingRollData(entity.getId()); - target.append(base); - target.append(modifier); - } - int diceRoll = Compute.d6(2); - r = new Report(2300); - r.subject = entity.getId(); - r.add(target.getValueAsString()); - r.add(diceRoll); - if (diceRoll < target.getValue()) { - r.choose(false); - addReport(r); - if (moving) { - doEntityFallsInto( entity, src, dest, base ); - } else { - doEntityFall(entity, base); - } - return; - } else { - r.choose(true); - addReport(r); - } - } - } - - /** - * Inflict damage on a pilot - * - * @param en The Entity who's pilot gets damaged. - * @param damage The int amount of damage. - */ - private Vector damageCrew(Entity en, int damage) { - Vector vDesc = new Vector(); - Pilot crew = en.getCrew(); - - if (!crew.isDead() && !crew.isEjected() && !crew.isDoomed()) { - crew.setHits( crew.getHits() + damage ); - Report r = new Report(6025); - r.subject = en.getId(); - r.indent(2); - r.addDesc(en); - r.add(crew.getName()); - r.add(damage); - r.newlines = 0; - vDesc.addElement(r); - if ( Pilot.DEATH > crew.getHits() ) { - crew.setRollsNeeded( crew.getRollsNeeded() + damage ); - } else if ( !crew.isDoomed() ) { - crew.setDoomed(true); - vDesc.addAll( destroyEntity(en, "pilot death", true)); - } - } - - return vDesc; - } - - /** - * This checks if the mech pilot goes unconscious from the damage he has - * taken this phase. - */ - private void resolveCrewDamage() { - boolean anyRolls = false; - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - final Entity e = (Entity)i.nextElement(); - if (resolveCrewDamage(e, anyRolls)) { - anyRolls = true; - } - } - if (anyRolls) { - addNewLines(); - } - } - - /** - * resolves consciousness rolls for one entity - */ - private boolean resolveCrewDamage(Entity e, boolean anyRolls) { - final int totalHits = e.getCrew().getHits(); - final int rollsNeeded = e.getCrew().getRollsNeeded(); - e.crew.setRollsNeeded(0); - if (!e.isTargetable() || !e.getCrew().isActive() || rollsNeeded == 0) { - return false; - } - for (int hit = totalHits - rollsNeeded + 1; hit <= totalHits; hit++) { - int rollTarget = Compute.getConsciousnessNumber( hit ); - boolean edgeUsed = false; - do { - if (edgeUsed) - e.crew.decreaseEdge(); - int roll = Compute.d6(2); - if ( e.getCrew().getOptions().booleanOption("pain_resistance") ) - roll = Math.min(12, roll + 1); - Report r = new Report(6030); - r.subject = e.getId(); - r.addDesc(e); - r.add(e.getCrew().getName()); - r.add(rollTarget); - r.add(roll); - if (roll >= rollTarget) { - e.crew.setKoThisRound(false); - r.choose(true); - } else { - e.crew.setKoThisRound(true); - r.choose(false); - if (e.crew.hasEdgeRemaining() - && e.crew.getOptions().booleanOption("edge_when_ko")) { - edgeUsed = true; - vPhaseReport.addElement(r); - r = new Report(6520); - r.subject = e.getId(); - r.addDesc(e); - r.add(e.getCrew().getName()); - r.add(e.crew.getOptions().intOption("edge")); - } // if - //return true; - } // else - addReport(r); - } while (e.crew.hasEdgeRemaining() && e.crew.isKoThisRound() - && e.crew.getOptions().booleanOption("edge_when_ko")); - // end of do-while - if (e.crew.isKoThisRound()) { - e.crew.setUnconscious(true); - return true; - } - } - return true; - } - - /** - * Make the rolls indicating whether any unconscious crews wake up - */ - private void resolveCrewWakeUp() { - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - final Entity e = (Entity)i.nextElement(); - - // only unconscious pilots of mechs and protos and MechWarrirs - // can roll to wake up - if ( !e.isTargetable() || !e.crew.isUnconscious() || - e.crew.isKoThisRound() || - !(e instanceof Mech || e instanceof Protomech || e instanceof MechWarrior)) { - continue; - } - int roll = Compute.d6(2); - - if ( e.getCrew().getOptions().booleanOption("pain_resistance") ) - roll = Math.min(12, roll + 1); - - int rollTarget = Compute.getConsciousnessNumber( e.crew.getHits() ); - Report r = new Report(6029); - r.subject = e.getId(); - r.addDesc(e); - r.add(e.getCrew().getName()); - r.add(rollTarget); - r.add(roll); - if (roll >= rollTarget) { - r.choose(true); - e.crew.setUnconscious(false); - } else { - r.choose(false); - } - addReport(r); - } - } - - public Vector damageEntity(Entity te, HitData hit, int damage, boolean ammoExplosion) { - return damageEntity(te, hit, damage, ammoExplosion, 0, false, false); - } - - public Vector damageEntity(Entity te, HitData hit, int damage) { - return damageEntity(te, hit, damage, false, 0, false, false); - } - - public Vector damageEntity(Entity te, HitData hit, int damage, - boolean ammoExplosion, int bFrag) { - return damageEntity(te, hit, damage, ammoExplosion, bFrag, - false, false); - } - - public Vector damageEntity(Entity te, HitData hit, int damage, - boolean ammoExplosion, int bFrag, - boolean damageIS) { - return damageEntity(te, hit, damage, ammoExplosion, bFrag, - damageIS, false); - } - - public Vector damageEntity(Entity te, HitData hit, int damage, - boolean ammoExplosion, int bFrag, - boolean damageIS, boolean areaSatArty) { - return damageEntity (te, hit, damage, ammoExplosion, bFrag, damageIS, - false, true); - } - - /** - * Deals the listed damage to an entity. Returns a vector of Reports - * for the phase report - * - * @param te the target entity - * @param hit the hit data for the location hit - * @param damage the damage to apply - * @param ammoExplosion ammo explosion type damage is applied - * directly to the IS, hurts the pilot, causes auto-ejects, - * and can blow the unit to smithereens - * @param bFrag If 0, nothing; if 1, Fragmentation; if 2, Flechette. - * @param damageIS Should the target location's internal structure be - * damaged directly? - * @param areaSatArty Is the damage from an area saturating artillery - * attack? - * @param throughFront Is the damage coming through the hex the unit - * is facing? - * @return a Vector of Reports - */ - private Vector damageEntity(Entity te, HitData hit, int damage, - boolean ammoExplosion, int bFrag, - boolean damageIS, boolean areaSatArty, - boolean throughFront) { - - Vector vDesc = new Vector(); - Report r; - int te_n = te.getId(); - //This is good for shields if a shield absorps the hit it shouldn't - //effect the pilot. - boolean isHeadHit = (te instanceof Mech - && ((Mech)te).getCockpitType() != Mech.COCKPIT_TORSO_MOUNTED - && hit.getLocation() == Mech.LOC_HEAD); - - // show Locations which have rerolled with Edge - HitData undoneLocation = hit.getUndoneLocation(); - while (undoneLocation != null) { - r = new Report(6500); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - r.addDesc(te); - r.add(te.getLocationAbbr(undoneLocation)); - vDesc.addElement(r); - undoneLocation = undoneLocation.getUndoneLocation(); - } // while - // if edge was uses, give at end overview of remainings - if (hit.getUndoneLocation() != null) { - r = new Report(6510); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - r.addDesc(te); - r.add(te.crew.getOptions().intOption("edge")); - vDesc.addElement(r); - } // if - - boolean autoEject = false; - if (ammoExplosion) { - if (te instanceof Mech) { - Mech mech = (Mech)te; - if (mech.isAutoEject()) { - autoEject = true; - vDesc.addAll(ejectEntity(te, true)); - } - } - } - boolean isBattleArmor = (te instanceof BattleArmor); - boolean isPlatoon = !isBattleArmor && (te instanceof Infantry); - boolean isFerroFibrousTarget = false; - boolean wasDamageIS = false; - boolean tookInternalDamage = damageIS; - IHex te_hex = null; - - boolean hardenedArmor = false; - if ((te instanceof Mech) - && (te.getArmorType() == EquipmentType.T_ARMOR_HARDENED)) - hardenedArmor = true; - int crits = ((hit.getEffect() == HitData.EFFECT_CRITICAL) && (!hardenedArmor)) ? 1 : 0; - int specCrits = ((hit.getEffect() == HitData.EFFECT_CRITICAL) && (hardenedArmor)) ? 1 : 0; - HitData nextHit = null; - - // Some "hits" on a Protomech are actually misses. - if( te instanceof Protomech && - hit.getLocation() == Protomech.LOC_NMISS ) { - r = new Report(6035); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - return vDesc; - } - - // check for critical hit/miss vs. a BA - if( crits > 0 && te instanceof BattleArmor) { - //possible critical miss if the rerolled location isn't alive - if(hit.getLocation() >= te.locations() - || te.getInternal(hit.getLocation()) <= 0) { - r = new Report(6037); - r.add(hit.getLocation()); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - return vDesc; - } - //otherwise critical hit - r = new Report(6225); - r.add(te.getLocationAbbr(hit)); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - - crits = 0; - damage = Math.max(te.getInternal(hit.getLocation()) + - te.getArmor(hit.getLocation()), - damage); - } - - if ((te != null) && - (te.getArmor(hit) > 0) && - ((te.getArmorType() == EquipmentType.T_ARMOR_FERRO_FIBROUS) || - (te.getArmorType() == EquipmentType.T_ARMOR_LIGHT_FERRO) || - (te.getArmorType() == EquipmentType.T_ARMOR_HEAVY_FERRO))) { - isFerroFibrousTarget = true; - } - - // Is the infantry in the open? - if ( isPlatoon && !te.isDestroyed() && !te.isDoomed() ) { - te_hex = game.getBoard().getHex( te.getPosition() ); - if ( te_hex != null && - !te_hex.containsTerrain( Terrains.WOODS ) && - !te_hex.containsTerrain( Terrains.JUNGLE ) && - !te_hex.containsTerrain( Terrains.ROUGH ) && - !te_hex.containsTerrain( Terrains.RUBBLE ) && - !te_hex.containsTerrain( Terrains.SWAMP ) && - !te_hex.containsTerrain( Terrains.BUILDING ) && - !te_hex.containsTerrain(Terrains.FORTIFIED)) { - // PBI. Damage is doubled. - damage = damage * 2; - r = new Report(6040); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - } - } - // Is the infantry in vacuum? - if ( (isPlatoon || isBattleArmor ) && !te.isDestroyed() - && !te.isDoomed() && game.getOptions().booleanOption("vacuum")) { - // PBI. Double damage. - damage = damage * 2; - r = new Report(6041); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - } - // If dealing with fragmentation missiles, - // it does double damage to infantry... - // We're actually going to abuse this for AX-head warheads, too, so as to not add another parameter. - switch (bFrag) - { - case 1: - if (isPlatoon) { - damage *= 2; - r = new Report(6045); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - } - else if (te != null) { - damage = 0; - r = new Report(6050); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - } - break; - case 2: - if (isPlatoon) { - damage *= 2; - r = new Report(6055); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - } - else if ((te != null) && (!isBattleArmor)) { - damage /= 2; - r = new Report(6060); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - } - break; - case 3: - if (isFerroFibrousTarget) { - damage = te.getArmor(hit) >=3?3:te.getArmor(hit); - r = new Report(6061); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - r.add(damage); - vDesc.addElement(r); - } else if (te != null) { - r = new Report(6062); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - } - break; - case 4: - //Incendiary AC ammo does +2 damage to unarmoured infantry - if(isPlatoon ) { - damage += 2; - } - break; - - default: - // We can ignore this. - break; - } - - //save EI status, in case sensors crit destroys it - final boolean eiStatus = te.hasActiveEiCockpit(); - // BA using EI implants receive +1 damage from attacks - if (!(te instanceof Mech) && !(te instanceof Protomech) && eiStatus) { - damage += 1; - } - - // Allocate the damage - while (damage > 0) { - - // let's resolve some damage! - r = new Report(6065); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - r.addDesc(te); - r.add(damage); - if (damageIS) r.messageId = 6070; - r.add(te.getLocationAbbr(hit)); - vDesc.addElement(r); - - // was the section destroyed earlier this phase? - if (te.getInternal(hit) == IArmorState.ARMOR_DOOMED) { - // cannot transfer a through armor crit if so - crits = 0; - } - - //here goes the fun :) - //Shields take damage first then cowls then armor whee - //Shield does not protect from ammo explosions or falls. - if ( !ammoExplosion && !hit.isFallDamage() && te.hasShield() ){ - Mech me = (Mech)te; - int damageNew = me.shieldAbsorptionDamage(damage,hit.getLocation(),hit.isRear()); - //if a shield absorbed the damage then lets tell the world about it. - if ( damageNew != damage){ - int damageDiff = damage - damageNew; - damage = damageNew; - - r = new Report (3530); - r.subject = te_n; - r.indent(3); - r.newlines=0; - r.add(damageDiff); - vDesc.addElement(r); - - if ( damage <= 0 ){ - crits = 0; - specCrits = 0; - isHeadHit = false; - } - - } - } - - // Armored Cowl may absorb some damage from hit - if (te instanceof Mech) { - Mech me = (Mech)te; - if (me.hasCowl() && hit.getLocation()==Mech.LOC_HEAD && - !throughFront ) { - int damageNew = me.damageCowl(damage); - int damageDiff = damage-damageNew; - damage = damageNew; - - r = new Report (3520); - r.subject = te_n; - r.indent(3); - r.newlines=0; - r.add(damageDiff); - vDesc.addElement(r); - } - } - - // Destroy searchlights on 7+ (torso hits on mechs) - boolean spotlightHittable = false; - if (te.hasSpotlight()) { - spotlightHittable = true; - int loc = hit.getLocation(); - if (te instanceof Mech) { - if (loc != Mech.LOC_CT && loc != Mech.LOC_LT && loc != Mech.LOC_RT) { - spotlightHittable = false; - } - } else if (te instanceof Tank) { - if (loc != Tank.LOC_FRONT && loc != Tank.LOC_RIGHT && loc != Tank.LOC_LEFT) { - spotlightHittable = false; - } - } - if (spotlightHittable) { - int spotroll = Compute.d6(2); - r = new Report(6072); - r.indent(2); - r.subject = te_n; - r.add(spotroll); - vDesc.addElement(r); - if (spotroll >= 7) { - r = new Report(6071); - r.subject = te_n; - r.indent(2); - vDesc.addElement(r); - te.setSpotlightState(false); - te.setSpotlight(false); - } - } - } - - // Does an exterior passenger absorb some of the damage? - if (!damageIS) { - int nLoc = hit.getLocation(); - Entity passenger = te.getExteriorUnitAt( nLoc, hit.isRear() ); - // Does an exterior passenger absorb some of the damage? - if ( !ammoExplosion && null != passenger - && !passenger.isDoomed() ) { - // Yup. Roll up some hit data for that passenger. - r = new Report(6075); - r.subject = passenger.getId(); - r.indent(3); - r.addDesc(passenger); - vDesc.addElement(r); - - HitData passHit = passenger.getTrooperAtLocation - ( hit, te); - - // How much damage will the passenger absorb? - int absorb = 0; - HitData nextPassHit = passHit; - do { - if ( 0 < passenger.getArmor( nextPassHit ) ) { - absorb += passenger.getArmor( nextPassHit ); - } - if ( 0 < passenger.getInternal( nextPassHit ) ) { - absorb += passenger.getInternal( nextPassHit ); - } - nextPassHit = passenger.getTransferLocation( nextPassHit ); - } while ( damage > absorb && nextPassHit.getLocation() >= 0 ); - - // Damage the passenger. - vDesc.addAll( damageEntity(passenger, passHit, damage)); - - // Did some damage pass on? - if ( damage > absorb ) { - // Yup. Remove the absorbed damage. - damage -= absorb; - r = new Report(6080); - r.subject = te_n; - r.indent(1); - r.add(damage); - r.addDesc(te); - vDesc.addElement(r); - } else { - // Nope. Return our description. - return vDesc; - } - - } // End nLoc-has-exterior-passenger - - // is this a mech dumping ammo being hit in the rear torso? - boolean bTorso = (nLoc == Mech.LOC_CT || nLoc == Mech.LOC_RT || - nLoc == Mech.LOC_LT); - if (te instanceof Mech && hit.isRear() && bTorso) { - for (Enumeration e = te.getAmmo(); e.hasMoreElements(); ) { - Mounted mAmmo = (Mounted)e.nextElement(); - if (mAmmo.isDumping() && !mAmmo.isDestroyed() && - !mAmmo.isHit()) { - // doh. explode it - vDesc.addAll( explodeEquipment(te, mAmmo.getLocation(), mAmmo) ); - mAmmo.setHit(true); - } - } - } - } - - // is there armor in the location hit? - if (!ammoExplosion && te.getArmor(hit) > 0 && !damageIS) { - int tmpDamageHold = -1; - - // If the target has hardened armor, we need to adjust damage. - if (hardenedArmor) { - tmpDamageHold = damage; - damage /= 2; - damage += (tmpDamageHold%2); - } - - if (te.getArmor(hit) > damage) { - // armor absorbs all damage - te.setArmor(te.getArmor(hit) - damage, hit); - if (tmpDamageHold >= 0) - te.damageThisPhase += tmpDamageHold; - else - te.damageThisPhase += damage; - damage = 0; - r = new Report(6085); - r.subject = te_n; - r.newlines = 0; - if(spotlightHittable)r.indent(3); - r.add(te.getArmor(hit)); - vDesc.addElement(r); - } else { - // damage goes on to internal - int absorbed = Math.max(te.getArmor(hit), 0); - te.setArmor(IArmorState.ARMOR_DESTROYED, hit); - if (tmpDamageHold >= 0) - te.damageThisPhase += 2*absorbed; - else - te.damageThisPhase += absorbed; - damage -= absorbed; - r = new Report(6090); - r.subject = te_n; - r.newlines = 0; - if(spotlightHittable)r.indent(3); - vDesc.addElement(r); - if (te instanceof GunEmplacement) { - // gun emplacements have no internal, - // destroy the section - destroyLocation(te, hit.getLocation()); - r = new Report(6115); - r.subject = te_n; - r.newlines = 0; - vDesc.addElement(r); - - if (te.getTransferLocation(hit).getLocation() == - Entity.LOC_DESTROYED) { - vDesc.addAll( - destroyEntity(te, - "damage", - false)); - } - } - } - - // If it has hardened armor, now we need to "correct" any remaining damage. - if (tmpDamageHold > 0) { - if (hardenedArmor) { - damage *= 2; - damage -= (tmpDamageHold%2); - } - } - } - - // is there damage remaining? - if (damage > 0) { - tookInternalDamage = true; - // is there internal structure in the location hit? - if (te.getInternal(hit) > 0) { - // Triggers a critical hit on Vehicles and Mechs. - if ( !isPlatoon && !isBattleArmor ) { - crits++; - } - - // Now we need to consider alternate structure types! - int tmpDamageHold = -1; - if ((te instanceof Mech) && (((Mech)te).hasCompositeStructure())) { - tmpDamageHold = damage; - damage *= 2; - } - if ((te instanceof Mech) && (((Mech)te).hasReinforcedStructure())) { - tmpDamageHold = damage; - damage /= 2; - damage += (tmpDamageHold%2); - } - - if (te.getInternal(hit) > damage) { - // internal structure absorbs all damage - te.setInternal(te.getInternal(hit) - damage, hit); - te.damageThisPhase += damage; - damage = 0; - r = new Report(1210); - r.subject = te_n; - r.newlines = 0; - // Infantry platoons have men not "Internals". - if ( isPlatoon ) { - r.messageId = 6095; - } else { - r.messageId = 6100; - } - r.add(te.getInternal(hit)); - vDesc.addElement(r); - } else { - // damage transfers, maybe - int absorbed = Math.max(te.getInternal(hit), 0); - - // Handle Protomech pilot damage - // due to location destruction - if ( te instanceof Protomech ) { - int hits = Protomech.POSSIBLE_PILOT_DAMAGE[hit.getLocation()] - - ((Protomech)te).getPilotDamageTaken(hit.getLocation()); - if ( hits > 0 ) { - vDesc.addAll( damageCrew( te, hits )); - ((Protomech)te).setPilotDamageTaken - (hit.getLocation(), - Protomech.POSSIBLE_PILOT_DAMAGE[hit.getLocation()]); - } - } - - // Platoon, Trooper, or Section destroyed message - r = new Report(1210); - r.subject = te_n; - r.newlines = 0; - if ( isPlatoon ) { - // Infantry have only one section, and - // are therefore destroyed. - r.messageId = 6105; - } else if ( isBattleArmor ) { - r.messageId = 6110; - } else { - r.messageId = 6115; - } - vDesc.addElement(r); - - // If a sidetorso got destroyed, and the - // corresponding arm is not yet destroyed, add - // it as a club to that hex (p.35 BMRr) - if (te instanceof Mech && - ((hit.getLocation() == Mech.LOC_RT && - te.getInternal(Mech.LOC_RARM) > 0) || - (hit.getLocation() == Mech.LOC_LT && - te.getInternal(Mech.LOC_LARM) > 0))) { - int blownOffLocation = -1; //good initial value? - if (hit.getLocation() == Mech.LOC_RT) { - blownOffLocation = Mech.LOC_RARM; - } else { - blownOffLocation = Mech.LOC_LARM; - } - r = new Report(6120); - r.subject = te_n; - r.add(te.getLocationName(blownOffLocation)); - r.newlines = 0; - vDesc.addElement(r); - IHex h = game.getBoard().getHex(te.getPosition()); - if (te instanceof BipedMech) { - if (!h.containsTerrain( Terrains.ARMS)) { - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.ARMS, 1)); - } - else h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.ARMS, h.terrainLevel(Terrains.ARMS)+1)); - } else if (!h.containsTerrain( Terrains.LEGS)) { - h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.LEGS, 1)); - } else h.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.LEGS, h.terrainLevel(Terrains.LEGS)+1)); - sendChangedHex(te.getPosition()); - } - - // Level 3 mechanized BA, troopers riding on a location - // all die when the location is destroyed. - if(game.getOptions().booleanOption("maxtech_mechanized_ba") && - te instanceof Mech) { - Entity passenger = te.getExteriorUnitAt( hit.getLocation(), hit.isRear() ); - if(null != passenger && !passenger.isDoomed()) { - HitData passHit = passenger.getTrooperAtLocation( hit, te); - passHit.setEffect(HitData.EFFECT_CRITICAL); //ensures a kill - if(passenger.getInternal(passHit) > 0) { - vDesc.addAll(damageEntity(passenger, passHit, damage)); - } - passHit = new HitData(hit.getLocation(), !(hit.isRear())); - passHit = passenger.getTrooperAtLocation( passHit, te); - passHit.setEffect(HitData.EFFECT_CRITICAL); //ensures a kill - if(passenger.getInternal(passHit) > 0) { - vDesc.addAll(damageEntity(passenger, passHit, damage)); - } - } - } - - // Destroy the location. - destroyLocation(te, hit.getLocation()); - te.damageThisPhase += absorbed; - damage -= absorbed; - - // Now we need to consider alternate structure types! - if (tmpDamageHold > 0) { - if (((Mech)te).hasCompositeStructure()) { - // If there's a remainder, we can actually ignore it. - damage /= 2; - } else if (((Mech)te).hasReinforcedStructure()) { - damage *= 2; - damage -= (tmpDamageHold%2); - } - } - - if (te instanceof Mech && - (hit.getLocation() == Mech.LOC_RT || - hit.getLocation() == Mech.LOC_LT)) { - - boolean engineExploded = false; - - - int numEngineHits = 0; - numEngineHits += - te.getHitCriticals(CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_ENGINE, - Mech.LOC_CT); - numEngineHits += - te.getHitCriticals(CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_ENGINE, - Mech.LOC_RT); - numEngineHits += - te.getHitCriticals(CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_ENGINE, - Mech.LOC_LT); - - engineExploded = checkEngineExplosion(te, vDesc, numEngineHits); - if ( !engineExploded && numEngineHits > 2 ) { - // third engine hit - vDesc.addAll( destroyEntity(te, "engine destruction")); - if ( game.getOptions().booleanOption("auto_abandon_unit") ) - vDesc.addAll(abandonEntity(te)); - - } - } - - if (te instanceof VTOL && hit.getLocation() == VTOL.LOC_ROTOR) { - //if rotor is destroyed, movement goes bleh. - //I think this will work? - hit.setEffect(HitData.EFFECT_VEHICLE_MOVE_DESTROYED); - - } - } - } if (te.getInternal(hit) <= 0) { - // internal structure is gone, what are the transfer potentials? - nextHit = te.getTransferLocation(hit); - if (nextHit.getLocation() == Entity.LOC_DESTROYED) { - if (te instanceof Mech) { - // add all non-destroyed engine crits - te.engineHitsThisRound += te.getGoodCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_ENGINE, hit.getLocation()); - // and substract those that where hit previously this round - // hackish, but works. - te.engineHitsThisRound -= te.getHitCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_ENGINE, hit.getLocation()); - } - - boolean engineExploded = false; - - engineExploded = checkEngineExplosion(te, vDesc, te.engineHitsThisRound); - - if ( !engineExploded && !((te instanceof VTOL) && hit.getLocation() == VTOL.LOC_ROTOR)) { - // Entity destroyed. Ammo explosions are - // neither survivable nor salvagable. - // Only ammo explosions in the CT are devastating. - vDesc.addAll( destroyEntity( te, "damage", - !ammoExplosion, - !( (ammoExplosion || areaSatArty) && - hit.getLocation() == - Mech.LOC_CT ) ) ); - // If the head is destroyed, kill the crew. - if (hit.getLocation() == Mech.LOC_HEAD || - (hit.getLocation() == Mech.LOC_CT && ((ammoExplosion && !autoEject) || areaSatArty))) { - te.getCrew().setDoomed(true); - } - if (game.getOptions().booleanOption("auto_abandon_unit")) { - vDesc.addAll(abandonEntity(te)); - } - } - - // nowhere for further damage to go - damage = 0; - } else if ( nextHit.getLocation() == Entity.LOC_NONE ) { - // Rest of the damage is wasted. - damage = 0; - } else if (ammoExplosion && te.locationHasCase(hit.getLocation())) { - // Remaining damage prevented by CASE - r = new Report(6125); - r.subject = te_n; - r.add(damage); - r.indent(3); - r.newlines = 0; - vDesc.addElement(r); - - // ... but page 21 of the Ask The Precentor Martial FAQ - // www.classicbattletech.com/PDF/AskPMForumArchiveandFAQ.pdf - // says that the damage counts for making PSRs. - te.damageThisPhase += damage; - - // The target takes no more damage from the explosion. - damage = 0; - } else if (damage > 0) { - // remaining damage transfers - r = new Report(6130); - r.subject = te_n; - r.indent(2); - r.newlines = 0; - r.add(damage); - r.add(te.getLocationAbbr(nextHit)); - vDesc.addElement(r); - - // If there are split weapons in this location, mark it as - // destroyed, even if it took no criticals. - for (Enumeration weapons=te.getWeapons(); weapons.hasMoreElements(); ) { - Mounted m = (Mounted)weapons.nextElement(); - if (m.isSplit()) { - if (m.getLocation() == hit.getLocation() || - m.getLocation() == nextHit.getLocation()) { - te.setWeaponDestroyed(m); - } - } - } - } - } - } else if (hit.getSpecCritMod() < 0) { - // If there ISN'T any armor left but we did damage, then there's a chance of a crit, using Armor Piercing. - specCrits++; - } - // check for breaching - vDesc.addAll( breachCheck(te, hit.getLocation(), null)); - - // resolve special results - if (hit.getEffect() == HitData.EFFECT_VEHICLE_MOVE_DAMAGED) { - r = new Report(6135); - r.subject = te_n; - r.indent(3); - vDesc.addElement(r); - int nMP = te.getOriginalWalkMP(); - if (nMP > 0) { - te.setOriginalWalkMP(nMP - 1); - - if (te.getOriginalWalkMP()==0) { - // From http://www.classicbattletech.com/PDF/AskPMForumArchiveandFAQ.pdf - // page 19, tanks are only immobile if they take that critical hit. - // ((Tank)te).immobilize(); - - // Hovercraft reduced to 0MP over water sink - if ( te.getMovementMode() == IEntityMovementMode.HOVER && - game.getBoard().getHex( te.getPosition() ).terrainLevel(Terrains.WATER) > 0 - &&!(game.getBoard().getHex( te.getPosition() ).containsTerrain(Terrains.ICE))) { - vDesc.addAll( destroyEntity(te, "a watery grave", false) ); - } - } - } - } else if (hit.getEffect() == HitData.EFFECT_VEHICLE_MOVE_DESTROYED) { - r = new Report(6140); - r.subject = te_n; - r.indent(3); - vDesc.addElement(r); - ((Tank)te).immobilize(); - // Does the hovercraft sink? - te_hex = game.getBoard().getHex( te.getPosition() ); - if ( te.getMovementMode() == IEntityMovementMode.HOVER && - te_hex.terrainLevel(Terrains.WATER) > 0 && - !(te_hex.containsTerrain(Terrains.ICE))) { - vDesc.addAll( destroyEntity(te, "a watery grave", false) ); - } - if(te instanceof VTOL) { - Report.addNewline(vDesc); - //report problem: add tab - vDesc.addAll( crashVTOL((VTOL)te)); - } - } else if (hit.getEffect() == HitData.EFFECT_VEHICLE_TURRETLOCK) { - r = new Report(6145); - r.subject = te_n; - r.indent(3); - vDesc.addElement(r); - ((Tank)te).lockTurret(); - } - else if (hit.getEffect() == - HitData.EFFECT_GUN_EMPLACEMENT_WEAPONS) { - r = new Report(6146); - r.subject = te_n; - r.indent(3); - vDesc.addElement(r); - Enumeration weapons = te.getWeapons(); - while (weapons.hasMoreElements()) { - ((Mounted) weapons.nextElement()).setDestroyed(true); - } - } - else if (hit.getEffect() == HitData.EFFECT_GUN_EMPLACEMENT_TURRET) { - r = new Report(6147); - r.subject = te_n; - r.indent(3); - vDesc.addElement(r); - ((GunEmplacement)te).setTurretLocked(true); - } - else if (hit.getEffect() == HitData.EFFECT_GUN_EMPLACEMENT_CREW) { - r = new Report(6148); - r.subject = te_n; - r.indent(3); - vDesc.addElement(r); - ((GunEmplacement)te).getCrew().setDoomed(true); - } - // roll all critical hits against this location - // unless the section destroyed in a previous phase? - if (te.getInternal(hit) != IArmorState.ARMOR_DESTROYED) { - for (int i = 0; i < crits; i++) { - ((Report) vDesc.elementAt(vDesc.size() - 1)).newlines++; - vDesc.addAll( criticalEntity(te, hit.getLocation(), hit.glancingMod()) ); - } - crits = 0; - - for (int i = 0; i < specCrits; i++) { - ((Report) vDesc.elementAt(vDesc.size() - 1)).newlines++; - vDesc.addAll( criticalEntity(te, hit.getLocation(), (hardenedArmor?-2:hit.getSpecCritMod())+hit.glancingMod()) ); - } - specCrits = 0; - } - - if (isHeadHit) { - Report.addNewline(vDesc); - vDesc.addAll( damageCrew(te, 1) ); - } - - // loop to next location - hit = nextHit; - if (damageIS) { - wasDamageIS = true; - damageIS = false; - } - } - //Mechs using EI implants take pilot damage each time a hit - //inflicts IS damage - if (tookInternalDamage - && ((te instanceof Mech) || (te instanceof Protomech)) - && te.hasActiveEiCockpit()) { - Report.addNewline(vDesc); - int roll = Compute.d6(2); - r = new Report(5075); - r.subject = te.getId(); - r.addDesc(te); - r.add(7); - r.add(roll); - r.choose(roll>=7); - r.indent(2); - vDesc.add(r); - if(roll < 7) { - vDesc.addAll( damageCrew(te, 1) ); - } - } - - //damage field guns on infantry platoons if there arent enough men left to man it - if(isPlatoon) { - float tons = 0.0f; - for(Enumeration weapons = te.getWeapons();weapons.hasMoreElements();) { - Mounted weap = weapons.nextElement(); - WeaponType wtype = (WeaponType)weap.getType(); - if(!wtype.hasFlag(WeaponType.F_INFANTRY)) { - tons += wtype.getTonnage(te); - if(tons > te.getInternal(Infantry.LOC_INFANTRY)) { - weap.setDestroyed(true); - } - } - } - } - - //This flag indicates the hit was directly to IS - if (wasDamageIS) { - Report.addNewline(vDesc); - } - return vDesc; - } - - /** - * Check to see if the entity's engine explodes. - * Rules for ICE explosions are different to fusion engines. - * @param en - the Entity in question. - * This value must not be null. - * @param vDesc - the Vector that this function should - * add its Reports to. It may be empty, but not - * null. - * @param hits - the number of criticals on the engine - * @return true if the unit's engine exploded, - * false if not. - */ - private boolean checkEngineExplosion(Entity en, Vector vDesc, int hits) { - if (!(en instanceof Mech) - && !(en instanceof QuadMech) - && !(en instanceof BipedMech)) { - return false; - } - if(en.isDoomed() || en.isDestroyed()) - return false; - Mech mech = (Mech)en; - - //ICE can always explode and roll every time hit - if (mech.getEngine().isFusion() - && (!game.getOptions().booleanOption("engine_explosions") - || en.rolledForEngineExplosion - || en.engineHitsThisRound < 2) ) - return false; - int explosionBTH = 12; - if(!mech.getEngine().isFusion()) { - switch (hits) { - case 0: - return false; - case 1: - explosionBTH = 10; - break; - case 2: - explosionBTH = 7; - break; - case 3: - default: - explosionBTH = 4; - break; - } - } - int explosionRoll = Compute.d6(2); - boolean didExplode = explosionRoll >= explosionBTH; - - Report r; - r = new Report(6150); - r.subject = en.getId(); - r.indent(2); - r.addDesc(en); - r.add(en.engineHitsThisRound); - vDesc.addElement(r); - r = new Report(6155); - r.subject = en.getId(); - r.indent(2); - r.add(explosionBTH); - r.add(explosionRoll); - vDesc.addElement(r); - en.rolledForEngineExplosion = true; - - if ( !didExplode ) { - //whew! - r = new Report(6160); - r.subject = en.getId(); - r.indent(2); - vDesc.addElement(r); - } else { - r = new Report(6165, Report.PUBLIC); - r.subject = en.getId(); - r.indent(2); - vDesc.addElement(r); - vDesc.addAll( destroyEntity(en, "engine explosion", false, false)); - //kill the crew - en.getCrew().setDoomed(true); - - //This is a hack so MM.NET marks the mech as not salvageable - if ( en instanceof Mech ) - destroyLocation(en, Mech.LOC_CT); - - //Light our hex on fire - final IHex curHex = game.getBoard().getHex(en.getPosition()); - - if ((null != curHex) - && !curHex.containsTerrain(Terrains.FIRE) - && (curHex.containsTerrain(Terrains.WOODS) - || curHex.containsTerrain(Terrains.JUNGLE))) { - curHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - r = new Report(6170, Report.PUBLIC); - r.subject = en.getId(); - r.indent(2); - r.add(en.getPosition().getBoardNum()); - vDesc.addElement(r); - sendChangedHex(en.getPosition()); - } - - //ICE explosions don't hurt anyone else, but fusion do - if (mech.getEngine().isFusion()) { - //Nuke anyone that is in our hex - Enumeration entitesWithMe = game.getEntities(en.getPosition()); - Hashtable entitesHit = new Hashtable(); - - entitesHit.put(en, en); - - while (entitesWithMe.hasMoreElements()) { - Entity entity = (Entity)entitesWithMe.nextElement(); - if ( entity.equals(en) ) - continue; - vDesc.addAll( destroyEntity(entity, "engine explosion proximity", false, false)); - // Kill the crew - entity.getCrew().setDoomed(true); - entitesHit.put(entity, entity); - } - - //Now we damage people near us - int engineRating = en.getEngine().getRating(); - int[] damages = { 999, (engineRating / 10), (engineRating / 20), (engineRating / 40) }; - Vector entites = game.getEntitiesVector(); - for (int i = 0; i < entites.size(); i++) { - Entity entity = (Entity)entites.elementAt(i); - - if (entitesHit.containsKey(entity)) - continue; - - if ( entity.isDoomed() || entity.isDestroyed() || !entity.isDeployed() ) - continue; - - int range = en.getPosition().distance(entity.getPosition()); - - if ( range > 3 ) - continue; - - int damage = damages[range]; - - r = new Report(6175); - r.subject = entity.getId(); - r.indent(2); - r.addDesc(entity); - r.add(damage); - r.newlines = 0; - vDesc.addElement(r); - - while (damage > 0) { - int cluster = Math.min(5, damage); - HitData hit = entity.rollHitLocation(ToHitData.HIT_NORMAL, Compute.targetSideTable(en, entity)); - vDesc.addAll( damageEntity(entity, hit, cluster)); - damage -= cluster; - } - Report.addNewline(vDesc); - } - } - } - - return didExplode; - } - - /** - * Apply a single critical hit. - * - * The following private member of Server are accessed from this function, - * preventing it from being factored out of the Server class: - * destroyEntity() - * destroyLocation() - * checkEngineExplosion() - * damageCrew() - * explodeEquipment() - * game - * - * @param en the Entity that is being damaged. - * This value may not be null. - * @param loc the int location of critical hit. - * This value may be Entity.NONE for hits - * to Tanks and for hits to a Protomech - * torso weapon. - * @param cs the CriticalSlot being damaged. - * This value may not be null. - * For critical hits on a Tank, the index of - * the slot should be the index of the critical hit table. - * @param secondaryEffects the boolean flag that indicates - * whether to allow critical hits to cause secondary effects (such - * as triggering an ammo explosion, sending hovercraft to watery - * graves, or damaging Protomech torso weapons). This value is - * normally true, but it will be false - * when the hit is being applied from a saved game or scenario. - */ - public Vector applyCriticalHit( Entity en, int loc, CriticalSlot cs, - boolean secondaryEffects ) { - Vector vDesc = new Vector(); - Report r; - - // Handle hits on "critical slots" of tanks. - if ( en instanceof Tank ) { - Tank tank = (Tank)en; - VTOL vtol = null; - if (en instanceof VTOL) - vtol = (VTOL)en; - r = new Report(6180); - r.subject = en.getId(); - r.indent(3); - r.newlines = 0; - vDesc.addElement(r); - switch ( cs.getIndex() ) { - case 1 : //crew stunned, or killed if VTOL - if (vtol == null) { - r = new Report(6185); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - // Carried units can't unload from a stunned transport. - // Units that escape a transport don't need to un-stun. - tank.stunCrew(); - } else { //VTOL's suffer crew death instead - r = new Report(6190); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - vDesc.addAll( - destroyEntity(vtol, "crew death", true)); - en.getCrew().setDoomed(true); - vDesc.addAll( crashVTOL(vtol)); - } - break; - case 2 : //this one's ridiculous. the 'main weapon' jams. - Mounted mWeap = tank.getMainWeapon(); - if (mWeap == null) { //no main weapon, no crit - r = new Report(6195); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - } - else { - r = new Report(6200); - r.subject = en.getId(); - r.add(mWeap.getName()); - int jamTurns = tank.getJammedTurns() + 1; - if ( jamTurns > 1 ) { - r.messageId = 6205; - r.add(jamTurns); - } - r.newlines = 0; - vDesc.addElement(r); - tank.setJammedTurns( jamTurns ); - } - break; - case 3 : //engine destroyed - r = new Report(6210); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - tank.immobilize(); - // Does the hovercraft sink? - // Sinking immobile hovercraft is a secondary effect - // and does not occur when loading from a scenario. - if ( secondaryEffects ) { - IHex te_hex = game.getBoard().getHex( en.getPosition() ); - if (vtol == null) { - if ( en.getMovementMode() == IEntityMovementMode.HOVER - && te_hex.terrainLevel(Terrains.WATER) > 0 - && !(te_hex.containsTerrain(Terrains.ICE))) { - vDesc.addAll( - destroyEntity(en,"a watery grave", false)); - } - } else { //VTOLs may land or crash - //TODO: Nothing if VTOL is landed. If over clear, - // paved, rough, or building, VTOL must make PSR - // to land or crash. Other terrain is automatic - // crash. - Report.addNewline(vDesc); - //report problem: add 3 tabs - vDesc.addAll( crashVTOL(vtol)); - } - } - break; - case 4 : //crew killed - r = new Report(6190); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - vDesc.addAll( - destroyEntity(en, "crew death", true)); - en.getCrew().setDoomed(true); - if (vtol != null) { //VTOL's crash too - Report.addNewline(vDesc); - //report problem: add 3 tabs - vDesc.addAll( crashVTOL(vtol)); - } - break; - case 5 : //fuel tank/engine shielding, vehicle explodes - r = new Report(6215); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - if (vtol == null) { - vDesc.addAll(destroyEntity(en, "fuel tank explosion", false, false)); - } else { //VTOL's explode and scatter burning fuel - Report.addNewline(vDesc); - //report problem: add 3 tabs - vDesc.addAll( explodeVTOL(vtol)); - } - en.getCrew().setDoomed(true); - break; - case 6 : //power plant hit, vehicle explodes - r = new Report(6220); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - boolean hasCASE = en.locationHasCase(Tank.LOC_BODY); - if (vtol == null) { - vDesc.addAll(destroyEntity(en, "power plant destruction", hasCASE, hasCASE)); - } else { //VTOL's explode and scatter burning fuel - Report.addNewline(vDesc); - //report problem: add 3 tabs - vDesc.addAll( explodeVTOL(vtol)); - } - en.getCrew().setDoomed(!hasCASE); - break; - } - - } // End entity-is-tank - - // Handle critical hits on system slots. - else if ( CriticalSlot.TYPE_SYSTEM == cs.getType() ) { - cs.setHit(true); - if (en instanceof Protomech) { - int numHit=((Protomech)en).getCritsHit(loc); - if ( cs.getIndex() != Protomech.SYSTEM_TORSO_WEAPON_A && - cs.getIndex() != Protomech.SYSTEM_TORSO_WEAPON_B ) { - r = new Report(6225); - r.subject = en.getId(); - r.indent(3); - r.newlines = 0; - r.add(Protomech.systemNames[cs.getIndex()]); - vDesc.addElement(r); - } - switch (cs.getIndex()) { - case Protomech.SYSTEM_HEADCRIT: - if (2==numHit) { - r = new Report(6230); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - destroyLocation(en, loc); - } - break; - case Protomech.SYSTEM_ARMCRIT: - if (2==numHit) { - r = new Report(6235); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - destroyLocation(en,loc); - } - break; - case Protomech.SYSTEM_LEGCRIT: - if (3==numHit) { - r = new Report(6240); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - destroyLocation(en,loc); - } - break; - case Protomech.SYSTEM_TORSOCRIT: - if (3==numHit) { - vDesc.addAll( - destroyEntity(en, "torso destruction")); - } - // Torso weapon hits are secondary effects and - // do not occur when loading from a scenario. - else if ( secondaryEffects ) { - int tweapRoll=Compute.d6(1); - CriticalSlot newSlot = null; - switch (tweapRoll) { - case 1: - case 2: - newSlot = new CriticalSlot - ( CriticalSlot.TYPE_SYSTEM, - Protomech.SYSTEM_TORSO_WEAPON_A ); - vDesc.addAll( - applyCriticalHit(en, Entity.NONE, - newSlot, secondaryEffects)); - break; - case 3: - case 4: - newSlot = new CriticalSlot - ( CriticalSlot.TYPE_SYSTEM, - Protomech.SYSTEM_TORSO_WEAPON_B ); - vDesc.addAll( - applyCriticalHit(en, Entity.NONE, - newSlot, secondaryEffects)); - break; - case 5: - case 6: - //no effect - } - } - break; - case Protomech.SYSTEM_TORSO_WEAPON_A: - Mounted weaponA =( (Protomech) en ).getTorsoWeapon(true); - if ( null != weaponA ) { - weaponA.setHit(true); - r = new Report(6245); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - } - break; - case Protomech.SYSTEM_TORSO_WEAPON_B: - Mounted weaponB = ( (Protomech) en ).getTorsoWeapon(false); - if ( null != weaponB ) { - weaponB.setHit(true); - r = new Report(6250); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - } - break; - - - } // End switch( cs.getType() ) - - // Shaded hits cause pilot damage. - if ( ((Protomech)en).shaded(loc, numHit) ) { - // Destroyed Protomech sections have - // already damaged the pilot. - int pHits = - Protomech.POSSIBLE_PILOT_DAMAGE[ loc ] - - ((Protomech)en).getPilotDamageTaken( loc ); - if ( Math.min(1, pHits) > 0 ) { - Report.addNewline(vDesc); - vDesc.addAll( - damageCrew(en, 1)); - pHits = 1 + ((Protomech)en) - .getPilotDamageTaken( loc ); - ((Protomech)en).setPilotDamageTaken - ( loc, pHits ); - } - } // End have-shaded-hit - - } // End entity-is-protomech - else { - r = new Report(6225); - r.subject = en.getId(); - r.indent(3); - r.add(((Mech)en).getSystemName(cs.getIndex())); - r.newlines = 0; - vDesc.addElement(r); - switch(cs.getIndex()) { - case Mech.SYSTEM_COCKPIT : - // Don't kill a pilot multiple times. - if ( Pilot.DEATH > en.getCrew().getHits() ) { - // boink! - en.getCrew().setDoomed(true); - Report.addNewline(vDesc); - vDesc.addAll( - destroyEntity(en, "pilot death", true)); - } - break; - case Mech.SYSTEM_ENGINE : - en.engineHitsThisRound++; - - boolean engineExploded = false; - - int numEngineHits = 0; - numEngineHits += en.getHitCriticals - (CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_ENGINE, Mech.LOC_CT); - numEngineHits += en.getHitCriticals - (CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_ENGINE, Mech.LOC_RT); - numEngineHits += en.getHitCriticals - (CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_ENGINE, Mech.LOC_LT); - - engineExploded = checkEngineExplosion(en, vDesc, numEngineHits); - if ( !engineExploded && numEngineHits > 2 ) { - // third engine hit - vDesc.addAll( - destroyEntity(en, "engine destruction")); - if (game.getOptions().booleanOption("auto_abandon_unit")) { - vDesc.addAll(abandonEntity(en)); - } - } - break; - case Mech.SYSTEM_GYRO : - if (en.getHitCriticals(CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_GYRO, loc) > 1) { - // gyro destroyed - game.addPSR( new PilotingRollData - (en.getId(), PilotingRollData.AUTOMATIC_FAIL, - 3, "gyro destroyed") ); - } else { - // first gyro hit - game.addPSR( new PilotingRollData - (en.getId(), 3, "gyro hit") ); - } - break; - case Mech.ACTUATOR_UPPER_LEG : - case Mech.ACTUATOR_LOWER_LEG : - case Mech.ACTUATOR_FOOT : - // leg/foot actuator piloting roll - game.addPSR( new PilotingRollData - (en.getId(), 1, "leg/foot actuator hit") ); - break; - case Mech.ACTUATOR_HIP : - // hip piloting roll - game.addPSR( new PilotingRollData - (en.getId(), 2, "hip actuator hit") ); - break; - } - - } // End entity-is-mek - - } // End crit-on-system-slot - - // Handle critical hits on equipment slots. - else if ( CriticalSlot.TYPE_EQUIPMENT == cs.getType() ) { - cs.setHit(true); - Mounted mounted = en.getEquipment(cs.getIndex()); - EquipmentType eqType = mounted.getType(); - boolean hitBefore = mounted.isHit(); - - r = new Report(6225); - r.subject = en.getId(); - r.indent(3); - r.add(mounted.getDesc()); - r.newlines = 0; - vDesc.addElement(r); - - //Shield objects are not useless when they take one crit. - //Shields can be critted and still be usable. - if (eqType instanceof MiscType && ((MiscType)eqType).isShield()) - mounted.setHit(false); - else - mounted.setHit(true); - - if (eqType instanceof MiscType && eqType.hasFlag(MiscType.F_HARJEL)) { - r = new Report(6254); - r.subject = en.getId(); - r.indent(2); - breachLocation(en, loc, null, true); - } - - // If the item is the ECM suite of a Mek Stealth system - // then it's destruction turns off the stealth. - if ( !hitBefore && eqType instanceof MiscType && - eqType.hasFlag(MiscType.F_ECM) && - mounted.getLinkedBy() != null ) { - Mounted stealth = mounted.getLinkedBy(); - r = new Report(6255); - r.subject = en.getId(); - r.indent(2); - r.add(stealth.getType().getName()); - r.newlines = 0; - vDesc.addElement(r); - stealth.setMode( "Off" ); - } - - // Handle equipment explosions. - // Equipment explosions are secondary effects and - // do not occur when loading from a scenario. - if ( secondaryEffects && eqType.isExplosive() && !hitBefore ) { - vDesc.addAll(explodeEquipment(en, loc, mounted)); - } - - // Make sure that ammo in this slot is exhaused. - if ( mounted.getShotsLeft() > 0 ) { - mounted.setShotsLeft(0); - } - - } // End crit-on-equipment-slot - // mechs with TSM hit by anti-tsm missiles this round get another crit - if (en instanceof Mech && en.hitThisRoundByAntiTSM) { - Mech mech = (Mech)en; - if (mech.hasTSM()) { - r = new Report(6430); - r.subject = en.getId(); - r.indent(2); - r.addDesc(en); - r.newlines = 0; - vDesc.addElement(r); - vDesc.addAll(oneCriticalEntity(en, Compute.d6(2))); - } - en.hitThisRoundByAntiTSM = false; - } - - // Return the results of the damage. - return vDesc; - } - - /** - * Rolls and resolves critical hits with no die roll modifiers. - */ - private Vector criticalEntity(Entity en, int loc) { - return criticalEntity(en, loc, 0, true); - } - - private Vector criticalEntity(Entity en, int loc, int critMod) { - return criticalEntity(en, loc, critMod, true); - } - - /** - * Rolls one critical hit - */ - private Vector oneCriticalEntity(Entity en, int loc) { - return criticalEntity(en, loc, 0, false); - } - - private Vector crashVTOL(VTOL en,Coords crashPos,int curElevation) { - return crashVTOL(en, false, 0,crashPos,curElevation,0); - } - private Vector crashVTOL(VTOL en) { - return crashVTOL(en, false, 0 , en.getPosition(),en.getElevation(),0); - } - - /** - * Crash a VTOL - * @param en The VTOL to crash - * @param sideSlipCrash A boolean value indicating wether this - * is a sideslip crash or not. - * @param hexesMoved The int number of hexes moved. - * @param crashPos The Coords of the crash - * @param crashElevation The int elevation of the VTOL - * @param impactSide The int describing the side on which - * the VTOL falls - * @return a Vector of Reports. - */ - private Vector crashVTOL(VTOL en, boolean sideSlipCrash, int hexesMoved, Coords crashPos, int crashElevation,int impactSide) { - Vector vDesc = new Vector(); - Report r; - - if(!sideSlipCrash) { - //report lost movement and crashing - r = new Report(6260); - r.subject = en.getId(); - r.newlines = 0; - r.addDesc(en); - vDesc.addElement(r); - int newElevation = 0; - IHex fallHex = game.getBoard().getHex(crashPos); - - //May land on roof of building or bridge - if(fallHex.containsTerrain(Terrains.BLDG_ELEV)) - newElevation = fallHex.terrainLevel(Terrains.BLDG_ELEV); - else if(fallHex.containsTerrain(Terrains.BRIDGE_ELEV)) { - newElevation = fallHex.terrainLevel(Terrains.BRIDGE_ELEV); - if(newElevation > crashElevation) - newElevation = 0; //vtol was under bridge already - } - - int fall = crashElevation - newElevation; - if(fall==0) { - //already on ground, no harm done - r = new Report(6265); - r.subject = en.getId(); - vDesc.addElement(r); - } else { - //set elevation 1st to avoid multiple crashes - en.setElevation(newElevation); - - //plummets to ground - r = new Report(6270); - r.subject = en.getId(); - r.add(fall); - vDesc.addElement(r); - - // facing after fall - String side; - int table; - int facing = Compute.d6(); - switch(facing) { - case 1: - case 2: - side = "right side"; - table = ToHitData.SIDE_RIGHT; - break; - case 3: - side = "rear"; - table = ToHitData.SIDE_REAR; - break; - case 4: - case 5: - side = "left side"; - table = ToHitData.SIDE_LEFT; - break; - case 0: - default: - side = "front"; - table = ToHitData.SIDE_FRONT; - } - - if(newElevation <= 0) { - boolean waterFall= fallHex.containsTerrain(Terrains.WATER); - if(waterFall && fallHex.containsTerrain(Terrains.ICE)) { - int roll = Compute.d6(1); - r = new Report(2118); - r.subject = en.getId(); - r.add(en.getDisplayName(), true); - r.add(roll); - r.subject = en.getId(); - addReport(r); - if(roll == 6) { - resolveIceBroken(crashPos); - } else { - waterFall = false; //saved by ice - } - } - if(waterFall) { - //falls into water and is destroyed - r = new Report(6275); - r.subject = en.getId(); - vDesc.addElement(r); - en.destroy("Fell into water",false, false);//not sure, is this salvagable? - } - } - - // calculate damage for hitting the surface - int damage = (int)Math.round(en.getWeight() / 10.0) * (fall + 1); - - // adjust damage for gravity - damage = Math.round(damage * game.getOptions().floatOption("gravity")); - // report falling - r = new Report(6280); - r.subject = en.getId(); - r.indent(); - r.addDesc(en); - r.add(side); - r.add(damage); - r.newlines = 0; - vDesc.addElement(r); - - en.setFacing((en.getFacing() + (facing - 1)) % 6); - - boolean exploded=false; - - // standard damage loop - while (damage > 0) { - int cluster = Math.min(5, damage); - HitData hit = en.rollHitLocation(ToHitData.HIT_NORMAL, table); - int ISBefore[]={en.getInternal(Tank.LOC_FRONT), en.getInternal(Tank.LOC_RIGHT), en.getInternal(Tank.LOC_LEFT), en.getInternal(Tank.LOC_REAR)};//hack? - vDesc.addAll( - damageEntity(en, hit, cluster)); - int ISAfter[]={en.getInternal(Tank.LOC_FRONT), en.getInternal(Tank.LOC_RIGHT), en.getInternal(Tank.LOC_LEFT), en.getInternal(Tank.LOC_REAR)}; - for(int x=0;x<=3;x++) { - if(ISBefore[x]!=ISAfter[x]) { - exploded=true; - } - } - damage -= cluster; - } - if (exploded) { - r = new Report(6285); - r.subject = en.getId(); - r.addDesc(en); - vDesc.addElement(r); - vDesc.addAll( explodeVTOL(en)); - } - - //check for location exposure - doSetLocationsExposure(en, fallHex, false, newElevation); - - } - } else { - en.setElevation(0);//considered landed in the hex. - //crashes into ground thanks to sideslip - r = new Report(6290); - r.subject = en.getId(); - r.addDesc(en); - vDesc.addElement(r); - int damage = (int)Math.round(en.getWeight() / 10.0) * (hexesMoved + 1); - boolean exploded=false; - - // standard damage loop - while (damage > 0) { - int cluster = Math.min(5, damage); - HitData hit = en.rollHitLocation(ToHitData.HIT_NORMAL, impactSide); - int ISBefore[]={en.getInternal(Tank.LOC_FRONT), en.getInternal(Tank.LOC_RIGHT), en.getInternal(Tank.LOC_LEFT), en.getInternal(Tank.LOC_REAR)};//hack? - vDesc.addAll( damageEntity(en, hit, cluster)); - int ISAfter[]={en.getInternal(Tank.LOC_FRONT), en.getInternal(Tank.LOC_RIGHT), en.getInternal(Tank.LOC_LEFT), en.getInternal(Tank.LOC_REAR)}; - for(int x=0;x<=3;x++) { - if(ISBefore[x]!=ISAfter[x]) { - exploded=true; - } - } - damage -= cluster; - } - if(exploded) { - r = new Report(6295); - r.subject = en.getId(); - r.addDesc(en); - vDesc.addElement(r); - vDesc.addAll( explodeVTOL(en)); - } - - } - return vDesc; - - } - - /** - * Explode a VTOL - * @param en The VTOL to explode. - * @return a Vector of reports - */ - private Vector explodeVTOL(VTOL en) { - Vector vDesc = new Vector(); - Report r; - - if(en.getEngine().isFusion()) { - //fusion engine, no effect - r = new Report(6300); - r.subject = en.getId(); - vDesc.addElement(r); - } else { - Coords pos=en.getPosition(); - IHex hex = game.getBoard().getHex(pos); - if(hex.containsTerrain(Terrains.WOODS) || hex.containsTerrain(Terrains.JUNGLE)) { - hex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - } else { - game.getBoard().addInfernoTo(pos, InfernoTracker.STANDARD_ROUND, 1); - ((InfernoTracker)(game.getBoard().getInfernos().get(pos))).setTurnsLeftToBurn(game.getBoard().getInfernoBurnTurns(pos)-game.getBoard().getInfernoIVBurnTurns(pos)-2); //massive hack - } - } - - return vDesc; - } - - /** - * Rolls and resolves critical hits on mechs or vehicles. - * if rollNumber is false, a single hit is applied - needed for - * MaxTech Heat Scale rule. - */ - private Vector criticalEntity(Entity en, int loc, int critMod, boolean rollNumber) { - CriticalSlot slot = null; - Vector vDesc = new Vector(); - Report r; - Coords coords = en.getPosition(); - IHex hex = null; - int hits; - if (rollNumber) { - if (null != coords) hex = game.getBoard().getHex(coords); - r = new Report(6305); - r.subject = en.getId(); - r.indent(2); - r.add(en.getLocationAbbr(loc)); - r.newlines = 0; - vDesc.addElement(r); - hits = 0; - int roll = Compute.d6(2); - r = new Report(6310); - r.subject = en.getId(); - String rollString = new String(); - if ( critMod != 0 ) { - rollString = "(" + roll; - if ( critMod > 0 ) { - rollString += "+"; - } - rollString += critMod + ") = "; - roll += critMod; - } - rollString += roll; - r.add(rollString); - r.newlines = 0; - vDesc.addElement(r); - if (roll <= 7) { - //no effect - r = new Report(6005); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - return vDesc; - } else if (roll >= 8 && roll <= 9) { - hits = 1; - r = new Report(6315); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - } else if (roll >= 10 && roll <= 11) { - hits = 2; - r = new Report(6320); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - } else if (roll == 12) { - if (en instanceof Tank || en instanceof Protomech) { - hits = 3; - r = new Report(6325); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - } else if (en.locationIsLeg(loc)) { - //limb blown off - r = new Report(6120); - r.subject = en.getId(); - r.add(en.getLocationName(loc)); - r.newlines = 0; - vDesc.addElement(r); - if (en.getInternal(loc) > 0) { - destroyLocation(en, loc); - } - if (null != hex) { - if (!hex.containsTerrain (Terrains.LEGS)) { - hex.addTerrain (Terrains.getTerrainFactory().createTerrain(Terrains.LEGS, 1)); - } - else { - hex.addTerrain (Terrains.getTerrainFactory().createTerrain - (Terrains.LEGS, - hex.terrainLevel(Terrains.LEGS)+1)); - } - } - sendChangedHex(en.getPosition()); - return vDesc; - } else if (loc == Mech.LOC_RARM || loc == Mech.LOC_LARM) { - //limb blown off - r = new Report(6120); - r.subject = en.getId(); - r.add(en.getLocationName(loc)); - r.newlines = 0; - vDesc.addElement(r); - destroyLocation(en, loc); - if (null != hex) { - if (!hex.containsTerrain( Terrains.ARMS)) { - hex.addTerrain (Terrains.getTerrainFactory().createTerrain(Terrains.ARMS, 1)); - } - else { - hex.addTerrain (Terrains.getTerrainFactory().createTerrain - (Terrains.ARMS, - hex.terrainLevel(Terrains.ARMS)+1)); - } - } - sendChangedHex(en.getPosition()); - return vDesc; - } else if (loc == Mech.LOC_HEAD) { - //head blown off - r = new Report(6330); - r.subject = en.getId(); - r.add(en.getLocationName(loc)); - r.newlines = 0; - vDesc.addElement(r); - destroyLocation(en, loc); - // Don't kill a pilot multiple times. - if ( Pilot.DEATH > en.getCrew().getHits() ) { - en.crew.setDoomed(true); - Report.addNewline(vDesc); - vDesc.addAll( destroyEntity(en, "pilot death", true)); - } - return vDesc; - } else { - // torso hit - hits = 3; - r = new Report(6325); - r.subject = en.getId(); - r.newlines = 0; - vDesc.addElement(r); - } - } - } else { - hits = 1; - } - - // vehicle handle crits in their own 'special' way - if (en instanceof Tank) { - Tank tank = (Tank)en; - for (int x = 0; x < hits; x++) { - slot = new CriticalSlot( CriticalSlot.TYPE_SYSTEM, - Compute.d6(1) ); - vDesc.addAll( applyCriticalHit(en, Entity.NONE, slot, true)); - } - } - else { - // transfer criticals, if needed - while (hits > 0 && en.canTransferCriticals(loc) - && en.getTransferLocation(loc) != Entity.LOC_DESTROYED - && en.getTransferLocation(loc) != Entity.LOC_NONE) { - loc = en.getTransferLocation(loc); - r = new Report(6335); - r.subject = en.getId(); - r.indent(3); - r.add(en.getLocationAbbr(loc)); - r.newlines = 0; - vDesc.addElement(r); - } - - // Roll critical hits in this location. - while (hits > 0) { - - // Have we hit all available slots in this location? - if (en.getHittableCriticals(loc) <= 0) { - r = new Report(6340); - r.subject = en.getId(); - r.indent(3); - r.newlines = 0; - vDesc.addElement(r); - break; - } - - // Randomly pick a slot to be hit. - int slotIndex = Compute.randomInt - ( en.getNumberOfCriticals(loc) ); - slot = en.getCritical(loc, slotIndex); - - // Ignore empty or unhitable slots (this - // includes all previously hit slots). - - if (slot != null && slot.isHittable()) { - // if explosive use edge - if ((en instanceof Mech) - && ( en.crew.hasEdgeRemaining() - && en.crew.getOptions().booleanOption("edge_when_explosion")) - && slot.getType() == CriticalSlot.TYPE_EQUIPMENT - && en.getEquipment(slot.getIndex()).getType().isExplosive()) { - en.crew.decreaseEdge(); - r = new Report(6530); - r.subject = en.getId(); - r.indent(3); - r.newlines = 0; - r.add(en.crew.getOptions().intOption("edge")); - vDesc.addElement(r); - continue; - } - vDesc.addAll( applyCriticalHit(en, loc, slot, true)); - hits--; - } - - } // Hit another slot in this location. - } - - return vDesc; - } - - /** - * Checks for location breach and returns phase logging. - *

- * Please note that dependent locations ARE NOT considered breached! - * - * @param entity the Entity that needs to be checked. - * @param loc the int location on the entity that needs - * to be checked for a breach. - * @param hex the IHex the enitity occupies when checking - * This value will be null if the check is the - * result of an attack, and non-null if it occurs during movement. - */ - private Vector breachCheck(Entity entity, int loc, IHex hex) { - Vector vDesc = new Vector(); - Report r; - - // BattleArmor does not breach - if (entity instanceof Infantry) { - return vDesc; - } - - if (entity instanceof VTOL) { - return vDesc; - } - - // functional HarJel prevents breach - if (entity instanceof Mech && ((Mech)entity).hasHarJelIn(loc)) { - r = new Report(6342); - r.subject = entity.getId(); - r.indent(3); - vDesc.addElement(r); - return vDesc; - } - - // This handles both water and vacuum breaches. - if (entity.getLocationStatus(loc) > ILocationExposureStatus.NORMAL) { - // Does the location have armor (check rear armor on Mek) - // and is the check due to damage? - int breachroll = 0; - if (entity.getArmor(loc) > 0 && - (entity instanceof Mech ? (entity.getArmor(loc,true)>0) : true) - && null == hex) { - breachroll = Compute.d6(2); - r = new Report(6345); - r.subject = entity.getId(); - r.indent(3); - r.add(entity.getLocationAbbr(loc)); - r.add(breachroll); - r.newlines = 0; - vDesc.addElement(r); - } - // Breach by damage or lack of armor. - if ( breachroll >= 10 - || !(entity.getArmor(loc) > 0) - || !(entity instanceof Mech ? (entity.getArmor(loc,true)>0) : - true) ) { - vDesc.addAll( breachLocation(entity, loc, hex, false)); - } - } - return vDesc; - } - - /** - * Marks all equipment in a location on an entity as useless. - * - * @param entity the Entity that needs to be checked. - * @param loc the int location on the entity that needs - * to be checked for a breach. - * @param hex the IHex the enitity occupies when checking - * This value will be null if the check is the - * result of an attack, and non-null if it occurs during movement. - * @param harJel a boolean value indicating if the uselessness - * is the cause of a critically hit HarJel system - */ - private Vector breachLocation(Entity entity, int loc, IHex hex, boolean harJel) { - Vector vDesc = new Vector(); - Report r; - - if (entity.getInternal(loc) < 0 || - entity.getLocationStatus(loc) < ILocationExposureStatus.NORMAL) { - //already destroyed or breached? don't bother - return vDesc; - } - - r = new Report(6350); - if (harJel) r.messageId = 6351; - r.subject = entity.getId(); - r.add(entity.getShortName()); - r.add(entity.getLocationAbbr(loc)); - r.newlines = 0; - vDesc.addElement(r); - - if (entity instanceof Tank) { - vDesc.addAll( - destroyEntity(entity, "hull breach", true, true)); - return vDesc; - } - // equipment and crits will be marked in applyDamage? - - // equipment marked missing - for (Enumeration i = entity.getEquipment(); i.hasMoreElements();) { - Mounted mounted = (Mounted)i.nextElement(); - if (mounted.getLocation() == loc) { - mounted.setBreached(true); - } - } - // all critical slots set as useless - for (int i = 0; i < entity.getNumberOfCriticals(loc); i++) { - final CriticalSlot cs = entity.getCritical(loc, i); - if (cs != null) { - // for every undamaged actuator destroyed by breaching, - // we make a PSR (see bug 1040858) - if (entity.locationIsLeg(loc)) { - if (cs.isHittable()) { - switch(cs.getIndex()) { - case Mech.ACTUATOR_UPPER_LEG : - case Mech.ACTUATOR_LOWER_LEG : - case Mech.ACTUATOR_FOOT : - // leg/foot actuator piloting roll - game.addPSR( new PilotingRollData - (entity.getId(), 1, "leg/foot actuator hit") ); - break; - case Mech.ACTUATOR_HIP : - // hip piloting roll (at +0, because we get the +2 - // anyway because the location is breached - // phase report will look a bit weird, but the roll - // is correct - game.addPSR( new PilotingRollData - (entity.getId(), 0, "hip actuator hit") ); - break; - } - } - } - cs.setBreached(true); - } - } - - //Check location for engine/cockpit breach and report accordingly - if (loc == Mech.LOC_CT) { - vDesc.addAll( destroyEntity(entity, "hull breach")); - if (game.getOptions().booleanOption("auto_abandon_unit")) { - vDesc.addAll(abandonEntity(entity)); - } - } - if (loc == Mech.LOC_HEAD) { - entity.crew.setDoomed(true); - vDesc.addAll( destroyEntity(entity, "hull breach")); - if (entity.getLocationStatus(loc) == ILocationExposureStatus.WET) { - r = new Report(6355); - r.subject = entity.getId(); - r.addDesc(entity); - vDesc.addElement(r); - } else { - r = new Report(6360); - r.subject = entity.getId(); - r.addDesc(entity); - vDesc.addElement(r); - } - } - - // Set the status of the location. - // N.B. if we set the status before rolling water PSRs, we get a - // "LEG DESTROYED" modifier; setting the status after gives a hip - // actuator modifier. - entity.setLocationStatus(loc, ILocationExposureStatus.BREACHED); - - // Did the hull breach destroy the engine? - if (entity.getHitCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_ENGINE, - Mech.LOC_LT) + - entity.getHitCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_ENGINE, - Mech.LOC_CT) + - entity.getHitCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_ENGINE, - Mech.LOC_RT) - >= 3) { - vDesc.addAll( destroyEntity(entity, "engine destruction")); - if (game.getOptions().booleanOption("auto_abandon_unit")) { - vDesc.addAll(abandonEntity(entity)); - } - } - - return vDesc; - } - - /** - * Marks all equipment in a location on an entity as destroyed. - */ - void destroyLocation(Entity en, int loc) { - // if it's already marked as destroyed, don't bother - if (en.getInternal(loc) < 0) { - return; - } - // mark armor, internal as doomed - en.setArmor(IArmorState.ARMOR_DOOMED, loc, false); - en.setInternal(IArmorState.ARMOR_DOOMED, loc); - if (en.hasRearArmor(loc)) { - en.setArmor(IArmorState.ARMOR_DOOMED, loc, true); - } - // equipment marked missing - for (Enumeration i = en.getEquipment(); i.hasMoreElements();) { - Mounted mounted = (Mounted)i.nextElement(); - if (mounted.getLocation() == loc) { - mounted.setMissing(true); - } - } - // all critical slots set as missing - for (int i = 0; i < en.getNumberOfCriticals(loc); i++) { - final CriticalSlot cs = en.getCritical(loc, i); - if (cs != null) { - // count engine hits for maxtech engine explosions - if (cs.getType() == CriticalSlot.TYPE_SYSTEM && - cs.getIndex() == Mech.SYSTEM_ENGINE && - !cs.isDamaged()) { - en.engineHitsThisRound++; - } - cs.setMissing(true); - } - } - // if it's a leg, the entity falls - if (en instanceof Mech && en.locationIsLeg(loc)) { - game.addPSR(new PilotingRollData(en.getId(), PilotingRollData.AUTOMATIC_FAIL, 5, "leg destroyed")); - } - // dependent locations destroyed - if (en.getDependentLocation(loc) != Entity.LOC_NONE) { - destroyLocation(en, en.getDependentLocation(loc)); - } - } - - /** - * Mark the unit as destroyed! Units transported in the destroyed unit - * will get a chance to escape. - * - * @param entity - the Entity that has been destroyed. - * @param reason - a String detailing why the entity - * was destroyed. - * @return a Vector of Report objects - * that can be sent to the output log. - */ - private Vector destroyEntity(Entity entity, String reason) { - return destroyEntity( entity, reason, true ); - } - - /** - * Marks a unit as destroyed! Units transported inside the destroyed - * unit will get a chance to escape unless the destruction was not - * survivable. - * - * @param entity - the Entity that has been destroyed. - * @param reason - a String detailing why the entity - * was destroyed. - * @param survivable - a boolean that identifies the - * desctruction as unsurvivable for transported units. - * @return a Vector of Report objects - * that can be sent to the output log. - */ - private Vector destroyEntity(Entity entity, String reason, - boolean survivable) { - // Generally, the entity can still be salvaged. - return this.destroyEntity( entity, reason, survivable, true ); - } - - /** - * Marks a unit as destroyed! Units transported inside the destroyed - * unit will get a chance to escape unless the destruction was not - * survivable. - * - * @param entity - the Entity that has been destroyed. - * @param reason - a String detailing why the entity - * was destroyed. - * @param survivable - a boolean that identifies the - * desctruction as unsurvivable for transported units. - * @param canSalvage - a boolean that indicates if - * the unit can be salvaged (or cannibalized for spare parts). - * If true, salvage operations are possible, if - * false, the unit is too badly damaged. - * @return a Vector of Report objects - * that can be sent to the output log. - */ - private Vector destroyEntity(Entity entity, String reason, - boolean survivable, boolean canSalvage) { - Vector vDesc = new Vector(); - Report r; - - // The unit can suffer an ammo explosion after it has been destroyed. - int condition = IEntityRemovalConditions.REMOVE_SALVAGEABLE; - if ( !canSalvage ) { - entity.setSalvage( canSalvage ); - condition = IEntityRemovalConditions.REMOVE_DEVASTATED; - } - - // Destroy the entity, unless it's already destroyed. - if (!entity.isDoomed() && !entity.isDestroyed()) { - r = new Report(6365); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(reason); - r.newlines=0; - vDesc.addElement(r); - - entity.setDoomed(true); - - // Kill any picked up MechWarriors - Enumeration iter = entity.getPickedUpMechWarriors().elements(); - while (iter.hasMoreElements() ) { - Integer mechWarriorId = (Integer)iter.nextElement(); - Entity mw = game.getEntity(mechWarriorId.intValue()); - mw.setDestroyed(true); - game.removeEntity( mw.getId(), condition ); - this.entityUpdate(mw.getId()); - send( createRemoveEntityPacket(mw.getId(), condition) ); - r = new Report(6370); - r.subject = mw.getId(); - r.addDesc(mw); - vDesc.addElement(r); - } - - // Handle escape of transported units. - iter = entity.getLoadedUnits().elements(); - if ( iter.hasMoreElements() ) { - Entity other = null; - Coords curPos = entity.getPosition(); - IHex entityHex = game.getBoard().getHex( curPos ); - int curFacing = entity.getFacing(); - while ( iter.hasMoreElements() ) { - other = (Entity) iter.nextElement(); - - // Can the other unit survive? - if ( !survivable ) { - - // Nope. - other.setDestroyed(true); - game.moveToGraveyard( other.getId() ); - this.entityUpdate(other.getId()); - send( createRemoveEntityPacket(other.getId(), - condition) ); - r = new Report(6370); - r.subject = other.getId(); - r.addDesc(other); - vDesc.addElement(r); - } - // Can we unload the unit to the current hex? - // TODO : unloading into stacking violation is not - // explicitly prohibited in the BMRr. - else if (null != Compute.stackingViolation(game, other.getId(), curPos) - || other.isHexProhibited(entityHex) ) { - // Nope. - other.setDestroyed(true); - game.moveToGraveyard( other.getId() ); - this.entityUpdate(other.getId()); - send( createRemoveEntityPacket(other.getId(), - condition) ); - r = new Report(6375); - r.subject = other.getId(); - r.addDesc(other); - vDesc.addElement(r); - } // End can-not-unload - else { - // The other unit survives. - this.unloadUnit( entity, other, curPos, curFacing, entity.getElevation() ); - } - - } // Handle the next transported unit. - - } // End has-transported-unit - - // Handle transporting unit. - if ( Entity.NONE != entity.getTransportId() ) { - final Entity transport = game.getEntity - ( entity.getTransportId() ); - Coords curPos = transport.getPosition(); - int curFacing = transport.getFacing(); - this.unloadUnit( transport, entity, curPos, curFacing, transport.getElevation() ); - this.entityUpdate( transport.getId() ); - } // End unit-is-transported - - // Is this unit being swarmed? - final int swarmerId = entity.getSwarmAttackerId(); - if ( Entity.NONE != swarmerId ) { - final Entity swarmer = game.getEntity( swarmerId ); - - // remove the swarmer from the move queue - game.removeTurnFor(swarmer); - send(createTurnVectorPacket()); - - swarmer.setSwarmTargetId( Entity.NONE ); - entity.setSwarmAttackerId( Entity.NONE ); - r = new Report(6380); - r.subject = swarmerId; - r.addDesc(swarmer); - vDesc.addElement(r); - this.entityUpdate( swarmerId ); - } - - // Is this unit swarming somebody? - final int swarmedId = entity.getSwarmTargetId(); - if ( Entity.NONE != swarmedId ) { - final Entity swarmed = game.getEntity( swarmedId ); - swarmed.setSwarmAttackerId( Entity.NONE ); - entity.setSwarmTargetId( Entity.NONE ); - r = new Report(6385); - r.subject = swarmed.getId(); - r.addDesc(swarmed); - vDesc.addElement(r); - this.entityUpdate( swarmedId ); - } - - } // End entity-not-already-destroyed. - - // update our entity, so clients have correct data - // needed for MekWars stuff - this.entityUpdate(entity.getId()); - - return vDesc; - } - - - /** - * Makes a piece of equipment on a mech explode! POW! This expects either - * ammo, or an explosive weapon. Returns a vector of Report objects. - */ - private Vector explodeEquipment(Entity en, int loc, int slot) { - return explodeEquipment(en, loc, en.getEquipment(en.getCritical(loc, slot).getIndex())); - } - - private Vector explodeEquipment(Entity en, int loc, Mounted mounted) { - Vector vDesc = new Vector(); - // is this already destroyed? - if (mounted.isDestroyed()) { - System.err.println("server: explodeEquipment called on destroyed" - + " equipment (" + mounted.getName() + ")"); - return vDesc; - } - - // special-case. RACs only explode when jammed - if (mounted.getType() instanceof WeaponType && - ((WeaponType)mounted.getType()).getAmmoType() == AmmoType.T_AC_ROTARY) { - if (!mounted.isJammed()) { - return vDesc; - } - } - - // special case. ACs only explode when firing incendiary ammo - if (mounted.getType() instanceof WeaponType && - ((WeaponType)mounted.getType()).getAmmoType() == AmmoType.T_AC) { - if (!mounted.isUsedThisRound()) { - return vDesc; - } - Mounted ammo = mounted.getLinked(); - if(ammo == null || !(ammo.getType() instanceof AmmoType) || - ((AmmoType)ammo.getType()).getMunitionType() != AmmoType.M_INCENDIARY_AC ) { - return vDesc; - } - - WeaponType wtype = (WeaponType)mounted.getType(); - if ( ((wtype.getAmmoType() == AmmoType.T_LRM) || - (wtype.getAmmoType() == AmmoType.T_LRM_STREAK) || - (wtype.getAmmoType() == AmmoType.T_LRM_TORPEDO) || - (wtype.getAmmoType() == AmmoType.T_LRM_TORPEDO_COMBO))){ - return vDesc; - } - - } - - // Inferno ammo causes heat buildup as well as the damage - if (mounted.getType() instanceof AmmoType - && ((((AmmoType)mounted.getType()).getAmmoType() == AmmoType.T_SRM) - || (((AmmoType)mounted.getType()).getAmmoType() == AmmoType.T_BA_INFERNO)) - && ((AmmoType)mounted.getType()).getMunitionType() == AmmoType.M_INFERNO - && mounted.getShotsLeft() > 0) { - en.heatBuildup += 30; - } - - // determine and deal damage - int damage = mounted.getExplosionDamage(); - - if (damage <= 0) { - return vDesc; - } - - Report r = new Report(6390); - r.subject = en.getId(); - r.add(mounted.getName()); - r.add(damage); - r.indent(3); - r.newlines = 0; - vDesc.addElement(r); - mounted.setShotsLeft(0); - vDesc.addAll( damageEntity(en, new HitData(loc), damage, true)); - Report.addNewline(vDesc); - - - int pilotDamage = 2; - if (en.getCrew().getOptions().booleanOption("pain_resistance")) pilotDamage = 1; - if (en.getCrew().getOptions().booleanOption("iron_man")) pilotDamage = 1; - vDesc.addAll( damageCrew(en, pilotDamage)); - if ( en.crew.isDoomed() || en.crew.isDead() ) { - vDesc.addAll( destroyEntity(en, "crew death", true) ); - } else { - Report.addNewline(vDesc); - } - - return vDesc; - } - - /** - * Makes one slot of ammo, determined by certain rules, explode on a mech. - */ - private Vector explodeAmmoFromHeat(Entity entity) { - int damage = 0; - int rack = 0; - int boomloc = -1; - int boomslot = -1; - Vector vDesc = new Vector(); - - for (int j = 0; j < entity.locations(); j++) { - for (int k = 0; k < entity.getNumberOfCriticals(j); k++) { - CriticalSlot cs = entity.getCritical(j, k); - if (cs == null || cs.isDestroyed() || cs.isHit() || cs.getType() != CriticalSlot.TYPE_EQUIPMENT) { - continue; - } - Mounted mounted = entity.getEquipment(entity.getCritical(j, k).getIndex()); - if (!(mounted.getType() instanceof AmmoType)) { - continue; - } - AmmoType atype = (AmmoType)mounted.getType(); - if (!atype.isExplosive()) { - continue; - } - //ignore empty bins - if (atype.getShots() == 0) { - continue; - } - // BMRr, pg. 48, compare one rack's - // damage. Ties go to most rounds. - int newRack = atype.getDamagePerShot() * atype.getRackSize(); - int newDamage = mounted.getExplosionDamage(); - if ( !mounted.isHit() && ( rack < newRack || - (rack == newRack && damage < newDamage) ) ) { - rack = newRack; - damage = newDamage; - boomloc = j; - boomslot = k; - } - } - } - if (boomloc != -1 && boomslot != -1) { - CriticalSlot slot = entity.getCritical(boomloc, boomslot); - slot.setHit(true); - entity.getEquipment(slot.getIndex()).setHit(true); - vDesc = explodeEquipment(entity, boomloc, boomslot); - } else { - //Luckily, there is no ammo to explode. - Report r = new Report(5105); - r.subject = entity.getId(); - r.indent(); - vDesc.addElement(r); - } - return vDesc; - } - - /** - * Makes a mech fall. - */ - private void doEntityFall(Entity entity, Coords fallPos, int height, int facing, PilotingRollData roll) { - Report r; - - IHex fallHex = game.getBoard().getHex(fallPos); - - // we don't need to deal damage yet, if the entity is doing DFA - if (entity.isMakingDfa()) { - r = new Report(2305); - r.subject = entity.getId(); - addReport(r); - entity.setProne(true); - return; - } - // facing after fall - String side; - int table; - switch(facing) { - case 1: - case 2: - side = "right side"; - table = ToHitData.SIDE_RIGHT; - break; - case 3: - side = "rear"; - table = ToHitData.SIDE_REAR; - break; - case 4: - case 5: - side = "left side"; - table = ToHitData.SIDE_LEFT; - break; - case 0: - default: - side = "front"; - table = ToHitData.SIDE_FRONT; - } - - int waterDepth = fallHex.terrainLevel(Terrains.WATER); - int damageHeight = height; - - - // HACK: if the dest hex is water, assume that the fall height given is - // to the floor of the hex, and modifiy it so that it's to the surface - if (waterDepth > 0) { - damageHeight = height - waterDepth; - } else { - waterDepth = 0; //because it will be used to set elevation - } - - if(fallHex.containsTerrain(Terrains.ICE)) { - waterDepth = 0; - } - - //Falling into water instantly destroys most non-mechs - if(waterDepth > 0 - && !(entity instanceof Mech) - && !(entity instanceof Protomech) - && (entity.getRunMP() > 0 && entity.getMovementMode() != IEntityMovementMode.HOVER) - && entity.getMovementMode() != IEntityMovementMode.HYDROFOIL - && entity.getMovementMode() != IEntityMovementMode.NAVAL - && entity.getMovementMode() != IEntityMovementMode.SUBMARINE) { - addReport( - destroyEntity(entity, "a watery grave", false)); - return; - } - - // calculate damage for hitting the surface - int damage = (int)Math.round(entity.getWeight() / 10.0) * (damageHeight + 1); - // calculate damage for hitting the ground, but only if we actually fell - // into water - // if we fell onto the water surface, that damage is halved. - int waterDamage = 0; - if (waterDepth > 0) { - damage /= 2; - waterDamage = (int)Math.round(entity.getWeight() / 10.0) * (waterDepth + 1) /2; - } - - // If the waterDepth is larger than the fall height, - // we fell underwater - if (waterDepth > height) { - damage = 0; - waterDamage = (int)Math.round(entity.getWeight() / 10.0) * (height + 1) /2; - } - // adjust damage for gravity - damage = Math.round(damage * game.getOptions().floatOption("gravity")); - waterDamage = Math.round(waterDamage * game.getOptions().floatOption("gravity")); - - // report falling - if (waterDamage == 0) { - r = new Report(2310); - r.subject = entity.getId(); - r.indent(); - r.newlines = 0; - r.addDesc(entity); - r.add(side); //international issue - r.add(damage); - } else if (damage > 0) { - r = new Report(2315); - r.subject = entity.getId(); - r.indent(); - r.newlines = 0; - r.addDesc(entity); - r.add(side); //international issue - r.add(damage); - r.add(waterDamage); - } else { - r = new Report(2310); - r.subject = entity.getId(); - r.indent(); - r.newlines = 0; - r.addDesc(entity); - r.add(side); //international issue - r.add(waterDamage); - } - addReport(r); - damage += waterDamage; - - // Any swarming infantry will be dislodged, but we don't want to - // interrupt the fall's report. We have to get the ID now because - // the fall may kill the entity which will reset the attacker ID. - final int swarmerId = entity.getSwarmAttackerId(); - - // Positioning must be prior to damage for proper handling of breaches - // Only Mechs can fall prone. - if ( entity instanceof Mech ) { - entity.setProne(true); - } - entity.setPosition(fallPos); - entity.setFacing((entity.getFacing() + (facing - 1)) % 6); - entity.setSecondaryFacing(entity.getFacing()); - entity.setElevation(-waterDepth); - if (waterDepth > 0) { - for (int loop=0; loop< entity.locations();loop++){ - entity.setLocationStatus(loop, ILocationExposureStatus.WET); - } - } - - // standard damage loop - while (damage > 0) { - int cluster = Math.min(5, damage); - HitData hit = entity.rollHitLocation(ToHitData.HIT_NORMAL, table); - hit.makeFallDamage(true); - addReport( damageEntity(entity, hit, cluster)); - damage -= cluster; - } - - //check for location exposure - doSetLocationsExposure(entity, fallHex, false, -waterDepth); - - // we want to be able to avoid pilot damage even when it was - // an automatic fall, only unconsciousness should cause auto-damage - roll.removeAutos(); - - if (height > 0) { - roll.addModifier(height, "height of fall"); - } - - entity.addPilotingModifierForTerrain(roll, fallPos); - - if (roll.getValue() == PilotingRollData.IMPOSSIBLE) { - r = new Report(2320); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(entity.crew.getName()); - r.indent(); - addReport(r); - addReport( damageCrew(entity, 1)); - ((Report) vPhaseReport.elementAt(vPhaseReport.size() - 1)).newlines++; - } else { - int diceRoll = Compute.d6(2); - r = new Report(2325); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(entity.crew.getName()); - r.add(roll.getValueAsString()); - r.add(diceRoll); - if (diceRoll >= roll.getValue()) { - r.choose(true); - addReport(r); - } else { - r.choose(false); - addReport(r); - addReport( damageCrew(entity, 1)); - ((Report) vPhaseReport.elementAt(vPhaseReport.size() - 1)).newlines++; - } - } - - // Now dislodge any swarming infantry. - if ( Entity.NONE != swarmerId ) { - final Entity swarmer = game.getEntity( swarmerId ); - entity.setSwarmAttackerId( Entity.NONE ); - swarmer.setSwarmTargetId( Entity.NONE ); - // Did the infantry fall into water? - if ( waterDepth > 0 ) { - // Swarming infantry die. - swarmer.setPosition( fallPos ); - r = new Report(2330); - r.newlines = 0; - r.subject = swarmer.getId(); - r.addDesc(swarmer); - addReport(r); - addReport( destroyEntity(swarmer, "a watery grave", false)); - } else { - // Swarming infantry take an 11 point hit. - // ASSUMPTION : damage should not be doubled. - r = new Report(2335); - r.newlines = 0; - r.subject = swarmer.getId(); - r.addDesc(swarmer); - addReport(r); - addReport( damageEntity(swarmer, swarmer.rollHitLocation(ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT), 11)); - ((Report) vPhaseReport.elementAt(vPhaseReport.size() - 1)).newlines++; - } - swarmer.setPosition( fallPos ); - entityUpdate( swarmerId ); - } // End dislodge-infantry - - // clear all PSRs after a fall -- the Mek has already failed ONE and fallen, it'd be cruel to make it fail some more! - game.resetPSRs(entity); - } - - /** - * The mech falls into an unoccupied hex from the given height above - */ - private void doEntityFall(Entity entity, Coords fallPos, int height, PilotingRollData roll) { - doEntityFall(entity, fallPos, height, Compute.d6(1), roll); - } - - /** - * The mech falls down in place - */ - private void doEntityFall(Entity entity, PilotingRollData roll) { - doEntityFall(entity, entity.getPosition(), 0, roll); - } - - /** - * Report: - * - Any ammo dumps beginning the following round. - * - Any ammo dumps that have ended with the end of this round. - */ - private void resolveAmmoDumps() { - Report r; - for (Enumeration i = game.getEntities(); i.hasMoreElements();) { - Entity entity = (Entity)i.nextElement(); - for (Enumeration j = entity.getAmmo(); j.hasMoreElements(); ) { - Mounted m = (Mounted)j.nextElement(); - if (m.isPendingDump()) { - //report dumping next round - r = new Report(5110); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(m.getName()); - addReport(r); - //update status - m.setPendingDump(false); - m.setDumping(true); - } - else if (m.isDumping()) { - //report finished dumping - r = new Report(5115); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(m.getName()); - addReport(r); - //update status - m.setDumping(false); - m.setShotsLeft(0); - } - } - entity.reloadEmptyWeapons(); - } - } - - /** - * Returns true if the hex is set on fire with the specified roll. Of - * course, also checks to see that fire is possible in the specified hex. - * - * @param hex - the IHex to be lit. - * @param roll - the int target number for the ignition roll - * @param bAnyTerrain - true if the fire can be lit in any - * terrain. If this value is false the hex will be - * lit only if it contains Woods,jungle or a Building. - * @param entityId - the entityId responsible for the ignite attempt. - * If the value is Entity.NONE, then the roll attempt will not - * be included in the report. - */ - public boolean ignite( IHex hex, int roll, boolean bAnyTerrain, - int entityId ) { - - // The hex might be null due to spreadFire translation - // goes outside of the board limit. - if ( !game.getOptions().booleanOption("fire") || null == hex ) { - return false; - } - - // The hex may already be on fire. - if ( hex.containsTerrain( Terrains.FIRE ) ) { - return true; - } - - if ( !bAnyTerrain && - !(hex.containsTerrain(Terrains.WOODS)) && - !(hex.containsTerrain(Terrains.JUNGLE)) && - !(hex.containsTerrain(Terrains.BUILDING)) ) { - return false; - } - - int fireRoll = Compute.d6(2); - if (entityId != Entity.NONE) { - Report r = new Report(3430); - r.indent(3); - r.subject = entityId; - r.add(roll); - r.add(fireRoll); - addReport(r); - } - if (fireRoll >= roll) { - hex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.FIRE, 1)); - return true; - } else { - return false; - } - } - - /** - * Returns true if the hex is set on fire with the specified roll. Of - * course, also checks to see that fire is possible in the specified hex. - * This version of the method will not report the attempt roll. - * - * @param hex - the IHex to be lit. - * @param roll - the int target number for the ignition roll - * @param bAnyTerrain - true if the fire can be lit in any - * terrain. If this value is false the hex will be - * lit only if it contains Woods, jungle or a Building. - */ - public boolean ignite(IHex hex, int roll, boolean bAnyTerrain) { - return ignite(hex, roll, bAnyTerrain, Entity.NONE); - } - - public boolean ignite(IHex hex, int roll) { - // default signature, assuming only woods can burn - return ignite(hex, roll, false, Entity.NONE); - } - - public void removeFire(int x, int y, IHex hex) { - Coords fireCoords = new Coords(x, y); - hex.removeTerrain(Terrains.FIRE); - sendChangedHex(fireCoords); - if (!game.getOptions().booleanOption("maxtech_fire")) { - // only remove the 3 smoke hexes if under L2 rules! - int windDir = game.getWindDirection(); - removeSmoke(x, y, windDir); - removeSmoke(x, y, (windDir + 1) % 6); - removeSmoke(x, y, (windDir + 5) % 6); - } - //fire goes out due to lack of fuel - Report r = new Report(5170, Report.PUBLIC); - r.add(fireCoords.getBoardNum()); - addReport(r); - } - - /** - * called when a fire is burning. Adds smoke to hex in the direction - * specified. Called 3 times per fire hex - * @param x The int x-coordinate of the hex - * @param y The int y-coordinate of the hex - * @param windDir The int specifying the winddirection - */ - public void addSmoke(int x, int y, int windDir) { - Coords smokeCoords = new Coords(Coords.xInDir(x, y, windDir), Coords.yInDir(x, y, windDir)); - IHex nextHex = game.getBoard().getHex(smokeCoords); - if (nextHex != null && !(nextHex.containsTerrain(Terrains.SMOKE))) { - nextHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.SMOKE, 1)); - sendChangedHex(smokeCoords); - Report r = new Report(5175, Report.PUBLIC); - r.add(smokeCoords.getBoardNum()); - addReport(r); - } - } - - /** - * Add lvl3 smoke to the hex specified by the parameters. Called once. - * @param x The int x-coordinate of the hex - * @param y The int y-coordinate of the hex - */ - public void addL3Smoke(int x, int y) { - IBoard board = game.getBoard(); - Coords smokeCoords = new Coords(x, y); - IHex smokeHex = game.getBoard().getHex(smokeCoords); - boolean infernoBurning = board.isInfernoBurning( smokeCoords ); - Report r; - if (smokeHex == null) { - return; - } - // Have to check if it's inferno smoke or from a heavy/hardened building - heavy smoke from those - if (infernoBurning || Building.MEDIUM < smokeHex.terrainLevel(Terrains.BUILDING)) { - if (smokeHex.terrainLevel(Terrains.SMOKE) == 2){ - //heavy smoke fills hex - r = new Report(5180, Report.PUBLIC); - r.add(smokeCoords.getBoardNum()); - addReport(r); - } else { - if (smokeHex.terrainLevel(Terrains.SMOKE) == 1){ - //heavy smoke overrides light - smokeHex.removeTerrain(Terrains.SMOKE); - } - smokeHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.SMOKE, 2)); - sendChangedHex(smokeCoords); - r = new Report(5185, Report.PUBLIC); - r.add(smokeCoords.getBoardNum()); - addReport(r); - } - } else { - if (smokeHex.terrainLevel(Terrains.SMOKE) == 2){ - //heavy smoke overpowers light - r = new Report(5190, Report.PUBLIC); - r.add(smokeCoords.getBoardNum()); - addReport(r); - } else if (smokeHex.terrainLevel(Terrains.SMOKE) == 1){ - //light smoke continue to fill hex - r = new Report(5195, Report.PUBLIC); - r.add(smokeCoords.getBoardNum()); - addReport(r); - } else { - smokeHex.addTerrain(Terrains.getTerrainFactory().createTerrain(Terrains.SMOKE, 1)); - sendChangedHex(smokeCoords); - //light smoke fills hex - r = new Report(5200, Report.PUBLIC); - r.add(smokeCoords.getBoardNum()); - addReport(r); - } - } - } - - public void removeSmoke(int x, int y, int windDir) { // L2 smoke removal - Coords smokeCoords = new Coords(Coords.xInDir(x, y, windDir), Coords.yInDir(x, y, windDir)); - IHex nextHex = game.getBoard().getHex(smokeCoords); - if (nextHex != null && nextHex.containsTerrain(Terrains.SMOKE)) { - nextHex.removeTerrain(Terrains.SMOKE); - sendChangedHex(smokeCoords); - Report r = new Report(5205, Report.PUBLIC); - r.add(smokeCoords.getBoardNum()); - addReport(r); - } - } - - - /** - * Scans the boards directory for map boards of the appropriate size - * and returns them. - */ - private Vector scanForBoardsInDir (File dir, String addPath, int w, int h) { - String fileList[] = dir.list(); - Vector tempList = new Vector(); - Comparator sortComp = StringUtil.stringComparator(); - for (int i = 0; i < fileList.length; i++) { - if (fileList[i].indexOf(".board") == -1) { - continue; - } - if (Board.boardIsSize(addPath.concat("/").concat(fileList[i]), w, h)) { - tempList.addElement(addPath.concat("/").concat(fileList[i].substring(0, fileList[i].lastIndexOf(".board")))); - } - } - return tempList; - } - - private Vector scanForBoards(int boardWidth, int boardHeight) { - return scanForBoards (boardWidth, boardHeight, game.getOptions().booleanOption("maps_include_subdir")); - } - - private Vector scanForBoards(int boardWidth, int boardHeight, boolean subdirs) { - Vector boards = new Vector(); - - File boardDir = new File("data/boards"); - boards.addElement(MapSettings.BOARD_GENERATED); - // just a check... - if (!boardDir.isDirectory()) { - return boards; - } - - // scan files - String[] fileList = boardDir.list(); - Vector tempList = new Vector(); - Comparator sortComp = StringUtil.stringComparator(); - for (int i = 0; i < fileList.length; i++) { - File x = new File (new String("data/boards/").concat(fileList[i])); - if (x.isDirectory() && subdirs) { - tempList.addAll(scanForBoardsInDir(x, fileList[i], boardWidth, boardHeight)); - continue; - } - if (fileList[i].indexOf(".board") == -1) { - continue; - } - if (Board.boardIsSize(fileList[i], boardWidth, boardHeight)) { - tempList.addElement(fileList[i].substring(0, fileList[i].lastIndexOf(".board"))); - } - } - - // if there are any boards, add these: - if (tempList.size() > 0) { - boards.addElement( MapSettings.BOARD_RANDOM ); - boards.addElement( MapSettings.BOARD_SURPRISE ); - Collections.sort(tempList, sortComp); - for ( int loop = 0; loop < tempList.size(); loop++ ) { - boards.addElement( tempList.elementAt(loop) ); - } - } - - //TODO: alphabetize files? - - return boards; - } - - private boolean doBlind() { - return (game.getOptions().booleanOption("double_blind") && - game.getPhase() >= IGame.PHASE_DEPLOYMENT); - } - - /** - * In a double-blind game, update only visible entities. Otherwise, - * update everyone - */ - private void entityUpdate(int nEntityID) { - entityUpdate(nEntityID, new Vector()); - } - - private void entityUpdate(int nEntityID, Vector movePath) { - Entity eTarget = game.getEntity(nEntityID); - if(eTarget == null) { - if(game.getOutOfGameEntity(nEntityID) != null) { - System.err.printf("S: attempted to send entity update for out of game entity, id was %d\n", nEntityID); - } else { - System.err.printf("S: attempted to send entity update for null entity, id was %d\n", nEntityID); - } - return; //do not send the update it will crash the client - } - if (doBlind()) { - Vector vPlayers = game.getPlayersVector(); - Vector vCanSee = whoCanSee(eTarget); - // send an entity update to everyone who can see - Packet pack = createEntityPacket(nEntityID, movePath); - for (int x = 0; x < vCanSee.size(); x++) { - Player p = (Player)vCanSee.elementAt(x); - send(p.getId(), pack); - } - // send an entity delete to everyone else - pack = createRemoveEntityPacket( nEntityID, - eTarget.getRemovalCondition() ); - for (int x = 0; x < vPlayers.size(); x++) { - if (!vCanSee.contains(vPlayers.elementAt(x))) { - Player p = (Player)vPlayers.elementAt(x); - send(p.getId(), pack); - } - } - } - else { - // everyone can see - send(createEntityPacket(nEntityID, movePath)); - } - } - - /** - * Returns a vector of which players can see this entity. - */ - private Vector whoCanSee(Entity entity) { - - //Some times Null entities are sent to this - if ( entity == null ) - return new Vector(); - - boolean bTeamVision = game.getOptions().booleanOption("team_vision"); - Vector vEntities = game.getEntitiesVector(); - - Vector vCanSee = new Vector(); - vCanSee.addElement(entity.getOwner()); - if (bTeamVision) { - addTeammates(vCanSee, entity.getOwner()); - } - - for (Enumeration p = game.getPlayers(); p.hasMoreElements();) { - Player player = (Player)p.nextElement(); - - if (player.canSeeAll() && !vCanSee.contains(p)) - vCanSee.addElement(player); - } - - for (int i = 0; i < vEntities.size(); i++) { - Entity e = (Entity)vEntities.elementAt(i); - if (vCanSee.contains(e.getOwner()) || !e.isActive()) { - continue; - } - if(e.isOffBoard()) { - continue; //Off board units should not spot on board units - } - if (Compute.canSee(game, e, entity)) { - vCanSee.addElement(e.getOwner()); - if (bTeamVision) { - addTeammates(vCanSee, e.getOwner()); - } - } - } - return vCanSee; - } - - private boolean canSee(Player p, Entity e) { - if (e.getOwner().getId() == p.getId()) { - //The owner of an entity should be able to see it, of course. - return true; - } - Vector playersWhoCanSee = whoCanSee(e); - for (int i = 0; i < playersWhoCanSee.size(); i++) { - Player currentPlayer = (Player)playersWhoCanSee.elementAt(i); - if (currentPlayer.equals(p)) { - return true; - } - } - - return false; - } - - /** - * Adds teammates of a player to the Vector. - * Utility function for whoCanSee. - */ - private void addTeammates(Vector vector, Player player) { - Vector vPlayers = game.getPlayersVector(); - for (int j = 0; j < vPlayers.size(); j++) { - Player p = (Player)vPlayers.elementAt(j); - if (!player.isEnemyOf(p) && !vector.contains(p)) { - vector.addElement(p); - } - } - } - - /** - * Send the complete list of entities to the players. - * If double_blind is in effect, enforce it by filtering the entities - */ - private void entityAllUpdate() { - if (doBlind()) { - Vector vPlayers = game.getPlayersVector(); - for (int x = 0; x < vPlayers.size(); x++) { - Player p = (Player)vPlayers.elementAt(x); - send(p.getId(), createFilteredEntitiesPacket(p)); - } - } - else { - send(createEntitiesPacket()); - } - } - - - /** - * Filters an entity vector according to LOS - */ - private Vector filterEntities(Player pViewer, Vector vEntities) { - Vector vCanSee = new Vector(); - Vector vAllEntities = game.getEntitiesVector(); - Vector vMyEntities = new Vector(); - boolean bTeamVision = game.getOptions().booleanOption("team_vision"); - - // If they can see all, return the input list - if (pViewer.canSeeAll()) { - return vEntities; - } - - for (int x = 0; x < vAllEntities.size(); x++) { - Entity e = (Entity)vAllEntities.elementAt(x); - if (e.getOwner() == pViewer || (bTeamVision && !e.getOwner().isEnemyOf(pViewer))) { - vMyEntities.addElement(e); - } - } - - for (int x = 0; x < vEntities.size(); x++) { - Entity e = (Entity)vEntities.elementAt(x); - if (vMyEntities.contains(e)) { - vCanSee.addElement(e); - continue; - } - for (int y = 0; y < vMyEntities.size(); y++) { - Entity e2 = (Entity)vMyEntities.elementAt(y); - if(e2.isOffBoard()) { - continue; - } - if (Compute.canSee(game, e2, e)) { - vCanSee.addElement(e); - break; - } - } - } - return vCanSee; - } - - //optimize and document me - private Vector filterReportVector(Vector originalReportVector, Player p) { - if (!doBlind()) { - //don't bother filtering if double-blind rules aren't in effect - return (Vector)originalReportVector.clone(); - } - Vector filteredReportVector = new Vector(); - Report r; - for (int i = 0; i < originalReportVector.size(); i++) { - r = (Report)originalReportVector.elementAt(i); - filteredReportVector.addElement(filterReport(r, p, false)); - } - - return filteredReportVector; - } - - /** - * Filter a single report so that the correct double-blind - * obscuration takes place. - * - * @param r the Report to filter - * @param p the Player that we are going to send the filtered report to - * @param omitCheck boolean indicating that this report hapened in - * the past, so we no longer have access to the Player - * @return a new Report, which has possibly been obscured - */ - private Report filterReport(Report r, Player p, boolean omitCheck) { - if (r.subject == Entity.NONE && r.type != Report.PUBLIC) { - //Reports that don't have a subject should be public. - System.err.println("Error: Attempting to filter a Report object that is not public yet has no subject.\n\t\tmessageId: " + r.messageId); - return r; - } - if (r.type == Report.PUBLIC || (p == null && !omitCheck)) { - return r; - } - Entity entity = game.getEntity(r.subject); - Player owner = null; - if (entity != null) - owner = entity.getOwner(); - if (!omitCheck && (entity == null || owner == null)) { - System.err.println("Error: Attempting to filter a Report object that is not public but has a subject (" + entity + ") with owner (" + owner + ").\n\tmessageId: " + r.messageId); - return r; - } - //off board (Artillery) units get treated as public messages - if ( entity.isOffBoard() ) - return r; - Report copy = new Report(r); - for (int j = 0; j < copy.dataCount(); j++) { - if (omitCheck || !canSee(p, entity)) { - if (r.isValueObscured(j)) { - copy.hideData(j); - //Mark the original report to indicate which players - // received an obscured version of it. - if (p != null) - r.addObscuredRecipient(p.getName()); - } - //simulate hiding the report for *true* double-blind play - //***DEBUG*** TESTING ONLY - //copy.markForTesting(); - } - } - return copy; - } - - private Vector filterPastReports(Vector pastReports, Player p) { - //This stuff really only needs to be printed for debug reasons. other wise the logs get - //filled to the brim when ever someone connects. --Torren. - System.err.println("filterPastReports() begin"); - System.err.println(" player is " + p.getName()); - if (doBlind()) { - //System.err.println(" pastReports vector is\n" + pastReports); - Vector filteredReports = new Vector(); - Vector filteredRoundReports = new Vector(); - Vector roundReports = new Vector(); - Report r; - for (int i = 0; i < pastReports.size(); i++) { - roundReports = (Vector)pastReports.elementAt(i); - //System.err.println(" roundReports vector is\n" + roundReports); - for (int j = 0; j < roundReports.size(); j++) { - r = (Report)roundReports.elementAt(j); - if (r.isObscuredRecipient(p.getName())) { - //System.err.println(" report is " + r + " -obscuring-"); - filteredRoundReports.addElement(filterReport(r, null, true)); - } else { - //System.err.println(" report is " + r); - filteredRoundReports.addElement(r); - } - } - //System.err.println(" filteredRoundReport is\n" + filteredRoundReports); - filteredReports.addElement(filteredRoundReports.clone()); - filteredRoundReports.removeAllElements(); - } - System.err.println("filterPastReports() end"); - return filteredReports; - } else { - //don't bother filtering if double-blind rules aren't in effect - System.err.println("filterPastReports() end"); - return pastReports; - } - } - - /** - * Updates entities graphical "visibility indications" which are used - * in double-blind games. - */ - private void updateVisibilityIndicator() { - Vector vAllEntities = game.getEntitiesVector(); - for (int x = 0; x < vAllEntities.size(); x++) { - Entity e = (Entity)vAllEntities.elementAt(x); - boolean previousVisibleValue = e.isVisibleToEnemy(); - boolean previousSeenValue = e.isSeenByEnemy(); - e.setVisibleToEnemy(false); - Vector vCanSee = whoCanSee(e); - for (int y = 0; y < vCanSee.size(); y++) { - Player p = (Player)vCanSee.elementAt(y); - if (e.getOwner().isEnemyOf(p) && !p.isObserver()) { - e.setVisibleToEnemy(true); - e.setSeenByEnemy(true); - } - } - if (previousVisibleValue != e.isVisibleToEnemy() - || previousSeenValue != e.isSeenByEnemy()) { - sendVisibilityIndicator(e); - } - } - } - - /** - * Checks if an entity added by the client is valid and if so, adds it to the list - */ - private void receiveEntityAdd(Packet c, int connIndex) { - final Entity entity = (Entity)c.getObject(0); - - //Verify the entity's design - if (Server.entityVerifier == null) - Server.entityVerifier = new EntityVerifier(new File(VERIFIER_CONFIG_FILENAME)); - // we can only test meks and vehicles right now - if (entity instanceof Mech || entity instanceof Tank) { - TestEntity testEntity = null; - entity.restore(); - if (entity instanceof Mech) - testEntity = new TestMech((Mech)entity, Server.entityVerifier.mechOption, null); - if (entity instanceof VTOL) - testEntity = new TestTank((Tank)entity, Server.entityVerifier.tankOption, null);//not implemented yet. - if (entity instanceof Tank) - testEntity = new TestTank((Tank)entity, Server.entityVerifier.tankOption, null); - StringBuffer sb = new StringBuffer(); - if (testEntity.correctEntity(sb, !game.getOptions().booleanOption("is_eq_limits"))) { - entity.setDesignValid(true); - } else { - if (game.getOptions().booleanOption("allow_illegal_units")) { - entity.setDesignValid(false); - } else { - Player cheater = game.getPlayer( connIndex ); - sendServerChat("Player " + cheater.getName() + " attempted to add an illegal unit design (" + entity.getShortNameRaw() + "), the unit was rejected."); - System.err.println(sb); - return; - } - } - } - - // If we're adding a Protomech, calculate it's unit number. - if ( entity instanceof Protomech ) { - - // How many Protomechs does the player already have? - int numPlayerProtos = game.getSelectedEntityCount - ( new EntitySelector() { - private final int ownerId = entity.getOwnerId(); - public boolean accept( Entity entity ) { - if ( entity instanceof Protomech && - ownerId == entity.getOwnerId() ) - return true; - return false; - } - } ); - - // According to page 54 of the BMRr, Protomechs must be - // deployed in full Points of five, unless circumstances have - // reduced the number to less that that. - entity.setUnitNumber( (char) (numPlayerProtos / 5) ); - - } // End added-Protomech - - // Only assign an entity ID when the client hasn't. - if ( Entity.NONE == entity.getId() ) { - entity.setId(getFreeEntityId()); - } - - game.addEntity(entity.getId(), entity); - send(createAddEntityPacket(entity.getId())); - } - - /** - * Updates an entity with the info from the client. Only valid to do this - * during the lounge phase, except for heat sink changing. - */ - private void receiveEntityUpdate(Packet c, int connIndex) { - Entity entity = (Entity)c.getObject(0); - Entity oldEntity = game.getEntity(entity.getId()); - if (oldEntity != null && oldEntity.getOwner() == getPlayer(connIndex)) { - game.setEntity(entity.getId(), entity); - entityUpdate(entity.getId()); - // In the chat lounge, notify players of customizing of unit - if (game.getPhase() == IGame.PHASE_LOUNGE) { - StringBuffer message = new StringBuffer(); - message.append( "Unit " ); - if(game.getOptions().booleanOption("blind_drop") - || game.getOptions().booleanOption("real_blind_drop")) { - if(Entity.NONE != entity.getExternalId()) { - message.append("[").append(entity.getExternalId()).append("] "); - } - message.append(entity.getId()) - .append("(") - .append(entity.getOwner().getName()) - .append(")"); - } else { - message.append( entity.getDisplayName() ); - } - message.append( " has been customized." ); - sendServerChat( message.toString() ); - } - } else { - // hey! - } - } - - private void receiveEntityModeChange(Packet c, int connIndex) { - int entityId = c.getIntValue(0); - int equipId = c.getIntValue(1); - int mode = c.getIntValue(2); - Entity e = game.getEntity(entityId); - if (e.getOwner() != getPlayer(connIndex)) { - return; - } - Mounted m = e.getEquipment(equipId); - - // a mode change for ammo means dumping - if (m.getType() instanceof AmmoType - && !(m.getType().hasInstantModeSwitch())) { - m.setPendingDump(mode == 1); - } - else { - m.setMode(mode); - } - } - - private void receiveEntitySystemModeChange(Packet c, int connIndex) { - int entityId = c.getIntValue(0); - int equipId = c.getIntValue(1); - int mode = c.getIntValue(2); - Entity e = game.getEntity(entityId); - if (e.getOwner() != getPlayer(connIndex)) { - return; - } - if(e instanceof Mech && equipId == Mech.SYSTEM_COCKPIT) { - ((Mech)e).setCockpitStatus(mode); - } - } - - private void receiveEntityAmmoChange(Packet c, int connIndex) { - int entityId = c.getIntValue(0); - int weaponId = c.getIntValue(1); - int ammoId = c.getIntValue(2); - Entity e = game.getEntity(entityId); - - // Did we receive a request for a valid Entity? - if ( null == e ) { - System.err.print - ( "Server.receiveEntityAmmoChange: could not find entity #" ); - System.err.println( entityId ); - return; - } - Player player = getPlayer( connIndex ); - if ( null != player && e.getOwner() != player ) { - System.err.print - ( "Server.receiveEntityAmmoChange: player " ); - System.err.print( player.getName() ); - System.err.print( " does not own the entity " ); - System.err.println( e.getDisplayName() ); - return; - } - - // Make sure that the entity has the given equipment. - Mounted mWeap = e.getEquipment(weaponId); - Mounted mAmmo = e.getEquipment(ammoId); - if ( null == mAmmo ) { - System.err.print - ( "Server.receiveEntityAmmoChange: entity " ); - System.err.print( e.getDisplayName() ); - System.err.print( " does not have ammo #" ); - System.err.println( ammoId ); - return; - } - if ( !(mAmmo.getType() instanceof AmmoType) ) { - System.err.print - ( "Server.receiveEntityAmmoChange: item # " ); - System.err.print( ammoId ); - System.err.print( " of entity " ); - System.err.print( e.getDisplayName() ); - System.err.print( " is a " ); - System.err.print( mAmmo.getName() ); - System.err.println( " and not ammo." ); - return; - } - if ( null == mWeap ) { - System.err.print - ( "Server.receiveEntityAmmoChange: entity " ); - System.err.print( e.getDisplayName() ); - System.err.print( " does not have weapon #" ); - System.err.println( weaponId ); - return; - } - if ( !(mWeap.getType() instanceof WeaponType) ) { - System.err.print - ( "Server.receiveEntityAmmoChange: item # " ); - System.err.print( weaponId ); - System.err.print( " of entity " ); - System.err.print( e.getDisplayName() ); - System.err.print( " is a " ); - System.err.print( mWeap.getName() ); - System.err.println( " and not a weapon." ); - return; - } - if ( ((WeaponType) mWeap.getType()).getAmmoType() == AmmoType.T_NA ) { - System.err.print - ( "Server.receiveEntityAmmoChange: item # " ); - System.err.print( weaponId ); - System.err.print( " of entity " ); - System.err.print( e.getDisplayName() ); - System.err.print( " is a " ); - System.err.print( mWeap.getName() ); - System.err.println( " and does not use ammo." ); - return; - } - if ( ((WeaponType) mWeap.getType()).hasFlag(WeaponType.F_ONESHOT)) { - System.err.print - ( "Server.receiveEntityAmmoChange: item # " ); - System.err.print( weaponId ); - System.err.print( " of entity " ); - System.err.print( e.getDisplayName() ); - System.err.print( " is a " ); - System.err.print( mWeap.getName() ); - System.err.println( " and cannot use external ammo." ); - return; - } - - // Load the weapon. - e.loadWeapon( mWeap, mAmmo ); - } - - /** - * Deletes an entity owned by a certain player from the list - */ - private void receiveEntityDelete(Packet c, int connIndex) { - int entityId = c.getIntValue(0); - final Entity entity = game.getEntity(entityId); - - // Only allow players to delete their *own* entities. - if ( entity != null && entity.getOwner() == getPlayer(connIndex) ) { - - // If we're deleting a Protomech, recalculate unit numbers. - if ( entity instanceof Protomech ) { - - // How many Protomechs does the player have (include this one)? - int numPlayerProtos = game.getSelectedEntityCount - ( new EntitySelector() { - private final int ownerId = entity.getOwnerId(); - public boolean accept( Entity entity ) { - if ( entity instanceof Protomech && - ownerId == entity.getOwnerId() ) - return true; - return false; - } - } ); - - // According to page 54 of the BMRr, Protomechs must be - // deployed in full Points of five, unless "losses" have - // reduced the number to less that that. - final char oldMax = - (char)(Math.ceil( numPlayerProtos / 5.0 )-1); - char newMax = - (char)(Math.ceil( (numPlayerProtos-1)/ 5.0 )-1); - char deletedUnitNum = entity.getUnitNumber(); - - // Do we have to update a Protomech from the last unit? - if ( oldMax != deletedUnitNum && oldMax != newMax ) { - - // Yup. Find a Protomech from the last unit, and - // set it's unit number to the deleted entity. - Enumeration lastUnit = game.getSelectedEntities - ( new EntitySelector() { - private final int ownerId = entity.getOwnerId(); - private final char lastUnitNum = oldMax; - public boolean accept( Entity entity ) { - if ( entity instanceof Protomech && - ownerId == entity.getOwnerId() && - lastUnitNum == entity.getUnitNumber() ) - return true; - return false; - } - } ); - Entity lastUnitMember = (Entity) lastUnit.nextElement(); - lastUnitMember.setUnitNumber( deletedUnitNum ); - this.entityUpdate( lastUnitMember.getId() ); - - } // End update-unit-numbetr - - } // End added-Protomech - - game.removeEntity(entityId, IEntityRemovalConditions.REMOVE_NEVER_JOINED); - send(createRemoveEntityPacket(entityId, IEntityRemovalConditions.REMOVE_NEVER_JOINED)); - } - } - - /** - * Sets a player's ready status - */ - private void receivePlayerDone(Packet pkt, int connIndex) { - boolean ready = pkt.getBooleanValue(0); - Player player = getPlayer(connIndex); - if ( null != player ) { - player.setDone(ready); - } - } - - private void receiveInitiativeRerollRequest(Packet pkt, int connIndex) { - Player player = getPlayer(connIndex); - if ( IGame.PHASE_INITIATIVE_REPORT != game.getPhase() ) { - StringBuffer message = new StringBuffer(); - if ( null == player ) { - message.append( "Player #" ) - .append( connIndex ); - } else { - message.append( player.getName() ); - } - message.append( " is not allowed to ask for a reroll at this time." ); - System.err.println( message.toString() ); - sendServerChat( message.toString() ); - return; - } - if (game.hasTacticalGenius(player)) { - game.addInitiativeRerollRequest(game.getTeamForPlayer(player)); - } - if ( null != player ) { - player.setDone(true); - } - checkReady(); - } - - /** - * Sets game options, providing that the player has specified the password - * correctly. - * - * @return true if any options have been successfully changed. - */ - private boolean receiveGameOptions(Packet packet, int connId) { - Player player = game.getPlayer( connId ); - // Check player - if ( null == player ) { - System.err.print - ( "Server does not recognize player at connection " ); - System.err.println( connId ); - return false; - } - - // check password - if (password != null && password.length() > 0 && !password.equals(packet.getObject(0))) { - sendServerChat(connId, "The password you specified to change game options is incorrect."); - return false; - } - - int changed = 0; - - for (Enumeration i = ((Vector)packet.getObject(1)).elements(); i.hasMoreElements();) { - IBasicOption option = (IBasicOption)i.nextElement(); - IOption originalOption = game.getOptions().getOption(option.getName()); - - if (originalOption == null) { - continue; - } - - StringBuffer message = new StringBuffer(); - message.append( "Player " ) - .append( player.getName() ) - .append( " changed option \"" ) - .append( originalOption.getDisplayableName() ) - .append( "\" to " ) - .append( option.getValue().toString() ) - .append( "." ); - sendServerChat( message.toString() ); - originalOption.setValue(option.getValue()); - changed++; - } - - // Set proper RNG - Compute.setRNG(game.getOptions().intOption("rng_type")); - - return changed > 0; - } - - /** - * Performs the additional processing of the received options after the the - * receiveGameOptions done its job; should be called after - * receiveGameOptions only if the receiveGameOptions - * returned true - * @param packet - * @param connId - */ - private void receiveGameOptionsAux(Packet packet, int connId) { - - for (Enumeration i = ((Vector)packet.getObject(1)).elements(); i.hasMoreElements();) { - IBasicOption option = (IBasicOption)i.nextElement(); - IOption originalOption = game.getOptions().getOption(option.getName()); - if (originalOption != null) { - if ("maps_include_subdir".equals(originalOption.getName())) { - mapSettings.setBoardsAvailableVector(scanForBoards(mapSettings.getBoardWidth(), mapSettings.getBoardHeight())); - mapSettings.removeUnavailable(); - mapSettings.setNullBoards(DEFAULT_BOARD); - send(createMapSettingsPacket()); - } - } - } - - } - - /** - * Sends out all player info to the specified connection - */ - private void transmitAllPlayerConnects(int connId) { - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - final Player player = (Player)i.nextElement(); - - send(connId, createPlayerConnectPacket(player.getId())); - } - } - - - - /** - * Creates a packet informing that the player has connected - */ - private Packet createPlayerConnectPacket(int playerId) { - final Object[] data = new Object[2]; - data[0] = new Integer(playerId); - data[1] = getPlayer(playerId); - return new Packet(Packet.COMMAND_PLAYER_ADD, data); - } - - /** - * Creates a packet containing the player info, for update - */ - private Packet createPlayerUpdatePacket(int playerId) { - final Object[] data = new Object[2]; - data[0] = new Integer(playerId); - data[1] = getPlayer(playerId); - return new Packet(Packet.COMMAND_PLAYER_UPDATE, data); - } - - /** - * Sends out the player info updates for all players to all connections - */ - private void transmitAllPlayerUpdates() { - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - final Player player = (Player)i.nextElement(); - if ( null != player ) { - send(createPlayerUpdatePacket(player.getId())); - } - } - } - - /** - * Sends out the player ready stats for all players to all connections - */ - private void transmitAllPlayerDones() { - for (Enumeration i = game.getPlayers(); i.hasMoreElements();) { - final Player player = (Player)i.nextElement(); - - send(createPlayerDonePacket(player.getId())); - } - } - - /** - * Creates a packet containing the player ready status - */ - private Packet createPlayerDonePacket(int playerId) { - Object[] data = new Object[2]; - data[0] = new Integer(playerId); - data[1] = new Boolean(getPlayer(playerId).isDone()); - return new Packet(Packet.COMMAND_PLAYER_READY, data); - } - - /** Creates a packet containing the current turn vector */ - private Packet createTurnVectorPacket() { - return new Packet(Packet.COMMAND_SENDING_TURNS, game.getTurnVector()); - } - - /** Creates a packet containing the current turn index */ - private Packet createTurnIndexPacket() { - return new Packet(Packet.COMMAND_TURN, new Integer(game.getTurnIndex())); - } - - /** - * Creates a packet containing the map settings - */ - private Packet createMapSettingsPacket() { - return new Packet(Packet.COMMAND_SENDING_MAP_SETTINGS, mapSettings); - } - - /** - * Creates a packet containing temporary map settings as a response to a - * client query - */ - private Packet createMapQueryPacket(MapSettings temp) { - return new Packet(Packet.COMMAND_QUERY_MAP_SETTINGS, temp); - } - - /** - * Creates a packet containing the game settingss - */ - private Packet createGameSettingsPacket() { - return new Packet(Packet.COMMAND_SENDING_GAME_SETTINGS, game.getOptions()); - } - - /** - * Creates a packet containing the game board - */ - private Packet createBoardPacket() { - return new Packet(Packet.COMMAND_SENDING_BOARD, game.getBoard()); - } - - /** - * Creates a packet containing a single entity, for update - */ - private Packet createEntityPacket(int entityId) { - return createEntityPacket(entityId, new Vector()); - } - private Packet createEntityPacket(int entityId, Vector movePath) { - final Entity entity = game.getEntity(entityId); - final Object[] data = new Object[3]; - data[0] = new Integer(entityId); - data[1] = entity; - data[2] = movePath; - return new Packet(Packet.COMMAND_ENTITY_UPDATE, data); - } - - /** - * Creates a packet containing a Vector of Reports - */ - private Packet createReportPacket(Player p) { - //when the final report is created MM sends a null player to create the - //report so this will handel that issue. - if ( p == null || !doBlind() ) - return new Packet(Packet.COMMAND_SENDING_REPORTS, filterReportVector(vPhaseReport, p)); - else - return new Packet(Packet.COMMAND_SENDING_REPORTS, p.getTurnReport()); - } - - /** - * Creates a packet containing a Vector of special Reports which - * needs to be sent during a phase that is not a report phase. - */ - private Packet createSpecialReportPacket() { - return new Packet(Packet.COMMAND_SENDING_REPORTS_SPECIAL, vPhaseReport.clone()); - } - - /** - * Creates a packet containing a Vector of Reports that represent - * a Tactical Genius re-roll request which needs to update a - * current phase's report. - */ - private Packet createTacticalGeniusReportPacket() { - return new Packet(Packet.COMMAND_SENDING_REPORTS_TACTICAL_GENIUS, vPhaseReport.clone()); - } - - /** - * Creates a packet containing all the round reports - */ - private Packet createAllReportsPacket(Player p) { - return new Packet(Packet.COMMAND_SENDING_REPORTS_ALL, filterPastReports(game.getAllReports(), p)); - } - - /** - * Creates a packet containing all current entities - */ - private Packet createEntitiesPacket() { - return new Packet(Packet.COMMAND_SENDING_ENTITIES, game.getEntitiesVector()); - } - - /** - * Creates a packet containing all current and out-of-game entities - */ - private Packet createFullEntitiesPacket() { - final Object[] data = new Object[2]; - data[0] = game.getEntitiesVector(); - data[1] = game.getOutOfGameEntitiesVector(); - return new Packet(Packet.COMMAND_SENDING_ENTITIES, data); - } - - /** - * Creates a packet containing all entities visible to the player in a blind game - */ - private Packet createFilteredEntitiesPacket(Player p) { - return new Packet(Packet.COMMAND_SENDING_ENTITIES, filterEntities(p, game.getEntitiesVector())); - } - - /** - * Creates a packet containing all entities, including wrecks, visible to the player in a blind game - */ - private Packet createFilteredFullEntitiesPacket(Player p) { - final Object[] data = new Object[2]; - data[0] = filterEntities(p, game.getEntitiesVector()); - data[1] = game.getOutOfGameEntitiesVector(); - return new Packet(Packet.COMMAND_SENDING_ENTITIES, data); - } - - /** - * Creates a packet detailing the addition of an entity - */ - private Packet createAddEntityPacket(int entityId) { - final Entity entity = game.getEntity(entityId); - final Object[] data = new Object[2]; - data[0] = new Integer(entityId); - data[1] = entity; - return new Packet(Packet.COMMAND_ENTITY_ADD, data); - } - - /** - * Creates a packet detailing the removal of an entity. - * Maintained for backwards compatability. - * - * @param entityId - the int ID of the entity being removed. - * @return A Packet to be sent to clients. - */ - private Packet createRemoveEntityPacket(int entityId) { - return this.createRemoveEntityPacket(entityId, IEntityRemovalConditions.REMOVE_SALVAGEABLE); - } - - /** - * Creates a packet detailing the removal of an entity. - * - * @param entityId - the int ID of the entity being removed. - * @param condition - the int condition the unit was in. - * This value must be one of Game.UNIT_IN_RETREAT, - * Game.UNIT_PUSHED, or - * Game.UNIT_SALVAGEABLE, or - * Game.UNIT_EJECTED, or - * Game.UNIT_DEVASTATED or an - * IllegalArgumentException will be thrown. - * @return A Packet to be sent to clients. - */ - private Packet createRemoveEntityPacket(int entityId, int condition) { - if ( condition != IEntityRemovalConditions.REMOVE_UNKNOWN && - condition != IEntityRemovalConditions.REMOVE_IN_RETREAT && - condition != IEntityRemovalConditions.REMOVE_PUSHED && - condition != IEntityRemovalConditions.REMOVE_SALVAGEABLE && - condition != IEntityRemovalConditions.REMOVE_EJECTED && - condition != IEntityRemovalConditions.REMOVE_CAPTURED && - condition != IEntityRemovalConditions.REMOVE_DEVASTATED && - condition != IEntityRemovalConditions.REMOVE_NEVER_JOINED ) { - throw new IllegalArgumentException( "Unknown unit condition: " + - condition ); - } - Object[] array = new Object[2]; - array[0] = new Integer(entityId); - array[1] = new Integer(condition); - return new Packet(Packet.COMMAND_ENTITY_REMOVE, array); - } - - /** - * Creates a packet indicating end of game, including detailed unit status - */ - private Packet createEndOfGamePacket() { - Object[] array = new Object[3]; - array[0] = getDetailedVictoryReport(); - array[1] = new Integer(game.getVictoryPlayerId()); - array[2] = new Integer(game.getVictoryTeam()); - return new Packet(Packet.COMMAND_END_OF_GAME, array); - } - - /** - * Transmits a chat message to all players - */ - private void sendChat(int connId, String origin, String message) { - send(connId, new Packet(Packet.COMMAND_CHAT, origin + ": " + message)); - } - - /** - * Transmits a chat message to all players - */ - private void sendChat(String origin, String message) { - String chat = origin + ": " + message; - send(new Packet(Packet.COMMAND_CHAT, chat)); - } - - public void sendServerChat(int connId, String message) { - sendChat(connId, "***Server", message); - } - - public void sendServerChat(String message) { - sendChat("***Server", message); - } - - /** - * Creates a packet containing a hex, and the coordinates it goes at. - */ - private Packet createHexChangePacket(Coords coords, IHex hex) { - final Object[] data = new Object[2]; - data[0] = coords; - data[1] = hex; - return new Packet(Packet.COMMAND_CHANGE_HEX, data); - } - - /** - * Sends notification to clients that the specified hex has changed. - */ - public void sendChangedHex(Coords coords) { - send(createHexChangePacket(coords, game.getBoard().getHex(coords))); - } - - public void sendVisibilityIndicator(Entity e) { - final Object[] data = new Object[3]; - data[0] = new Integer(e.getId()); - data[1] = new Boolean(e.isSeenByEnemy()); - data[2] = new Boolean(e.isVisibleToEnemy()); - send(new Packet(Packet.COMMAND_ENTITY_VISIBILITY_INDICATOR, data)); - } - - /** - * Creates a packet for an attack - */ - private Packet createAttackPacket(Vector vector, int charges) { - final Object[] data = new Object[2]; - data[0] = vector; - data[1] = new Integer(charges); - return new Packet(Packet.COMMAND_ENTITY_ATTACK, data); - } - - /** - * Creates a packet for an attack - */ - private Packet createAttackPacket(EntityAction ea, int charge) { - Vector vector = new Vector(1); - vector.addElement(ea); - Object[] data = new Object[2]; - data[0] = vector; - data[1] = new Integer(charge); - return new Packet(Packet.COMMAND_ENTITY_ATTACK, data); - } - - /** - * Creates a packet containing offboard artillery attacks - **/ - private Packet createArtilleryPacket(Player p) { - - if(p.getSeeAll()) { - return new Packet(Packet.COMMAND_SENDING_ARTILLERYATTACKS, game.getArtilleryVector()); - } - Vector v = new Vector(); - int team = p.getTeam(); - for(Enumeration i = game.getArtilleryAttacks();i.hasMoreElements();) { - ArtilleryAttackAction aaa = (ArtilleryAttackAction)i.nextElement(); - if(aaa.getPlayerId() == p.getId() || - (team != Player.TEAM_NONE && team == game.getPlayer(aaa.getPlayerId()).getTeam())) { - v.addElement(aaa); - } - } - return new Packet(Packet.COMMAND_SENDING_ARTILLERYATTACKS, v); - } - - /** - * Creates a packet containing flares - **/ - private Packet createFlarePacket() { - - return new Packet(Packet.COMMAND_SENDING_FLARES, game.getFlares()); - } - - /** - * Send a packet to all connected clients. - */ - private void send(Packet packet) { - if (connections == null) { - return; - } - for (Enumeration i = connections.elements(); i.hasMoreElements();) { - final Connection conn = (Connection)i.nextElement(); - conn.send(packet); - } - } - - private void sendReport() { - sendReport(false); - } - - /** - * Send the round report to all connected clients. - */ - private void sendReport(boolean tacticalGeniusReport) { - if (connections == null) { - return; - } - - for (Enumeration i = connections.elements(); i.hasMoreElements();) { - final Connection conn = (Connection)i.nextElement(); - Player p = game.getPlayer(conn.getId()); - Packet packet; - if (tacticalGeniusReport) - packet = createTacticalGeniusReportPacket(); - else - packet = createReportPacket(p); - conn.send(packet); - } - } - - /** - * Send a packet to a specific connection. - */ - private void send(int connId, Packet packet) { - if (getClient(connId) != null) { - getClient(connId).send(packet); - } else { - //What should we do if we've lost this client? - // For now, nothing. - } - } - - /** - * Send a packet to a pending connection - */ - private void sendToPending(int connId, Packet packet) { - if (getPendingConnection(connId) != null) { - getPendingConnection(connId).send(packet); - } else { - //What should we do if we've lost this client? - // For now, nothing. - } - } - - /** - * Process an in-game command - */ - private void processCommand(int connId, String commandString) { - String[] args; - String commandName; - // all tokens are read as strings; if they're numbers, string-ize 'em. - StringTokenizer st = new StringTokenizer(commandString); - args = new String[st.countTokens()]; - for (int i = 0; i < args.length; i++) { - args[i] = st.nextToken(); - } - - // figure out which command this is - commandName = args[0].substring(1); - - // process it - ServerCommand command = getCommand(commandName); - if (command != null) { - command.run(connId, args); - } else { - sendServerChat(connId, "Command not recognized. Type /help for a list of commands."); - } - } - - // Easter eggs. Happy April Fool's Day!! - private static final String DUNE_CALL = "They tried and failed?"; - private static final String DUNE_RESPONSE = "They tried and died!"; - private static final String STAR_WARS_CALL = "I'd just as soon kiss a Wookiee."; - private static final String STAR_WARS_RESPONSE = "I can arrange that!"; - - /** - * Process a packet from a connection. - * - * @param id - the int ID the connection that - * received the packet. - * @param packet - the Packet to be processed. - */ - protected synchronized void handle(int connId, Packet packet) { - Player player = game.getPlayer( connId ); - // Check player. Please note, the connection may be pending. - if ( null == player && null == getPendingConnection(connId) ) { - System.err.print - ( "Server does not recognize player at connection " ); - System.err.println( connId ); - return; - } - - //System.out.println("s(" + cn + "): received command"); - if (packet == null) { - System.out.println("server.connection.handle: got null packet"); - return; - } - // act on it - switch(packet.getCommand()) { - case Packet.COMMAND_CLOSE_CONNECTION : - // We have a client going down! - Connection c = getConnection(connId); - if ( c!= null) { - c.close(); - } - break; - case Packet.COMMAND_CLIENT_NAME : - receivePlayerName(packet, connId); - break; - case Packet.COMMAND_PLAYER_UPDATE : - receivePlayerInfo(packet, connId); - validatePlayerInfo(connId); - send(createPlayerUpdatePacket(connId)); - break; - case Packet.COMMAND_PLAYER_READY : - receivePlayerDone(packet, connId); - send(createPlayerDonePacket(connId)); - checkReady(); - break; - case Packet.COMMAND_REROLL_INITIATIVE : - receiveInitiativeRerollRequest(packet, connId); - send(createPlayerDonePacket(connId)); - break; - case Packet.COMMAND_CHAT : - String chat = (String)packet.getObject(0); - if (chat.startsWith("/")) { - processCommand(connId, chat); - } else { - sendChat(player.getName(), chat); - } - // Easter eggs. Happy April Fool's Day!! - if ( DUNE_CALL.equals(chat) ) { - sendServerChat( DUNE_RESPONSE ); - } - else if ( STAR_WARS_CALL.equals(chat) ) { - sendServerChat( STAR_WARS_RESPONSE ); - } - break; - case Packet.COMMAND_ENTITY_MOVE : - receiveMovement(packet, connId); - break; - case Packet.COMMAND_ENTITY_DEPLOY : - receiveDeployment(packet, connId); - break; - case Packet.COMMAND_DEPLOY_MINEFIELDS : - receiveDeployMinefields(packet, connId); - break; - case Packet.COMMAND_ENTITY_ATTACK : - receiveAttack(packet, connId); - break; - case Packet.COMMAND_ENTITY_ADD : - receiveEntityAdd(packet, connId); - resetPlayersDone(); - transmitAllPlayerDones(); - break; - case Packet.COMMAND_ENTITY_UPDATE : - receiveEntityUpdate(packet, connId); - resetPlayersDone(); - transmitAllPlayerDones(); - break; - case Packet.COMMAND_ENTITY_MODECHANGE : - receiveEntityModeChange(packet, connId); - break; - case Packet.COMMAND_ENTITY_SYSTEMMODECHANGE : - receiveEntitySystemModeChange(packet, connId); - break; - case Packet.COMMAND_ENTITY_AMMOCHANGE : - receiveEntityAmmoChange(packet, connId); - break; - case Packet.COMMAND_ENTITY_REMOVE : - receiveEntityDelete(packet, connId); - resetPlayersDone(); - transmitAllPlayerDones(); - break; - case Packet.COMMAND_SENDING_GAME_SETTINGS : - if (receiveGameOptions(packet, connId)) { - resetPlayersDone(); - transmitAllPlayerDones(); - send(createGameSettingsPacket()); - receiveGameOptionsAux(packet, connId); - } - break; - case Packet.COMMAND_SENDING_MAP_SETTINGS : - MapSettings newSettings=(MapSettings)packet.getObject(0); - if (!mapSettings.equalMapGenParameters(newSettings)) { - sendServerChat("Player " + player.getName() + - " changed mapsettings"); - } - mapSettings = newSettings; - newSettings = null; - mapSettings.replaceBoardWithRandom(MapSettings.BOARD_RANDOM); - resetPlayersDone(); - transmitAllPlayerDones(); - send(createMapSettingsPacket()); - break; - case Packet.COMMAND_QUERY_MAP_SETTINGS : - MapSettings temp = (MapSettings)packet.getObject(0); - temp.setBoardsAvailableVector(scanForBoards(temp.getBoardWidth(), temp.getBoardHeight())); - temp.removeUnavailable(); - temp.setNullBoards(DEFAULT_BOARD); - temp.replaceBoardWithRandom(MapSettings.BOARD_RANDOM); - temp.removeUnavailable(); - send(connId, createMapQueryPacket(temp)); - break; - case Packet.COMMAND_UNLOAD_STRANDED : - receiveUnloadStranded(packet, connId); - break; - case Packet.COMMAND_SET_ARTYAUTOHITHEXES : - receiveArtyAutoHitHexes(packet, connId); - } - } - - - /** - * Listen for incoming clients. - */ - public void run() { - Thread currentThread = Thread.currentThread(); - System.out.println("s: listening for clients..."); - while (connector == currentThread) { - try { - Socket s = serverSocket.accept(); - - int id = getFreeConnectionId(); - System.out.println("s: accepting player connection #" + id + " ..."); - - Connection c = ConnectionFactory.getInstance().createServerConnection(s, id); - c.addConnectionListener(connectionListener); - c.open(); - connectionsPending.addElement(c); - - greeting(id); - } catch(IOException ex) { - - } - } - } - - /** - * Makes one slot of inferno ammo, determined - * by certain rules, explode on a mech. - * - * @param entity The Entity that should suffer an - * inferno ammo explosion. - */ - private Vector explodeInfernoAmmoFromHeat(Entity entity) { - int damage = 0; - int rack = 0; - int boomloc = -1; - int boomslot = -1; - Vector vDesc = new Vector(); - Report r; - - // Find the most destructive Inferno ammo. - for (int j = 0; j < entity.locations(); j++) { - for (int k = 0; k < entity.getNumberOfCriticals(j); k++) { - CriticalSlot cs = entity.getCritical(j, k); - // Ignore empty, destroyed, hit, and structure slots. - if ( cs == null || cs.isDestroyed() || cs.isHit() || - cs.getType() != CriticalSlot.TYPE_EQUIPMENT ) { - continue; - } - // Ignore everything but weapons slots. - Mounted mounted = entity.getEquipment - ( entity.getCritical(j, k).getIndex() ); - if (!(mounted.getType() instanceof AmmoType)) { - continue; - } - // Ignore everything but Inferno ammo. - AmmoType atype = (AmmoType)mounted.getType(); - if ( !atype.isExplosive() || - atype.getMunitionType() != AmmoType.M_INFERNO) { - continue; - } - // Find the most destructive undamaged ammo. - // BMRr, pg. 48, compare one rack's - // damage. Ties go to most rounds. - int newRack = atype.getDamagePerShot() * atype.getRackSize(); - int newDamage = mounted.getExplosionDamage(); - if ( !mounted.isHit() && ( rack < newRack || - (rack == newRack && damage < newDamage) ) ) { - rack = newRack; - damage = newDamage; - boomloc = j; - boomslot = k; - } - } - } - // Did we find anything to explode? - if (boomloc != -1 && boomslot != -1) { - CriticalSlot slot = entity.getCritical(boomloc, boomslot); - slot.setHit(true); - entity.getEquipment(slot.getIndex()).setHit(true); - // We've allocated heatBuildup to heat in resolveHeat(), - // so need to add to the entity's heat instead. - vDesc.addAll( explodeEquipment(entity, boomloc, boomslot)); - entity.heat += 30; - r = new Report(5155); - r.indent(); - r.subject = entity.getId(); - r.add(entity.heat); - vDesc.addElement(r); - entity.heatBuildup = 0; - } else { //no ammo to explode - r = new Report(5160); - r.indent(); - r.subject = entity.getId(); - vDesc.addElement(r); - } - return vDesc; - } - - /** - * Determine the results of an entity moving through a wall of a building - * after having moved a certain distance. This gets called when a Mech - * or a Tank enters a building, leaves a building, or travels from one - * hex to another inside a multi-hex building. - * - * @param entity - the Entity that passed through a wall. - * Don't pass Infantry units to this method. - * @param bldg - the Building the entity is passing through. - * @param lastPos - the Coords of the hex the entity is - * exiting. - * @param curPos - the Coords of the hex the entity is - * entering - * @param distance - the int number of hexes the entity - * has moved already this phase. - * @param why - the String explanatin for this action. - * @return true if the building collapses due to overloading. - */ - private boolean passBuildingWall( Entity entity, - Building bldg, - Coords lastPos, - Coords curPos, - int distance, - String why ) { - - Report r; - - // Need to roll based on building type. - PilotingRollData psr = entity.rollMovementInBuilding(bldg, distance, why); - - // Did the entity make the roll? - if ( !doSkillCheckWhileMoving( entity, lastPos, - curPos, psr, false ) ) { - - // Divide the building's current CF by 10, round up. - int damage = (int) Math.ceil( bldg.getCurrentCF() / 10.0 ); - - // It is possible that the unit takes no damage. - if ( damage == 0 ) { - r = new Report(6440); - r.add(entity.getDisplayName()); - r.subject = entity.getId(); - r.indent(2); - addReport(r); - } else { - // BMRr, pg. 50: The attack direction for this damage is the front. - HitData hit = entity.rollHitLocation( ToHitData.HIT_NORMAL, - ToHitData.SIDE_FRONT ); - addReport( damageEntity(entity, hit, damage)); - } - } - - // Damage the building. The CF can never drop below 0. - int toBldg = (int) Math.ceil( entity.getWeight() / 10.0 ); - int curCF = bldg.getCurrentCF(); - curCF -= Math.min( curCF, toBldg ); - bldg.setCurrentCF( curCF ); - - // Apply the correct amount of damage to infantry in the building. - // ASSUMPTION: We inflict toBldg damage to infantry and - // not the amount to bring building to 0 CF. - this.damageInfantryIn( bldg, toBldg ); - - return checkBuildingCollapseWhileMoving(bldg, entity, curPos); - } - - private boolean checkBuildingCollapseWhileMoving(Building bldg, Entity entity, Coords curPos) { - // Get the position map of all entities in the game. - Hashtable positionMap = game.getPositionMap(); - - // Count the moving entity in its current position, not - // its pre-move postition. Be sure to handle nulls. - Vector entities = null; - if ( entity.getPosition() != null ) { - entities = (Vector) positionMap.get( entity.getPosition() ); - entities.removeElement( entity ); - } - entities = (Vector) positionMap.get( curPos ); - if ( entities == null ) { - entities = new Vector(); - positionMap.put( curPos, entities ); - } - entities.addElement( entity ); - - // Check for collapse of this building due to overloading, and return. - return this.checkForCollapse( bldg, positionMap ); - } - - /** - * Apply the correct amount of damage that passes on to any infantry unit - * in the given building, based upon the amount of damage the building - * just sustained. This amount is a percentage dictated by pg. 52 of BMRr. - * - * @param bldg - the Building that sustained the damage. - * @param damage - the int amount of damage. - */ - private void damageInfantryIn( Building bldg, int damage ) { - // Calculate the amount of damage the infantry will sustain. - float percent = 0.0f; - Report r; - switch( bldg.getType() ) { - case Building.LIGHT: percent = 0.75f; break; - case Building.MEDIUM: percent = 0.5f; break; - case Building.HEAVY: percent = 0.25f; break; - } - - // Round up at .5 points of damage. - int toInf = Math.round( damage * percent ); - - // Record if we find any infantry. - boolean foundInfantry = false; - - // Walk through the entities in the game. - Enumeration entities = game.getEntities(); - while ( entities.hasMoreElements() ) { - Entity entity = (Entity) entities.nextElement(); - final Coords coords = entity.getPosition(); - - // If the entity is infantry in one of the building's hexes? - if ( entity instanceof Infantry && - bldg.isIn( coords ) ) { - - // Is the entity is inside of the building - // (instead of just on top of it)? - if ( Compute.isInBuilding( game, entity, coords ) ) { - - // Report if the infantry receive no points of damage. - if ( toInf == 0 ) { - r = new Report(6445); - addReport(r); - } else { - // Yup. Damage the entity. - // Battle Armor units use 5 point clusters. - r = new Report(6450); - r.indent(2); - r.subject = entity.getId(); - r.add(entity.getDisplayName()); - r.add(toInf); - addReport(r); - int remaining = toInf; - int cluster = toInf; - if ( entity instanceof BattleArmor ) { - cluster = 5; - } - while ( remaining > 0 ) { - int next = Math.min( cluster, remaining ); - HitData hit = entity.rollHitLocation - ( ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT ); - addReport( damageEntity(entity, hit, next) ); - remaining -= next; - } - addReport(new Report(1210)); - } - - } // End infantry-inside-building - - } // End entity-is-infantry-in-building-hex - - } // Handle the next entity - - // If we found any infantry, add a line to the phase report. - if ( foundInfantry ) { - addReport(new Report(1210)); - } - - } // End private void damageInfantryIn( Building, int ) - - /** - * Determine if the given building should collapse. If so, - * inflict the appropriate amount of damage on each entity in - * the building and update the clients. If the building does - * not collapse, determine if any entities crash through its - * floor into its basement. Again, apply appropriate damage. - * - * @param bldg - the Building being checked. - * This value should not be null. - * @param positionMap - a Hashtable that maps - * the Coords positions or each unit - * in the game to a Vector of - * Entitys at that position. - * This value should not be null. - * @return true if the building collapsed. - */ - public boolean checkForCollapse( Building bldg, Hashtable positionMap ) { - - // If the input is meaningless, do nothing and throw no exception. - if ( bldg == null || - positionMap == null || positionMap.isEmpty() ) { - return false; - } - - // Get the building's current CF. - final int currentCF = bldg.getCurrentCF(); - - // Track all units that fall into the building's basement by Coords. - Hashtable basementMap = new Hashtable(); - - // Walk through the hexes in the building, looking for a collapse. - Enumeration bldgCoords = bldg.getCoords(); - boolean collapse = false; - while ( !collapse && bldgCoords.hasMoreElements() ) { - final Coords coords = (Coords) bldgCoords.nextElement(); - - // Get the Vector of Entities at these coordinates. - final Vector vector = (Vector) positionMap.get( coords ); - - // Are there any Entities at these coords? - if ( vector != null ) { - - // How many levels does this building have in this hex? - final IHex curHex = game.getBoard().getHex( coords ); - final int hexElev = curHex.surface(); - final int numFloors = Math.max(0,curHex.terrainLevel( Terrains.BLDG_ELEV )); - final int bridgeEl = curHex.terrainLevel(Terrains.BRIDGE_ELEV); - int numLoads = numFloors; - if(bridgeEl != ITerrain.LEVEL_NONE) { - numLoads ++; - } - if(numLoads < 1) { - System.err.println("Check for collapse: hex "+coords.toString()+" has no bridge or building"); - continue; - } - - // Track the load of each floor (and of the roof) separately. - // Track all units that fall into the basement in this hex. - // N.B. don't track the ground floor, the first floor is at - // index 0, the second is at index 1, etc., and the roof is - // at index (numFloors-1). - // if bridge is present, bridge will be numFloors - int[] loads = new int[numLoads]; - Vector basement = new Vector(); - for ( int loop = 0; loop < numLoads; loop++ ) { - loads[loop] = 0; - } - - // Walk through the entities in this position. - Enumeration entities = vector.elements(); - while ( !collapse && entities.hasMoreElements() ) { - final Entity entity = (Entity) entities.nextElement(); - final int entityElev = entity.getElevation(); - - if(entityElev != bridgeEl) { - // Ignore entities not *inside* the building - if ( entityElev > numFloors) { - continue; - } - } - - if(entity.getMovementMode() == IEntityMovementMode.HYDROFOIL - || entity.getMovementMode() == IEntityMovementMode.NAVAL - || entity.getMovementMode() == IEntityMovementMode.SUBMARINE) { - continue; //under the bridge even at same level - } - - // Add the weight of a Mek or tank to the correct floor. - if ( entity instanceof Mech || entity instanceof Tank ) { - int load = (int) entity.getWeight(); - int floor = entityElev; - if(floor == bridgeEl) { - floor = numLoads; - } - - // Entities on the ground floor may fall into the - // basement, but they won't collapse the building. - if ( numFloors > 0 && floor == 0 && load > currentCF ) { - basement.addElement( entity ); - } else if ( floor > 0 ) { - - // If the load on any floor but the ground floor - // exceeds the building's current CF it collapses. - floor--; - loads[ floor ] += load; - if ( loads[ floor ] > currentCF ) { - collapse = true; - } - - } // End not-ground-floor - - } // End increase-load - - } // Handle the next entity. - - // Track all entities that fell into the basement. - if ( !basement.isEmpty() ) { - basementMap.put( coords, basement ); - } - - } // End have-entities-here - - } // Check the next hex of the building. - - // Collapse the building if the flag is set. - if ( collapse ) { - Report r = new Report(2375); - r.add(bldg.getName()); - addReport(r); - this.collapseBuilding( bldg, positionMap ); - } - - // Otherwise, did any entities fall into the basement? - else if ( !basementMap.isEmpty() ) { - // TODO: implement basements - } - - // Return true if the building collapsed. - return collapse; - - } // End private boolean checkForCollapse( Building, Hashtable ) - - /** - * Collapse the building. Inflict the appropriate amount of damage - * on all entities in the building. Update all clients. - * - * @param bldg - the Building that has collapsed. - * @param positionMap - a Hashtable that maps - * the Coords positions or each unit - * in the game to a Vector of - * Entitys at that position. - * This value should not be null. - */ - public void collapseBuilding( Building bldg, Hashtable positionMap ) { - // Loop through the hexes in the building, and apply - // damage to all entities inside or on top of the building. - Report r; - final int phaseCF = bldg.getPhaseCF(); - Enumeration bldgCoords = bldg.getCoords(); - while ( bldgCoords.hasMoreElements() ) { - final Coords coords = (Coords) bldgCoords.nextElement(); - - // Get the Vector of Entities at these coordinates. - final Vector vector = (Vector) positionMap.get( coords ); - - // Are there any Entities at these coords? - if ( vector != null ) { - - // How many levels does this building have in this hex? - final IHex curHex = game.getBoard().getHex( coords ); - final int hexElev = curHex.surface(); - final int bridgeEl = curHex.terrainLevel(Terrains.BRIDGE_ELEV); - final int numFloors = Math.max(bridgeEl, curHex.terrainLevel( Terrains.BLDG_ELEV )); - - // Sort in elevation order - Collections.sort(vector, new Comparator() { - public int compare(Entity a, Entity b) { - if(a.getElevation() > b.getElevation()) - return -1; - else if(a.getElevation() > b.getElevation()) - return 1; - return 0; - } - }); - // Walk through the entities in this position. - Enumeration entities = vector.elements(); - while ( entities.hasMoreElements() ) { - final Entity entity = (Entity) entities.nextElement(); - //final int entityElev = entity.elevationOccupied( curHex ); - int floor = entity.getElevation(); - - // Ignore units above the building / bridge. - if ( floor > numFloors) { - continue; - } - - // Treat units on the roof like - // they were in the top floor. - if ( floor == numFloors ) { - floor--; - } - - // Calculate collapse damage for this entity. - int damage = (int) Math.ceil - ( phaseCF * (numFloors-floor) / 10.0 ); - - // Infantry suffer triple damage. - if ( entity instanceof Infantry ) { - damage *= 3; - } - - // Apply collapse damage the entity. - // ASSUMPTION: use 5 point clusters. - r = new Report(6455); - r.indent(); - r.subject = entity.getId(); - r.add(entity.getDisplayName()); - r.add(damage); - addReport(r); - int remaining = damage; - int cluster = damage; - if ( entity instanceof BattleArmor || - entity instanceof Mech || - entity instanceof Tank ) { - cluster = 5; - } - while ( remaining > 0 ) { - int next = Math.min( cluster, remaining ); - // In www.classicbattletech.com/PDF/AskPMForumArchiveandFAQ.pdf, - // pg. 18, Randall Bills says that all damage from a - // collapsing building is applied to the front. - - HitData hit = entity.rollHitLocation - (ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT ); - addReport( damageEntity(entity, hit, next) ); - remaining -= next; - } - addReport(new Report(1210)); - // TODO: Why are dead entities showing up on firing phase? - - // Do we need to handle falling Meks? - // BMRr, pg. 53 only mentions falling BattleMechs; - // Tanks can't be above the floor and I guess that - // infantry don't suffer falling damage. - // TODO: implement basements, then fall into it. - // ASSUMPTION: we'll let the Mech fall twice: once - // during damageEntity() above and once here. - floor = entity.getElevation(); - if ( floor > 0 || floor == bridgeEl) { - // ASSUMPTION: PSR to avoid pilot damage - // should use mods for entity damage and - // 20+ points of collapse damage (if any). - PilotingRollData psr = entity.getBasePilotingRoll(); - entity.addPilotingModifierForTerrain(psr, coords); - if ( damage >= 20 ) { - psr.addModifier( 1, "20+ damage" ); - } - this.doEntityFallsInto( entity, coords, coords, psr ); - } - - // Update this entity. - // ASSUMPTION: this is the correct thing to do. - this.entityUpdate( entity.getId() ); - - } // Handle the next entity. - - } // End have-entities-here. - - } // Handle the next hex of the building. - - // Update the building. - bldg.setCurrentCF( 0 ); - bldg.setPhaseCF( 0 ); - send( createCollapseBuildingPacket(bldg) ); - game.getBoard().collapseBuilding( bldg ); - - } // End private void collapseBuilding( Building ) - - /** - * Tell the clients to replace the given building with rubble hexes. - * - * @param bldg - the Building that has collapsed. - * @return a Packet for the command. - */ - private Packet createCollapseBuildingPacket( Building bldg ) { - Vector buildings = new Vector(); - buildings.addElement( bldg ); - return this.createCollapseBuildingPacket( buildings ); - } - - /** - * Tell the clients to replace the given buildings with rubble hexes. - * - * @param buildings - a Vector of Buildings - * that has collapsed. - * @return a Packet for the command. - */ - private Packet createCollapseBuildingPacket( Vector buildings ) { - return new Packet( Packet.COMMAND_BLDG_COLLAPSE, buildings ); - } - - /** - * Tell the clients to update the CFs of the given buildings. - * - * @param buildings - a Vector of Buildings - * that need to be updated. - * @return a Packet for the command. - */ - private Packet createUpdateBuildingCFPacket( Vector buildings ) { - return new Packet( Packet.COMMAND_BLDG_UPDATE_CF, buildings ); - } - - /** - * Apply this phase's damage to all buildings. Buildings may - * collapse due to damage. - */ - private void applyBuildingDamage() { - - // Walk through the buildings in the game. - // Build the collapse and update vectors as you go. - // N.B. never, NEVER, collapse buildings while you are walking through - // the Enumeration from megamek.common.Board#getBuildings. - Vector collapse = new Vector(); - Vector update = new Vector(); - Enumeration buildings = game.getBoard().getBuildings(); - while ( buildings.hasMoreElements() ) { - Building bldg = (Building) buildings.nextElement(); - - // If the CF is zero, the building should fall. - if ( bldg.getCurrentCF() == 0 ) { - collapse.addElement( bldg ); - } - - // If the building took damage this round, update it. - else if ( bldg.getPhaseCF() != bldg.getCurrentCF() ) { - bldg.setPhaseCF( bldg.getCurrentCF() ); - update.addElement( bldg ); - } - - } // Handle the next building - - // If we have any buildings to collapse, collapse them now. - if ( !collapse.isEmpty() ) { - - // Get the position map of all entities in the game. - Hashtable positionMap = game.getPositionMap(); - - // Walk through the buildings that have collapsed. - buildings = collapse.elements(); - while ( buildings.hasMoreElements() ) { - Building bldg = (Building) buildings.nextElement(); - Report r = new Report(6460,Report.PUBLIC); - r.add(bldg.getName()); - addReport(r); - this.collapseBuilding( bldg, positionMap ); - } - - } - - //check for buildings which should collapse due to being overloaded now CF is reduced - if(!update.isEmpty()) { - Hashtable positionMap = game.getPositionMap(); - for(Iterator i=update.iterator();i.hasNext();) { - Building bldg = (Building) i.next(); - if(checkForCollapse(bldg, positionMap)) i.remove(); - } - } - - // If we have any buildings to update, send the message. - if ( !update.isEmpty() ) { - sendChangedCFBuildings( update ); - } - } - - /** - * Apply the given amount of damage to the building. Please note, - * this method does not apply any damage to units inside the - * building, update the clients, or check for the building's collapse. - *

- * A default message will be used to describe why the building - * took the damage. - * - * @param bldg - the Building that has been damaged. - * This value should not be null, but no - * exception will occur. - * @param damage - the int amount of damage. - * @return a Report to be shown to the players. - */ - private Report damageBuilding( Building bldg, int damage ) { - final String defaultWhy = " absorbs "; - return damageBuilding( bldg, damage, defaultWhy ); - } - - /** - * Apply the given amount of damage to the building. Please note, - * this method does not apply any damage to units inside the - * building, update the clients, or check for the building's collapse. - * - * @param bldg - the Building that has been damaged. - * This value should not be null, but no - * exception will occur. - * @param damage - the int amount of damage. - * @param why - the String message that describes - * why the building took the damage. - * @return a Report to be shown to the players. - */ - private Report damageBuilding( Building bldg, int damage, String why ) { - Report r = new Report(1210); - r.newlines = 0; - - // Do nothing if no building or no damage was passed. - if ( bldg != null && damage > 0 ) { - int curCF = bldg.getCurrentCF(); - final int startingCF = curCF; - curCF -= Math.min( curCF, damage ); - bldg.setCurrentCF( curCF ); - r.messageId = 3435; - r.add( bldg.getName() ); - r.add( why ); - r.add( damage ); - - // If the CF is zero, the building should fall. - if ( curCF == 0 && startingCF != 0 ) { - r.messageId = 3440; - } - - } - return r; - } - - public void sendChangedCFBuildings(Vector buildings) { - send(createUpdateBuildingCFPacket(buildings)); - } - - /** - * Receives an packet to unload entityis stranded on immobile transports, - * and queue all valid requests for execution. If all players that have - * stranded entities have answered, executes the pending requests and end - * the current turn. - */ - private void receiveUnloadStranded( Packet packet, int connId ) { - GameTurn.UnloadStrandedTurn turn = null; - final Player player = game.getPlayer( connId ); - int[] entityIds = (int[]) packet.getObject(0); - Vector declared = null; - Player other = null; - Enumeration pending = null; - UnloadStrandedAction action = null; - Entity entity = null; - - // Is this the right phase? - if (game.getPhase() != IGame.PHASE_MOVEMENT) { - System.err.println - ("error: server got unload stranded packet in wrong phase"); - return; - } - - // Are we in an "unload stranded entities" turn? - if ( game.getTurn() instanceof GameTurn.UnloadStrandedTurn ) { - turn = (GameTurn.UnloadStrandedTurn) game.getTurn(); - } else { - System.err.println - ("error: server got unload stranded packet out of sequence"); - StringBuffer message = new StringBuffer(); - message.append( player.getName() ) - .append( " should not be sending 'unload stranded entity' packets at this time." ); - sendServerChat( message.toString() ); - return; - } - - // Can this player act right now? - if (!turn.isValid(connId, game)) { - System.err.println - ("error: server got unload stranded packet from invalid player"); - StringBuffer message = new StringBuffer(); - message.append( player.getName() ) - .append( " should not be sending 'unload stranded entity' packets." ); - sendServerChat( message.toString() ); - return; - } - - // Did the player already send an 'unload' request? - // N.B. we're also building the list of players who - // have declared their "unload stranded" actions. - declared = new Vector(); - pending = game.getActions(); - while ( pending.hasMoreElements() ) { - action = (UnloadStrandedAction) pending.nextElement(); - if ( action.getPlayerId() == connId ) { - System.err.println("error: server got multiple unload stranded packets from player"); - StringBuffer message = new StringBuffer(); - message.append( player.getName() ) - .append( " should not send multiple 'unload stranded entity' packets." ); - sendServerChat( message.toString() ); - return; - } else { - // This player is not from the current connection. - // Record this player to determine if this turn is done. - other = game.getPlayer( action.getPlayerId() ); - if ( !declared.contains( other ) ) { - declared.addElement( other ); - } - } - } // Handle the next "unload stranded" action. - - // Make sure the player selected at least *one* valid entity ID. - boolean foundValid = false; - for ( int index = 0; null != entityIds && index < entityIds.length; - index++ ) { - entity = game.getEntity( entityIds[index] ); - if (!game.getTurn().isValid(connId, entity, game)) { - System.err.println("error: server got unload stranded packet for invalid entity"); - StringBuffer message = new StringBuffer(); - message.append( player.getName() ) - .append( " can not unload stranded entity " ); - if ( null == entity ) { - message.append( "#" ) - .append( entityIds[index] ); - } else { - message.append( entity.getDisplayName() ); - } - message.append( " at this time." ); - sendServerChat( message.toString() ); - } else { - foundValid = true; - game.addAction( new UnloadStrandedAction( connId, - entityIds[index] ) ); - } - } - - // Did the player choose not to unload any valid stranded entity? - if ( !foundValid ) { - game.addAction( new UnloadStrandedAction( connId, Entity.NONE ) ); - } - - // Either way, the connection's player has now declared. - declared.addElement( player ); - - // Are all players who are unloading entities done? Walk - // through the turn's stranded entities, and look to see - // if their player has finished their turn. - entityIds = turn.getEntityIds(); - for ( int index = 0; index < entityIds.length; index++ ) { - entity = game.getEntity( entityIds[index] ); - other = entity.getOwner(); - if ( !declared.contains( other ) ) { - // At least one player still needs to declare. - return; - } - } - - // All players have declared whether they're unloading stranded units. - // Walk the list of pending actions and unload the entities. - pending = game.getActions(); - while ( pending.hasMoreElements() ) { - action = (UnloadStrandedAction) pending.nextElement(); - - // Some players don't want to unload any stranded units. - if ( Entity.NONE != action.getEntityId() ) { - entity = game.getEntity( action.getEntityId() ); - if ( null == entity ) { - // After all this, we couldn't find the entity!!! - System.err.print - ("error: server could not find stranded entity #"); - System.err.print( action.getEntityId() ); - System.err.println( " to unload!!!"); - } else { - // Unload the entity. Get the unit's transporter. - Entity transporter = - game.getEntity( entity.getTransportId() ); - this.unloadUnit( transporter, entity, - transporter.getPosition(), - transporter.getFacing(), - transporter.getElevation()); - } - } - - } // Handle the next pending unload action - - // Clear the list of pending units and move to the next turn. - game.resetActions(); - changeToNextTurn(); - } - /** - * For all current artillery attacks in the air from this entity - * with this weapon, clear the list of spotters. Needed because - * firing another round before first lands voids spotting. - * - * @param entityID int - */ - private void clearArtillerySpotters(int entityID,int weaponID) { - for (Enumeration i = game.getArtilleryAttacks(); i.hasMoreElements();) { - ArtilleryAttackAction aaa = (ArtilleryAttackAction) i.nextElement(); - if ( aaa.getWR().waa.getEntityId()==entityID && - aaa.getWR().waa.getWeaponId()==weaponID ) { - aaa.setSpotterIds(null); - } - - } - } - - /** - * Find the tagged entity for this attack - * - * Each TAG will attract a number of shots up to its priority number (mode setting) - * When all the TAGs are used up, the shots fired are reset. - * So if you leave them all on 1-shot, then homing attacks will be evenly split, however many shots you fire. - * - * Priority setting is to allocate more homing attacks to a more important target as decided by player. - * - * TAGs fired by the enemy aren't eligable, nor are TAGs fired at a target on a different map sheet. - */ - private WeaponResult convertHomingShotToEntityTarget(ArtilleryAttackAction aaa, Entity ae) { - WeaponResult wr = aaa.getWR(); - Targetable target = wr.waa.getTarget(game); - - final Coords tc = target.getPosition(); - Entity entityTarget = null; - - TagInfo info = null; - Entity tagger = null; - - for(int pass=0;pass<2;pass++) { - int bestDistance = Integer.MAX_VALUE; - int bestIndex = -1; - Vector v = game.getTagInfo(); - for(int i=0;i= wr.toHit.getValue()) { - artyAttacker.aTracker.setModifier - ( weapon, - ToHitData.AUTOMATIC_SUCCESS, - targetPos ); - } - // If the shot missed, but was adjusted by a - // spotter, future shots are more likely to hit. - else if (null != bestSpotter) { - artyAttacker.aTracker.setModifier - ( weapon, - artyAttacker.aTracker.getModifier - ( weapon, targetPos ) - 1, - targetPos ); - } - - } // End artyAttacker-alive - } - - // Schedule this attack to be resolved. - results.addElement(wr); - attacks.addElement( aaa ); - - } // End attack-hits-this-turn - - // This attack is one round closer to hitting. - aaa.turnsTilHit--; - - } // Handle the next attack - - // loop through weapon results and resolve - int lastEntityId = Entity.NONE; - for (Enumeration i = results.elements();i.hasMoreElements();) { - WeaponResult wr = (WeaponResult) i.nextElement(); - resolveWeaponAttack(wr, lastEntityId); - lastEntityId = wr.waa.getEntityId(); - } - - // Clear out all resolved attacks. - for (Enumeration i = attacks.elements(); i.hasMoreElements();) { - game.removeArtilleryAttack - ( (ArtilleryAttackAction) i.nextElement() ); - } - for(Enumeration i = game.getPlayers();i.hasMoreElements();) { - Player player = (Player)i.nextElement(); - int connId = player.getId(); - send(connId, createArtilleryPacket(player)); - } - } - - /** - * enqueues any indirect artillery attacks made this turn - */ - private void enqueueIndirectArtilleryAttacks() { - resolveAllButWeaponAttacks(); - ArtilleryAttackAction aaa; - for (Enumeration i = game.getActions();i.hasMoreElements();) { - EntityAction ea = (EntityAction) i.nextElement(); - final Entity firingEntity = game.getEntity(ea.getEntityId()); - if (ea instanceof WeaponAttackAction) { - final WeaponAttackAction waa = (WeaponAttackAction) ea; - WeaponResult wr = preTreatWeaponAttack(waa); - boolean firingAtNewHex = false; - for (Enumeration j = game.getArtilleryAttacks(); - !firingAtNewHex && j.hasMoreElements();) { - ArtilleryAttackAction oaaa = (ArtilleryAttackAction) j.nextElement(); - if ( oaaa.getWR().waa.getEntityId() == wr.waa.getEntityId() && - !oaaa.getWR().waa.getTarget(game).getPosition().equals(wr.waa.getTarget(game).getPosition())) { - firingAtNewHex = true; - } - } - if (firingAtNewHex) { - clearArtillerySpotters( firingEntity.getId(), - waa.getWeaponId() ); - } - Enumeration spotters = game.getSelectedEntities(new EntitySelector() { - public int player = firingEntity.getOwnerId(); - public Targetable target = waa.getTarget(game); - public boolean accept(Entity entity) { - if ( (player == entity.getOwnerId()) && - !((LosEffects.calculateLos(game, entity.getId(), target)).isBlocked()) && entity.isActive()) { - return true; - } else { - return false; - } - - } - } ); - - Vector spotterIds = new Vector(); - while ( spotters.hasMoreElements() ) { - Integer id = new Integer - ( ((Entity) spotters.nextElement() ).getId() ); - spotterIds.addElement( id ); - } - aaa = new ArtilleryAttackAction( wr, game, - firingEntity.getOwnerId(), - spotterIds, firingEntity.getPosition()); - game.addArtilleryAttack(aaa); - } - } - game.resetActions(); - for(Enumeration i = game.getPlayers();i.hasMoreElements();) { - Player player = (Player)i.nextElement(); - int connId = player.getId(); - send(connId, createArtilleryPacket(player)); - } - } - - /** - * Credits a Kill for an entity, if the target got killed. - * - * @param target The Entity that got killed. - * @param attacker The Entity that did the killing. - */ - private void creditKill(Entity target, Entity attacker) { - if (target.isDoomed() && !target.getGaveKillCredit()) { - attacker.addKill(target); - } - } - - /** - * pre-treats a physical attack - * - * @param aaa The AbstractAttackAction of the physical attack - * to pre-treat - * - * @return The PhysicalResult of that action, including - * possible damage. - */ - private PhysicalResult preTreatPhysicalAttack(AbstractAttackAction aaa) { - final Entity ae = game.getEntity(aaa.getEntityId()); - int damage = 0; - PhysicalResult pr = new PhysicalResult(); - ToHitData toHit = new ToHitData(); - pr.roll = Compute.d6(2); - pr.aaa = aaa; - if (aaa instanceof BrushOffAttackAction) { - BrushOffAttackAction baa = (BrushOffAttackAction)aaa; - int arm = baa.getArm(); - baa.setArm(BrushOffAttackAction.LEFT); - toHit = BrushOffAttackAction.toHit(game, aaa.getEntityId(), aaa.getTarget(game), BrushOffAttackAction.LEFT); - baa.setArm(BrushOffAttackAction.RIGHT); - pr.toHitRight = BrushOffAttackAction.toHit(game, aaa.getEntityId(), aaa.getTarget(game), BrushOffAttackAction.RIGHT); - damage = BrushOffAttackAction.getDamageFor(ae, BrushOffAttackAction.LEFT); - pr.damageRight = BrushOffAttackAction.getDamageFor(ae, BrushOffAttackAction.RIGHT); - baa.setArm(arm); - pr.rollRight = Compute.d6(2); - } else if (aaa instanceof ChargeAttackAction) { - ChargeAttackAction caa = (ChargeAttackAction)aaa; - toHit = caa.toHit(game); - damage = ChargeAttackAction.getDamageFor(ae); - } else if (aaa instanceof ClubAttackAction) { - ClubAttackAction caa = (ClubAttackAction)aaa; - toHit = caa.toHit(game); - damage = ClubAttackAction.getDamageFor(ae, caa.getClub()); - } else if (aaa instanceof DfaAttackAction) { - DfaAttackAction daa = (DfaAttackAction)aaa; - toHit = daa.toHit(game); - damage = DfaAttackAction.getDamageFor(ae); - } else if (aaa instanceof KickAttackAction) { - KickAttackAction kaa = (KickAttackAction)aaa; - toHit = kaa.toHit(game); - damage = KickAttackAction.getDamageFor(ae, kaa.getLeg()); - } else if (aaa instanceof ProtomechPhysicalAttackAction) { - ProtomechPhysicalAttackAction paa = (ProtomechPhysicalAttackAction)aaa; - toHit = paa.toHit(game); - damage = ProtomechPhysicalAttackAction.getDamageFor(ae); - } else if (aaa instanceof PunchAttackAction) { - PunchAttackAction paa = (PunchAttackAction)aaa; - int arm = paa.getArm(); - int damageRight = 0; - paa.setArm(PunchAttackAction.LEFT); - toHit = paa.toHit(game); - paa.setArm(PunchAttackAction.RIGHT); - ToHitData toHitRight = paa.toHit(game); - damage = PunchAttackAction.getDamageFor(ae, PunchAttackAction.LEFT); - damageRight = PunchAttackAction.getDamageFor(ae, PunchAttackAction.RIGHT); - paa.setArm(arm); - // If we're punching while prone (at a Tank, - // duh), then we can only use one arm. - if ( ae.isProne() ) { - double oddsLeft = Compute.oddsAbove(toHit.getValue()); - double oddsRight = Compute.oddsAbove(toHitRight.getValue()); - // Use the best attack. - if ( oddsLeft*damage > oddsRight*damageRight ) { - paa.setArm(PunchAttackAction.LEFT); - } else paa.setArm(PunchAttackAction.RIGHT); - } - pr.damageRight = damageRight; - pr.toHitRight = toHitRight; - pr.rollRight = Compute.d6(2); - } else if (aaa instanceof PushAttackAction) { - PushAttackAction paa = (PushAttackAction)aaa; - toHit = paa.toHit(game); - } else if (aaa instanceof LayExplosivesAttackAction) { - LayExplosivesAttackAction leaa = (LayExplosivesAttackAction)aaa; - toHit = leaa.toHit(game); - damage = LayExplosivesAttackAction.getDamageFor(ae); - } else if (aaa instanceof ThrashAttackAction) { - ThrashAttackAction taa = (ThrashAttackAction)aaa; - toHit = taa.toHit(game); - damage = ThrashAttackAction.getDamageFor(ae); - } - pr.toHit = toHit; - pr.damage = damage; - return pr; - } - - /** - * Resolve a Physical Attack - * - * @param pr The PhysicalResult of the physical attack - * @param cen The int Entity Id of the entit's whose - * physical attack was last resolved - */ - private void resolvePhysicalAttack(PhysicalResult pr, int cen) { - AbstractAttackAction aaa = pr.aaa; - if (aaa instanceof PunchAttackAction) { - PunchAttackAction paa = (PunchAttackAction)aaa; - if (paa.getArm() == PunchAttackAction.BOTH) { - paa.setArm(PunchAttackAction.LEFT); - pr.aaa = paa; - resolvePunchAttack(pr, cen); - cen = paa.getEntityId(); - paa.setArm(PunchAttackAction.RIGHT); - pr.aaa = paa; - resolvePunchAttack(pr, cen); - } else { - resolvePunchAttack(pr, cen); - cen = paa.getEntityId(); - } - } else if (aaa instanceof KickAttackAction) { - resolveKickAttack(pr, cen); - cen = aaa.getEntityId(); - } else if (aaa instanceof BrushOffAttackAction) { - BrushOffAttackAction baa = (BrushOffAttackAction)aaa; - if (baa.getArm() == BrushOffAttackAction.BOTH) { - baa.setArm(BrushOffAttackAction.LEFT); - pr.aaa = baa; - resolveBrushOffAttack(pr, cen); - cen = baa.getEntityId(); - baa.setArm(BrushOffAttackAction.RIGHT); - pr.aaa = baa; - resolveBrushOffAttack(pr, cen); - } else { - resolveBrushOffAttack(pr, cen); - cen = baa.getEntityId(); - } - } else if (aaa instanceof ThrashAttackAction) { - resolveThrashAttack(pr, cen); - cen = aaa.getEntityId(); - } else if (aaa instanceof ProtomechPhysicalAttackAction) { - resolveProtoAttack(pr, cen); - cen = aaa.getEntityId(); - } else if (aaa instanceof ClubAttackAction) { - resolveClubAttack(pr, cen); - cen = aaa.getEntityId(); - } else if (aaa instanceof PushAttackAction) { - resolvePushAttack(pr, cen); - cen = aaa.getEntityId(); - } else if (aaa instanceof ChargeAttackAction) { - resolveChargeAttack(pr, cen); - cen = aaa.getEntityId(); - } else if (aaa instanceof DfaAttackAction) { - resolveDfaAttack(pr, cen); - cen = aaa.getEntityId(); - } else if (aaa instanceof LayExplosivesAttackAction) { - resolveLayExplosivesAttack(pr, cen); - cen = aaa.getEntityId(); - } else { - // hmm, error. - } - // Not all targets are Entities. - Targetable target = game.getTarget( aaa.getTargetType(), - aaa.getTargetId() ); - if ( target instanceof Entity ) { - creditKill( (Entity) target, game.getEntity(cen) ); - } - } - - /** - * Add any extreme gravity PSRs the entity gets due to its movement - * - * @param entity The Entity to check. - * @param step The last MoveStep of this entity - * @param curPos The current Coords of this entity - * @param cachedMaxMPExpenditure Server checks run/jump MP at start of move, as appropriate, caches to avoid mid-move change in MP causing erroneous grav check - */ - private void checkExtremeGravityMovement(Entity entity, MoveStep step, Coords curPos, int cachedMaxMPExpenditure) { - PilotingRollData rollTarget; - if (game.getOptions().floatOption("gravity") != 1) { - if (entity instanceof Mech) { - if (step.getMovementType() == IEntityMovementType.MOVE_WALK - || (step.getMovementType() == IEntityMovementType.MOVE_VTOL_WALK) - || step.getMovementType() == IEntityMovementType.MOVE_RUN - || (step.getMovementType() == IEntityMovementType.MOVE_VTOL_RUN)) { - if (step.getMpUsed() > cachedMaxMPExpenditure) { - // We moved too fast, let's make PSR to see if we get damage - game.addExtremeGravityPSR(entity.checkMovedTooFast(step)); - } - } else if (step.getMovementType() == IEntityMovementType.MOVE_JUMP) { - if (step.getMpUsed() > cachedMaxMPExpenditure) { - // We jumped too far, let's make PSR to see if we get damage - game.addExtremeGravityPSR(entity.checkMovedTooFast(step)); - } else if (game.getOptions().floatOption("gravity") > 1) { - // jumping in high g is bad for your legs - rollTarget = entity.getBasePilotingRoll(); - entity.addPilotingModifierForTerrain(rollTarget, step); - rollTarget.append(new PilotingRollData(entity.getId(), 0, "jumped in high gravity")); - game.addExtremeGravityPSR(rollTarget); - } - } - } else if (entity instanceof Tank) { - if (step.getMovementType() == IEntityMovementType.MOVE_WALK - || (step.getMovementType() == IEntityMovementType.MOVE_VTOL_WALK) - || step.getMovementType() == IEntityMovementType.MOVE_RUN - || (step.getMovementType() == IEntityMovementType.MOVE_VTOL_RUN)) { - // For Tanks, we need to check if the tank had - // more MPs because it was moving along a road. - if ((step.getMpUsed() > cachedMaxMPExpenditure) && !step.isOnlyPavement()) { - game.addExtremeGravityPSR(entity.checkMovedTooFast(step)); - } - else if (step.getMpUsed() > cachedMaxMPExpenditure + 1) { - // If the tank was moving on a road, he got a +1 bonus. - // N.B. The Ask Precentor Martial forum said that a 4/6 - // tank on a road can move 5/7, **not** 5/8. - game.addExtremeGravityPSR(entity.checkMovedTooFast(step)); - } // End tank-has-road-bonus - } - } - } - } - - /** - * Damage the inner structure of a mech's leg / a tank's front. - * This only happens when the Entity fails an extreme Gravity PSR. - * @param entity The Entity to damage. - * @param damage The int amount of damage. - */ - private void doExtremeGravityDamage(Entity entity, int damage) { - HitData hit; - if (entity instanceof BipedMech) { - for (int i = 6; i<=7; i++) { - hit = new HitData (i); - addReport( damageEntity(entity, hit, damage, false, 0, true)); - } - } if (entity instanceof QuadMech) { - for (int i = 4; i<=7; i++) { - hit = new HitData (i); - addReport( damageEntity(entity, hit, damage, false, 0, true)); - } - } else if (entity instanceof Tank) { - hit = new HitData (Tank.LOC_FRONT); - addReport( damageEntity(entity, hit, damage, false, 0, true)); - } - } - - /** - * Eject an Entity. - * @param entity The Entity to eject. - * @param autoEject The boolean state of the entity's auto- - * ejection system - * @return a Vector of report objects for the gamelog. - */ - public Vector ejectEntity(Entity entity, boolean autoEject) { - Vector vDesc = new Vector(); - Report r; - - // An entity can only eject it's crew once. - if (entity.getCrew().isEjected()) - return vDesc; - - // If the crew are already dead, don't bother - if(entity.getCrew().isDead() || entity.getCrew().isDoomed()) - return vDesc; - - // Mek pilots may get hurt during ejection, - // and run around the board afterwards. - if (entity instanceof Mech) { - PilotingRollData rollTarget = new PilotingRollData(entity.getId(), entity.getCrew().getPiloting(), "ejecting"); - if (entity.isProne()) { - rollTarget.addModifier(5, "Mech is prone"); - } - if (entity.getCrew().isUnconscious()) { - rollTarget.addModifier(3, "pilot unconscious"); - } - if (autoEject) { - rollTarget.addModifier(1, "automatic ejection"); - } - if (entity.getInternal(Mech.LOC_HEAD) < 3) { - rollTarget.addModifier(Math.min(3 - entity.getInternal(Mech.LOC_HEAD),2), "Head Internal Structure Damage"); - } - int facing = entity.getFacing(); - Coords targetCoords = entity.getPosition().translated((facing + 3)%6); - IHex targetHex = game.getBoard().getHex(targetCoords); - if (targetHex != null) { - if (targetHex.terrainLevel(Terrains.WATER) > 0 && !(targetHex.containsTerrain(Terrains.ICE))) { - rollTarget.addModifier(-1, "landing in water"); - } else if (targetHex.containsTerrain(Terrains.ROUGH)) { - rollTarget.addModifier(0, "landing in rough"); - } else if (targetHex.containsTerrain(Terrains.RUBBLE)) { - rollTarget.addModifier(0, "landing in rubble"); - } else if (targetHex.terrainLevel(Terrains.WOODS) == 1) { - rollTarget.addModifier(2, "landing in light woods"); - } else if (targetHex.terrainLevel(Terrains.WOODS) == 2) { - rollTarget.addModifier(3, "landing in heavy woods"); - } else if (targetHex.terrainLevel(Terrains.WOODS) == 3) { - rollTarget.addModifier(4, "landing in ultra heavy woods"); - } else if (targetHex.terrainLevel(Terrains.JUNGLE) == 1) { - rollTarget.addModifier(3, "landing in light jungle"); - } else if (targetHex.terrainLevel(Terrains.JUNGLE) == 2) { - rollTarget.addModifier(5, "landing in heavy jungle"); - } else if (targetHex.terrainLevel(Terrains.JUNGLE) == 3) { - rollTarget.addModifier(7, "landing in ultra heavy jungle"); - } else if (targetHex.terrainLevel(Terrains.BLDG_ELEV) > 0) { - rollTarget.addModifier(targetHex.terrainLevel(Terrains.BLDG_ELEV), "landing in a building"); - } else rollTarget.addModifier(-2, "landing in clear terrain"); - } else { - rollTarget.addModifier(-2, "landing off the board"); - } - if (autoEject) { - r = new Report(6395); - r.subject = entity.getId(); - r.addDesc(entity); - r.indent(2); - r.newlines = 0; - vDesc.addElement(r); - } - // okay, print the info - r = new Report(2180); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(rollTarget.getLastPlainDesc(), true); - r.indent(3); - vDesc.addElement(r); - // roll - final int diceRoll = Compute.d6(2); - r = new Report(2190); - r.subject = entity.getId(); - r.add(rollTarget.getValueAsString()); - r.add(rollTarget.getDesc()); - r.add(diceRoll); - r.indent(4); - r.newlines = 0; - // create the MechWarrior in any case, for campaign tracking - MechWarrior pilot = new MechWarrior(entity); - pilot.setDeployed(true); - pilot.setId(getFreeEntityId()); - game.addEntity(pilot.getId(), pilot); - send(createAddEntityPacket(pilot.getId())); - // make him not get a move this turn - pilot.setDone(true); - if (diceRoll < rollTarget.getValue()) { - r.choose(false); - vDesc.addElement(r); - Report.addNewline(vDesc); - Vector v = damageCrew(pilot, 1); - if(v.size() > 0) { - r = (Report)v.firstElement(); - r.indent(3); - vDesc.addElement(r); - } - } else { - r.choose(true); - vDesc.addElement(r); - } - if (entity.getCrew().isDoomed()) { - vDesc.addAll( - destroyEntity(pilot, "deadly ejection", false, false)); - } - else { - // Add the pilot as an infantry unit on the battlefield. - if (game.getBoard().contains(targetCoords)) { - pilot.setPosition(targetCoords); -/* Can pilots eject into water??? - ASSUMPTION : They can (because they get a -1 mod to the PSR. - // Did the pilot land in water? - if ( game.getBoard().getHex( targetCoords).levelOf - ( Terrain.WATER ) > 0 ) { - //report missing - desc.append("and the pilot ejects, but lands in water!!!\n"); - //report missing - desc.append(destroyEntity( pilot, "a watery grave", false )); - } else { - //report missing - desc.append("and the pilot ejects safely!\n"); - } -*/ - //report safe ejection - r = new Report(6400); - r.subject = entity.getId(); - r.indent(5); - vDesc.addElement(r); - if (game.getOptions().booleanOption("vacuum")) { - //ended up in a vacuum - r = new Report(6405); - r.subject = entity.getId(); - r.indent(3); - vDesc.addElement(r); - vDesc.addAll( - destroyEntity(pilot, "explosive decompression", false, false)); - } - // Update the entity - this.entityUpdate(pilot.getId()); - // check if the pilot lands in a minefield - doEntityDisplacementMinefieldCheck( pilot, - entity.getPosition(), - targetCoords ); - } else { - //ejects safely - r = new Report(6410); - r.subject = entity.getId(); - r.indent(3); - vDesc.addElement(r); - if (game.getOptions().booleanOption("vacuum")) { - //landed in vacuum - r = new Report(6405); - r.subject = entity.getId(); - r.indent(3); - vDesc.addElement(r); - vDesc.addAll( - destroyEntity(pilot, "explosive decompression", false, false)); - } else { - game.removeEntity( pilot.getId(), IEntityRemovalConditions.REMOVE_IN_RETREAT ); - send(createRemoveEntityPacket(pilot.getId(), IEntityRemovalConditions.REMOVE_IN_RETREAT) ); - } - } - if (game.getOptions().booleanOption("ejected_pilots_flee")) { - game.removeEntity(pilot.getId(), IEntityRemovalConditions.REMOVE_IN_RETREAT); - send(createRemoveEntityPacket(pilot.getId(), IEntityRemovalConditions.REMOVE_IN_RETREAT)); - } - } // Pilot safely ejects. - - } // End entity-is-Mek - - // Mark the entity's crew as "ejected". - entity.getCrew().setEjected( true ); - vDesc.addAll( - destroyEntity(entity, "ejection", true, true)); - - // only remove the unit that ejected manually - if (!autoEject) { - game.removeEntity( entity.getId(), IEntityRemovalConditions.REMOVE_EJECTED ); - send(createRemoveEntityPacket(entity.getId(), IEntityRemovalConditions.REMOVE_EJECTED)); - } - return vDesc; - } - - /** - * Abandon an Entity. - * @param entity The Entity to abandon. - * - * @return a Vector of report objects for the gamelog. - */ - public Vector abandonEntity(Entity entity) { - Vector vDesc = new Vector(); - Report r; - - // An entity can only eject it's crew once. - if (entity.getCrew().isEjected()) - return vDesc; - - if (entity.getCrew().isDoomed()) - return vDesc; - - //Don't make them abandon into vacuum - if (game.getOptions().booleanOption("vacuum")) - return vDesc; - - Coords targetCoords = entity.getPosition(); - - if (entity instanceof Mech) { - // okay, print the info - r = new Report(2027); - r.subject = entity.getId(); - r.add(entity.getCrew().getName()); - r.addDesc(entity); - r.indent(3); - vDesc.addElement(r); - - // create the MechWarrior in any case, for campaign tracking - MechWarrior pilot = new MechWarrior(entity); - pilot.getCrew().setUnconscious(entity.getCrew().isUnconscious()); - pilot.setDeployed(true); - pilot.setId(getFreeEntityId()); - game.addEntity(pilot.getId(), pilot); - send(createAddEntityPacket(pilot.getId())); - // make him not get a move this turn - pilot.setDone(true); - // Add the pilot as an infantry unit on the battlefield. - if (game.getBoard().contains(targetCoords)) - pilot.setPosition(targetCoords); - // Update the entity - this.entityUpdate(pilot.getId()); - // check if the pilot lands in a minefield - doEntityDisplacementMinefieldCheck( pilot, - entity.getPosition(), - targetCoords ); - if (game.getOptions().booleanOption("ejected_pilots_flee")) { - game.removeEntity(pilot.getId(), IEntityRemovalConditions.REMOVE_IN_RETREAT); - send(createRemoveEntityPacket(pilot.getId(), IEntityRemovalConditions.REMOVE_IN_RETREAT)); - } - } // End entity-is-Mek - - // Mark the entity's crew as "ejected". - entity.getCrew().setEjected( true ); - - return vDesc; - } - - /** - * Checks if ejected Mechwarriors are eligible to be picked up, - * and if so, captures them or picks them up - */ - private void resolveMechWarriorPickUp() { - Report r; - - // fetch all mechWarriors that are not picked up - Enumeration mechWarriors = - game.getSelectedEntities( new EntitySelector() { - public boolean accept(Entity entity) { - if (entity instanceof MechWarrior) { - MechWarrior mw = (MechWarrior)entity; - if (mw.getPickedUpById() == Entity.NONE && - !mw.isDoomed() && (mw.getTransportId() == Entity.NONE) ) { - return true; - } - } - return false; - } - } ); - // loop through them, check if they are in a hex occupied by another - // unit - while ( mechWarriors.hasMoreElements() ) { - boolean pickedUp = false; - MechWarrior e = (MechWarrior) mechWarriors.nextElement(); - Enumeration pickupEntities = game.getEntities(e.getPosition()); - while (pickupEntities.hasMoreElements() ) { - Entity pe = (Entity) pickupEntities.nextElement(); - if (pe.isDoomed() || pe.isShutDown() || pe.getCrew().isUnconscious()) { - continue; - } - if (!pickedUp && pe.getOwnerId() == e.getOwnerId() && pe.getId() != e.getId()) { - if (pe instanceof MechWarrior) { - //picked up by friendlies - r = new Report(6415, Report.PUBLIC); //no subject we can use... - r.add(pe.getDisplayName()); - addReport(r); - continue; - } - // Pick up the unit. - pe.pickUp(e); - // The picked unit is being carried by the loader. - e.setPickedUpById(pe.getId()); - e.setPickedUpByExternalId(pe.getExternalId()); - pickedUp = true; - r = new Report(6420, Report.PUBLIC); - r.add(e.getDisplayName()); - r.addDesc(pe); - addReport(r); - } - } - if (!pickedUp) { - Enumeration pickupEnemyEntities = game.getEnemyEntities(e.getPosition(), e); - while (pickupEnemyEntities.hasMoreElements() ) { - Entity pe = (Entity) pickupEnemyEntities.nextElement(); - if (pe.isDoomed() || pe.isShutDown() || - pe.getCrew().isUnconscious()) { - continue; - } - if (pe instanceof MechWarrior) { - //picked up by friendlies - r = new Report(6415, Report.PUBLIC); //no subject we can use... - r.add(pe.getDisplayName()); - addReport(r); - continue; - } - // Capture the unit. - pe.pickUp(e); - // The captured unit is being carried by the loader. - e.setCaptured( true ); - e.setPickedUpById(pe.getId()); - e.setPickedUpByExternalId(pe.getExternalId()); - pickedUp = true; - r = new Report(6420, Report.PUBLIC); - r.add(e.getDisplayName()); - r.addDesc(pe); - addReport(r); - } - } - if (pickedUp) { - // Remove the picked-up unit from the screen. - e.setPosition( null ); - // Update the loaded unit. - this.entityUpdate( e.getId() ); - } - } - } - - /** - * destroy all wheeled and tracked Tanks that got displaced into water - */ - private void resolveSinkVees() { - Enumeration sinkableTanks = - game.getSelectedEntities( new EntitySelector() { - public boolean accept(Entity entity) { - if (entity.isOffBoard()) { - return false; - } - - if (entity instanceof Tank - && (entity.getPosition() != null) - && (entity.getMovementMode() == IEntityMovementMode.TRACKED - || entity.getMovementMode() == IEntityMovementMode.WHEELED ) - && game.getBoard().getHex(entity.getPosition()).terrainLevel(Terrains.WATER) > 0 - && entity.getElevation() < 0) { - return true; - } - return false; - } - }); - while (sinkableTanks.hasMoreElements()) { - Entity e = (Entity)sinkableTanks.nextElement(); - addReport( - destroyEntity(e, "a watery grave", false)); - } - } - - /** - * let all Entities make their "break-free-of-swamp-stickyness" PSR - */ - private void doTryUnstuck() { - if (game.getPhase() != IGame.PHASE_MOVEMENT) - return; - - Report r; - - Enumeration stuckEntities = - game.getSelectedEntities( new EntitySelector() { - public boolean accept(Entity entity) { - if (entity.isStuck()) { - return true; - } - return false; - } - }); - PilotingRollData rollTarget; - while (stuckEntities.hasMoreElements()) { - Entity entity = (Entity)stuckEntities.nextElement(); - rollTarget = entity.getBasePilotingRoll(); - entity.addPilotingModifierForTerrain(rollTarget); - // apart from swamp & liquid magma, -1 modifier - IHex hex = game.getBoard().getHex(entity.getPosition()); - if(!(hex.containsTerrain(Terrains.SWAMP)) - && !(hex.terrainLevel(Terrains.MAGMA) == 2)) { - rollTarget.addModifier(-1, "bogged down"); - } - // okay, print the info - r = new Report(2340); - r.addDesc(entity); - addReport(r); - - // roll - final int diceRoll = Compute.d6(2); - r = new Report(2190); - r.add(rollTarget.getValueAsString()); - r.add(rollTarget.getDesc()); - r.add(diceRoll); - if (diceRoll < rollTarget.getValue()) { - r.choose(false); - } else { - r.choose(true); - entity.setStuck(false); - entity.setCanUnstickByJumping(false); - } - addReport(r); - } - } - - /** - * Remove all iNarc pods from all vehicles that did not - * move and shoot this round - * NOTE: this is not quite what the rules say, the player - * should be able to choose whether or not to remove all iNarc Pods - * that are attached. - */ - private void resolveVeeINarcPodRemoval() { - Enumeration vees = - game.getSelectedEntities( new EntitySelector() { - public boolean accept(Entity entity) { - if (entity instanceof Tank && - entity.mpUsed == 0) { - return true; - } - return false; - } - }); - boolean canSwipePods; - while (vees.hasMoreElements()) { - canSwipePods = true; - Entity entity = (Entity)vees.nextElement(); - for (int i=0;i<=5;i++) { - if ( entity.weaponFiredFrom(i) ) { - canSwipePods = false; - } - } - if (canSwipePods && entity.hasINarcPodsAttached() && - entity.getCrew().isActive()) { - entity.removeAllINarcPods(); - Report r = new Report(2345); - r.addDesc(entity); - addReport(r); - } - } - } - - private void deadEntitiesCleanup() { - //See note above where knownDeadEntities variable is declared - /* - Entity en = null; - for(Enumeration k = game.getGraveyardEntities(); k.hasMoreElements(); en = (Entity) k.nextElement()) { - if (en != null) { - if (!knownDeadEntities.contains(en)) { - knownDeadEntities.add(en); - } - } - } - */ - } - - private void resolveIceBroken(Coords c) { - game.getBoard().getHex(c).removeTerrain(Terrains.ICE); - sendChangedHex(c); - //drop entities on the surface into the water - for(Enumeration entities = game.getEntities(c);entities.hasMoreElements();) { - Entity e = (Entity)entities.nextElement(); - if(e.getElevation() == 0) { - doEntityFall(e, new PilotingRollData(TargetRoll.AUTOMATIC_FAIL)); - } - } - } - - private void checkForVehicleFire(Tank tank, boolean inferno) { - int boomroll = Compute.d6(2); - int penalty = 0; - switch(tank.getMovementMode()) { - case IEntityMovementMode.HOVER: - penalty = 4; - break; - case IEntityMovementMode.VTOL: - case IEntityMovementMode.WHEELED: - penalty = 2; - break; - } - if(inferno) { - boomroll = 12; - } - Report r = new Report(5250); - r.subject = tank.getId(); - r.addDesc(tank); - r.add(8-penalty); - r.add(boomroll); - if (boomroll + penalty < 8) { - //phew! - r.choose(true); - addReport(r); - } else { - //eek - if(!inferno) { - r.choose(false); - addReport(r); - } - if(boomroll + penalty < 10) { - vehicleMotiveDamage(tank, penalty - 1); - } else { - resolveVehicleFire(tank, false); - if(boomroll + penalty >= 12) { - r = new Report(5255); - r.subject = tank.getId(); - r.indent(3); - addReport(r); - tank.setOnFire(); - } - } - } - } - - private void resolveVehicleFire(Tank tank, boolean existingStatus) { - if(existingStatus && !tank.isOnFire()) - return; - for(int i=0;i 0) { - te.setOriginalWalkMP(nMP - 1); - - if (te.getOriginalWalkMP()==0) { - // Hovercraft reduced to 0MP over water sink - if ( te.getMovementMode() == IEntityMovementMode.HOVER && - game.getBoard().getHex( te.getPosition() ).terrainLevel(Terrains.WATER) > 0 && - !(game.getBoard().getHex( te.getPosition() ).containsTerrain(Terrains.ICE))) { - vDesc.addAll( destroyEntity(te, "a watery grave", false) ); - } - } - } - } else { - r = new Report(6140); - r.subject = te.getId(); - vDesc.addElement(r); - te.immobilize(); - // Does the hovercraft sink? - IHex te_hex = game.getBoard().getHex( te.getPosition() ); - if ( te.getMovementMode() == IEntityMovementMode.HOVER && - te_hex.terrainLevel(Terrains.WATER) > 0 && - !(te_hex.containsTerrain(Terrains.ICE))) { - vDesc.addAll( destroyEntity(te, "a watery grave", false) ); - } - if(te instanceof VTOL) { - Report.addNewline(vDesc); - //report problem: add tab - vDesc.addAll( crashVTOL((VTOL)te)); - } - } - addReport(vDesc); - } - - - /** - * Add a whole lotta Reports to the players report queues - * as well as the Master report queue vPhaseReport. - */ - private void addReport(Vector reports){ - //Only bother with player reports if doing double blind. - if ( doBlind()) - for (Enumeration i = connections.elements(); i.hasMoreElements();) { - final Connection conn = (Connection)i.nextElement(); - Player p = game.getPlayer(conn.getId()); - - p.getTurnReport().addAll(filterReportVector(reports,p)); - } - vPhaseReport.addAll(reports); - } - - /** - * Add a single report to the report queue of all players and the master - * vPhaseReport queue - */ - private void addReport(Report report){ - //Only bother with player reports if doing double blind. - if ( doBlind()) - for (Enumeration i = connections.elements(); i.hasMoreElements();) { - final Connection conn = (Connection)i.nextElement(); - Player p = game.getPlayer(conn.getId()); - - p.getTurnReport().addElement(filterReport(report,p,false)); - } - vPhaseReport.addElement(report); - } - - /** - * New Round has started clear everyones report queue - */ - private void clearReports(){ - //Only bother with player reports if doing double blind. - if ( doBlind()) - for (Enumeration i = connections.elements(); i.hasMoreElements();) { - final Connection conn = (Connection)i.nextElement(); - Player p = game.getPlayer(conn.getId()); - - p.getTurnReport().removeAllElements(); - } - vPhaseReport.removeAllElements(); - } - - /** - * make sure all teh new lines that where added to the old vPhaseReport - * get added to all of the players filters - */ - private void addNewLines(){ - //Only bother with player reports if doing double blind. - if ( doBlind()) - for (Enumeration i = connections.elements(); i.hasMoreElements();) { - final Connection conn = (Connection)i.nextElement(); - Player p = game.getPlayer(conn.getId()); - - Report.addNewline(p.getTurnReport()); - } - Report.addNewline(vPhaseReport); - } - - public void doAssaultDrop(Entity entity) { - PilotingRollData psr; - if(entity instanceof Mech) { - psr=entity.getBasePilotingRoll(); - } else { - psr=new PilotingRollData(entity.getId(),4,"landing assault drop"); - } - int roll = Compute.d6(2); - //check for a safe landing - Report r = new Report(2380); - r.subject = entity.getId(); - r.add(entity.getDisplayName(), true); - r.add(psr.getValueAsString()); - r.add(roll); - r.choose(roll >= psr.getValue()); - addReport(r); - if(roll < psr.getValue()) { - int fallHeight = psr.getValue() - roll; - //determine where we really land - int distance = Compute.d6(fallHeight); - Coords c = Compute.scatter(entity.getPosition(), distance); - r = new Report(2385); - r.subject = entity.getId(); - r.add(distance); - r.indent(3); - r.newlines = 0; - addReport(r); - if(fallHeight >=5 || !game.getBoard().contains(c)) { - r = new Report(2386); - addReport(r); - game.removeEntity(entity.getId(),IEntityRemovalConditions.REMOVE_NEVER_JOINED); - return; - } - entity.setPosition(c); - - //do fall damage - if(entity instanceof Mech || entity instanceof Protomech) { - entity.setElevation(fallHeight); - doEntityFallsInto(entity, c, c, psr, true); - } - else if(entity instanceof BattleArmor) { - for(int i=1;i 0 && !eruption)) - && !(en.isImmobile())) { - return; - } - Report r; - boolean isMech = en instanceof Mech; - if(isMech) - r = new Report(2405); - else - r = new Report(2400); - r.addDesc(en); - r.subject = en.getId(); - addReport(r); - if(isMech) { - HitData h; - for(int i=0;i hex.terrainLevel(Terrains.BLDG_ELEV))) { - bldgAbsorbs = bldg.getPhaseCF() / 10; - if(!(ammo != null && ammo.getMunitionType() == AmmoType.M_FLECHETTE)) { - //damage the building - r = damageBuilding( bldg, damage ); - r.subject = subjectId; - addReport(r); - addNewLines(); - } - } - - if(flak - && (flakElevation <= 0 - || flakElevation <= hex.terrainLevel(Terrains.BLDG_ELEV) - || flakElevation == hex.terrainLevel(Terrains.BRIDGE_ELEV))) { - //Flak in this hex would only hit landed units - return; - } - - // get units in hex - for (Enumeration impactHexHits = game.getEntities(coords);impactHexHits.hasMoreElements();) { - Entity entity = (Entity)impactHexHits.nextElement(); - int hits = damage; - ToHitData toHit = new ToHitData(); - int cluster = 5; - - //Check: is entity excluded? - if(entity == exclude) - continue; - - //Check: is entity inside building? - if(bldg != null && - bldgAbsorbs > 0 && - entity.getElevation() < hex.terrainLevel(Terrains.BLDG_ELEV)) { - cluster -= bldgAbsorbs; - if(entity instanceof Infantry) { - continue; //took its damage already from building damage - } - else if(cluster <= 0) { - //entity takes no damage - r = new Report(6426); - r.subject = subjectId; - r.addDesc(entity); - addReport(r); - continue; - } else { - r = new Report(6425); - r.subject = subjectId; - r.add(bldgAbsorbs); - addReport(r); - } - } - - if(flak) { - //Check: is entity not a VTOL in flight - if (!(entity instanceof VTOL || - entity.getMovementMode()==IEntityMovementMode.VTOL)) { - continue; - } - //Check: is entity at correct elevation? - if(entity.getElevation() != flakElevation) - continue; - } else { - //Check: is entity a VTOL in flight? - if (entity instanceof VTOL || - entity.getMovementMode()==IEntityMovementMode.VTOL) { - // VTOLs take no damage from normal artillery unless landed - if (entity.getElevation()!=0 - && entity.getElevation()!=hex.terrainLevel(Terrains.BLDG_ELEV) - && entity.getElevation()!=hex.terrainLevel(Terrains.BRIDGE_ELEV)) { - continue; - } - } - } - - //Work out hit table to use - if (attackSource!=null) { - toHit.setSideTable(entity.sideTable(attackSource)); - if(ammo != null - && entity instanceof Mech - && ammo.getMunitionType() == AmmoType.M_CLUSTER - && attackSource.equals(coords)) { - toHit.setHitTable(ToHitData.HIT_ABOVE); - } - } - - //Entity/ammo specific damage modifiers - if(ammo != null) { - if(ammo.getMunitionType() == AmmoType.M_CLUSTER) { - if(hex.containsTerrain(Terrains.FORTIFIED) - && entity instanceof Infantry - && !(entity instanceof BattleArmor)) { - hits *= 2; - } - if(hex.containsTerrain(Terrains.WOODS) - || hex.containsTerrain(Terrains.JUNGLE)) { - hits = (hits + 1) / 2; - } - } - else if(ammo.getMunitionType() == AmmoType.M_FLECHETTE) { - //wheeled and hover tanks take movement critical - if(entity instanceof Tank && - (entity.getMovementMode() == IEntityMovementMode.WHEELED || - entity.getMovementMode() == IEntityMovementMode.HOVER)) { - r = new Report(6480); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(toHit.getTableDesc()); - r.add(0); - addReport(r); - vehicleMotiveDamage((Tank)entity, 0); - continue; - } - //non infantry are immune - if(entity instanceof BattleArmor || - !(entity instanceof Infantry)) { - continue; - } - if(hex.containsTerrain(Terrains.WOODS) - || hex.containsTerrain(Terrains.JUNGLE)) { - hits = (hits + 1) / 2; - } - } - } - - //Do the damage - addNewLines(); - r = new Report(6480); - r.subject = entity.getId(); - r.addDesc(entity); - r.add(toHit.getTableDesc()); - r.add(hits); - addReport(r); - while(hits>0) { - HitData hit = entity.rollHitLocation(toHit.getHitTable(), toHit.getSideTable()); - - addReport( damageEntity(entity, hit, Math.min(cluster, hits), false, 0, false, true, false)); - hits -= Math.min(5,hits); - } - if(killer != null) { - creditKill(entity, killer); - } - addNewLines(); - } - } - - /** - * deal area saturation damage to the map, used for artillery - * @param centre The hex on which damage is centred - * @param attackSource The position the attack came from - * @param ammo The ammo type doing the damage - * @param subjectId Subject for reports - * @param killer Who should be credited with kills - * @param flak Flak, hits flying units only, instead of flyers being immune - * @param altitude Absolute altitude for flak attack - */ - void artilleryDamageArea(Coords centre, Coords attackSource, AmmoType ammo, int subjectId, Entity killer, boolean flak, int altitude) { - int damage; - int falloff=5; - if(ammo.getMunitionType() == AmmoType.M_FLECHETTE) { - damage = ammo.getRackSize() + 10; - } - else if(ammo.getMunitionType() == AmmoType.M_CLUSTER) { - if(ammo.getAmmoType() == AmmoType.T_SNIPER) - damage = 15; - else - damage = ammo.getRackSize(); - attackSource = centre; - } - else if(game.getOptions().booleanOption("maxtech_artillery")) { - //"standard" mutates into high explosive - if(ammo.getAmmoType() == AmmoType.T_LONG_TOM) - damage = 25; - else - damage = ammo.getRackSize() + 10; - falloff = 10; - } - else { - //level 2 ammo - damage = ammo.getRackSize(); - falloff = (damage + 1) / 2; - } - artilleryDamageArea(centre, attackSource, ammo, subjectId, killer, damage, falloff, flak, altitude); - } - - /** - * Deals area-saturation damage to an area of the board. - * Used for artillery, bombs, or anything else with linear decreas in damage - * @param centre The hex on which damage is centred - * @param attackSource The position the attack came from - * @param ammo The ammo type doing the damage - * @param subjectId Subject for reports - * @param killer Who should be credited with kills - * @param damage Damage at ground zero - * @param falloff Reduction in damage for each hex of distance - * @param flak Flak, hits flying units only, instead of flyers being immune - * @param altitude Absolute altitude for flak attack - */ - void artilleryDamageArea(Coords centre, Coords attackSource, AmmoType ammo, int subjectId, Entity killer, int damage, int falloff, boolean flak, int altitude) { - for(int ring=0;damage > 0;ring++,damage-=falloff) { - ArrayList hexes = Compute.coordsAtRange(centre, ring); - for(Coords c : hexes) { - artilleryDamageHex(c, attackSource, damage, ammo, subjectId, killer, null, flak, altitude); - } - attackSource = centre; // all splash comes from ground zero - } - } -} - diff --git a/java/cvsvintage/UMLModelElementStereotypeComboBoxModel_1.3_1.4_v0.java b/java/cvsvintage/UMLModelElementStereotypeComboBoxModel_1.3_1.4_v0.java deleted file mode 100644 index 81c7280..0000000 --- a/java/cvsvintage/UMLModelElementStereotypeComboBoxModel_1.3_1.4_v0.java +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) 1996-99 The Regents of the University of California. All -// Rights Reserved. Permission to use, copy, modify, and distribute this -// software and its documentation without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph appear in all copies. This software program and -// documentation are copyrighted by The Regents of the University of -// California. The software program and documentation are supplied "AS -// IS", without any accompanying services from The Regents. The Regents -// does not warrant that the operation of the program will be -// uninterrupted or error-free. The end-user understands that the program -// was developed for research purposes and is advised not to rely -// exclusively on the program for any reason. IN NO EVENT SHALL THE -// UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, -// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, -// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF -// THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF -// SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE -// PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF -// CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, -// UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - -// $header$ -package org.argouml.uml.ui.foundation.core; - -import org.argouml.model.uml.foundation.extensionmechanisms.ExtensionMechanismsHelper; -import org.argouml.model.uml.modelmanagement.ModelManagementHelper; -import org.argouml.uml.ui.UMLComboBoxModel2; -import org.argouml.uml.ui.UMLUserInterfaceContainer; -import ru.novosoft.uml.MElementEvent; -import ru.novosoft.uml.foundation.core.MModelElement; -import ru.novosoft.uml.foundation.extension_mechanisms.MStereotype; - -/** - * @since Oct 10, 2002 - * @author jaap.branderhorst@xs4all.nl - */ -public class UMLModelElementStereotypeComboBoxModel extends UMLComboBoxModel2 { - - /** - * Constructor for UMLModelElementStereotypeComboBoxModel. - * @param container - */ - public UMLModelElementStereotypeComboBoxModel(UMLUserInterfaceContainer container) { - super(container, true); - } - - /** - * @see org.argouml.uml.ui.UMLComboBoxModel2#isValidRoleAdded(ru.novosoft.uml.MElementEvent) - */ - protected boolean isValidRoleAdded(MElementEvent e) { - Object o = getChangedElement(e); - return o instanceof MStereotype - && ExtensionMechanismsHelper.getHelper().isValidStereoType((MModelElement)getTarget(), (MStereotype)o); - } - - /** - * @see org.argouml.uml.ui.UMLComboBoxModel2#isValidPropertySet(ru.novosoft.uml.MElementEvent) - */ - protected boolean isValidPropertySet(MElementEvent e) { - return e.getSource() == getTarget() && e.getName().equals("stereotype"); - } - - /** - * @see org.argouml.uml.ui.UMLComboBoxModel2#buildModelList() - */ - protected void buildModelList() { - MModelElement elem = (MModelElement)getTarget(); - setElements(ExtensionMechanismsHelper.getHelper().getAllPossibleStereotypes(elem)); - } - - /** - * @see org.argouml.uml.ui.UMLComboBoxModel2#getSelectedModelElement() - */ - protected Object getSelectedModelElement() { - if (getTarget() != null) { - return ((MModelElement)getTarget()).getStereotype(); - } - return null; - } - -} diff --git a/java/cvsvintage/UMLModelElementStereotypeComboBoxModel_1.3_1.4_v1.java b/java/cvsvintage/UMLModelElementStereotypeComboBoxModel_1.3_1.4_v1.java deleted file mode 100644 index 0ca9e69..0000000 --- a/java/cvsvintage/UMLModelElementStereotypeComboBoxModel_1.3_1.4_v1.java +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 1996-99 The Regents of the University of California. All -// Rights Reserved. Permission to use, copy, modify, and distribute this -// software and its documentation without fee, and without a written -// agreement is hereby granted, provided that the above copyright notice -// and this paragraph appear in all copies. This software program and -// documentation are copyrighted by The Regents of the University of -// California. The software program and documentation are supplied "AS -// IS", without any accompanying services from The Regents. The Regents -// does not warrant that the operation of the program will be -// uninterrupted or error-free. The end-user understands that the program -// was developed for research purposes and is advised not to rely -// exclusively on the program for any reason. IN NO EVENT SHALL THE -// UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, -// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, -// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF -// THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF -// SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE -// PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF -// CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, -// UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - -// $header$ -package org.argouml.uml.ui.foundation.core; - -import org.argouml.model.uml.foundation.extensionmechanisms.ExtensionMechanismsHelper; -import org.argouml.model.uml.modelmanagement.ModelManagementHelper; -import org.argouml.uml.ui.UMLComboBoxModel2; -import org.argouml.uml.ui.UMLUserInterfaceContainer; -import ru.novosoft.uml.MElementEvent; -import ru.novosoft.uml.foundation.core.MModelElement; -import ru.novosoft.uml.foundation.extension_mechanisms.MStereotype; - -/** - * @since Oct 10, 2002 - * @author jaap.branderhorst@xs4all.nl - */ -public class UMLModelElementStereotypeComboBoxModel extends UMLComboBoxModel2 { - - /** - * Constructor for UMLModelElementStereotypeComboBoxModel. - * @param container - */ - public UMLModelElementStereotypeComboBoxModel(UMLUserInterfaceContainer container) { - super(container, true); - } - - /** - * @see org.argouml.uml.ui.UMLComboBoxModel2#isValidRoleAdded(ru.novosoft.uml.MElementEvent) - */ - protected boolean isValidRoleAdded(MElementEvent e) { - Object o = getChangedElement(e); - return o instanceof MStereotype - && ExtensionMechanismsHelper.getHelper().isValidStereoType((MModelElement)getTarget(), (MStereotype)o); - } - - /** - * @see org.argouml.uml.ui.UMLComboBoxModel2#isValidPropertySet(ru.novosoft.uml.MElementEvent) - */ - protected boolean isValidPropertySet(MElementEvent e) { - return (e.getSource() == getTarget() && e.getName().equals("stereotype") || - (e.getSource() instanceof MStereotype && e.getName().equals("base")) || - (e.getSource() instanceof MStereotype && e.getName().equals("name"))); - } - - /** - * @see org.argouml.uml.ui.UMLComboBoxModel2#buildModelList() - */ - protected void buildModelList() { - MModelElement elem = (MModelElement)getTarget(); - setElements(ExtensionMechanismsHelper.getHelper().getAllPossibleStereotypes(elem)); - } - - /** - * @see org.argouml.uml.ui.UMLComboBoxModel2#getSelectedModelElement() - */ - protected Object getSelectedModelElement() { - if (getTarget() != null) { - return ((MModelElement)getTarget()).getStereotype(); - } - return null; - } - -} diff --git a/java/michal_v0.java b/java/michal_v0.java deleted file mode 100644 index 70e4c88..0000000 --- a/java/michal_v0.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Cmd_open.java - Command - * Copyright (C) 1998 Slava Pestov - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -import java.io.File; -import java.util.Hashtable; - -public class Cmd_open implements Command -{ - public Object init(Hashtable args) - { - return Boolean.TRUE; - } - - public Object exec(Hashtable args) - { - return (jEdit.buffers.openBuffer((View)args.get(VIEW), - (String)args.get(ARG)) == null) ? Boolean.FALSE - : Boolean.TRUE; - } -} - diff --git a/java/michal_v1.java b/java/michal_v1.java deleted file mode 100644 index 1299cfa..0000000 --- a/java/michal_v1.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Cmd_open_url.java - Command - * Copyright (C) 1998 Slava Pestov - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -import java.io.File; -import java.util.Hashtable; - -public class Cmd_open_url implements Command -{ - public Object init(Hashtable args) - { - return null; - } - - public Object exec(Hashtable args) - { - jEdit.buffers.openURL((View)args.get(VIEW)); - return null; - } -} - diff --git a/java/oldies/AlterTableAlterColumn_4076_4129_v0.java b/java/oldies/AlterTableAlterColumn_4076_4129_v0.java deleted file mode 100644 index 4f98237..0000000 --- a/java/oldies/AlterTableAlterColumn_4076_4129_v0.java +++ /dev/null @@ -1,473 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import java.util.ArrayList; -import java.util.HashSet; -import org.h2.command.CommandInterface; -import org.h2.command.Parser; -import org.h2.command.Prepared; -import org.h2.constant.ErrorCode; -import org.h2.constraint.Constraint; -import org.h2.constraint.ConstraintReferential; -import org.h2.engine.Database; -import org.h2.engine.DbObject; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionVisitor; -import org.h2.index.Index; -import org.h2.index.IndexType; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.schema.Schema; -import org.h2.schema.SchemaObject; -import org.h2.schema.Sequence; -import org.h2.schema.TriggerObject; -import org.h2.table.Column; -import org.h2.table.Table; -import org.h2.table.TableView; -import org.h2.util.New; - -/** - * This class represents the statements - * ALTER TABLE ADD, - * ALTER TABLE ADD IF NOT EXISTS, - * ALTER TABLE ALTER COLUMN, - * ALTER TABLE ALTER COLUMN RESTART, - * ALTER TABLE ALTER COLUMN SELECTIVITY, - * ALTER TABLE ALTER COLUMN SET DEFAULT, - * ALTER TABLE ALTER COLUMN SET NOT NULL, - * ALTER TABLE ALTER COLUMN SET NULL, - * ALTER TABLE DROP COLUMN - */ -public class AlterTableAlterColumn extends SchemaCommand { - - private Table table; - private Column oldColumn; - private Column newColumn; - private int type; - private Expression defaultExpression; - private Expression newSelectivity; - private String addBefore; - private boolean ifNotExists; - - public AlterTableAlterColumn(Session session, Schema schema) { - super(session, schema); - } - - public void setTable(Table table) { - this.table = table; - } - - public void setOldColumn(Column oldColumn) { - this.oldColumn = oldColumn; - } - - public void setAddBefore(String before) { - this.addBefore = before; - } - - public int update() { - session.commit(true); - Database db = session.getDatabase(); - session.getUser().checkRight(table, Right.ALL); - table.checkSupportAlter(); - table.lock(session, true, true); - Sequence sequence = oldColumn == null ? null : oldColumn.getSequence(); - if (newColumn != null) { - checkDefaultReferencesTable(newColumn.getDefaultExpression()); - } - switch (type) { - case CommandInterface.ALTER_TABLE_ALTER_COLUMN_NOT_NULL: { - if (!oldColumn.isNullable()) { - // no change - break; - } - checkNoNullValues(); - oldColumn.setNullable(false); - db.update(session, table); - break; - } - case CommandInterface.ALTER_TABLE_ALTER_COLUMN_NULL: { - if (oldColumn.isNullable()) { - // no change - break; - } - checkNullable(); - oldColumn.setNullable(true); - db.update(session, table); - break; - } - case CommandInterface.ALTER_TABLE_ALTER_COLUMN_DEFAULT: { - checkDefaultReferencesTable(defaultExpression); - oldColumn.setSequence(null); - oldColumn.setDefaultExpression(session, defaultExpression); - removeSequence(sequence); - db.update(session, table); - break; - } - case CommandInterface.ALTER_TABLE_ALTER_COLUMN_CHANGE_TYPE: { - // if the change is only increasing the precision, then we don't - // need to copy the table because the length is only a constraint, - // and does not affect the storage structure. - if (oldColumn.isWideningConversion(newColumn)) { - convertAutoIncrementColumn(newColumn); - oldColumn.copy(newColumn); - db.update(session, table); - } else { - oldColumn.setSequence(null); - oldColumn.setDefaultExpression(session, null); - oldColumn.setConvertNullToDefault(false); - if (oldColumn.isNullable() && !newColumn.isNullable()) { - checkNoNullValues(); - } else if (!oldColumn.isNullable() && newColumn.isNullable()) { - checkNullable(); - } - convertAutoIncrementColumn(newColumn); - copyData(); - } - break; - } - case CommandInterface.ALTER_TABLE_ADD_COLUMN: { - if (ifNotExists && table.doesColumnExist(newColumn.getName())) { - break; - } - convertAutoIncrementColumn(newColumn); - copyData(); - break; - } - case CommandInterface.ALTER_TABLE_DROP_COLUMN: { - if (table.getColumns().length == 1) { - throw DbException.get(ErrorCode.CANNOT_DROP_LAST_COLUMN, oldColumn.getSQL()); - } - table.dropSingleColumnConstraintsAndIndexes(session, oldColumn); - copyData(); - break; - } - case CommandInterface.ALTER_TABLE_ALTER_COLUMN_SELECTIVITY: { - int value = newSelectivity.optimize(session).getValue(session).getInt(); - oldColumn.setSelectivity(value); - db.update(session, table); - break; - } - default: - DbException.throwInternalError("type=" + type); - } - return 0; - } - - private void checkDefaultReferencesTable(Expression defaultExpression) { - if (defaultExpression == null) { - return; - } - HashSet dependencies = New.hashSet(); - ExpressionVisitor visitor = ExpressionVisitor.getDependenciesVisitor(dependencies); - defaultExpression.isEverything(visitor); - if (dependencies.contains(table)) { - throw DbException.get(ErrorCode.COLUMN_IS_REFERENCED_1, defaultExpression.getSQL()); - } - } - - private void convertAutoIncrementColumn(Column c) { - if (c.isAutoIncrement()) { - if (c.isPrimaryKey()) { - c.setOriginalSQL("IDENTITY"); - } else { - int objId = getObjectId(); - c.convertAutoIncrementToSequence(session, getSchema(), objId, table.isTemporary()); - } - } - } - - private void removeSequence(Sequence sequence) { - if (sequence != null) { - table.removeSequence(session, sequence); - sequence.setBelongsToTable(false); - Database db = session.getDatabase(); - db.removeSchemaObject(session, sequence); - } - } - - private void copyData() { - if (table.isTemporary()) { - throw DbException.getUnsupportedException("TEMP TABLE"); - } - Database db = session.getDatabase(); - String baseName = table.getName(); - String tempName = db.getTempTableName(baseName, session); - Column[] columns = table.getColumns(); - ArrayList newColumns = New.arrayList(); - Table newTable = cloneTableStructure(columns, db, tempName, newColumns); - try { - // check if a view would become invalid - // (because the column to drop is referenced or so) - checkViews(table, newTable); - } catch (DbException e) { - execute("DROP TABLE " + newTable.getName(), true); - throw DbException.get(ErrorCode.VIEW_IS_INVALID_2, e, getSQL(), e.getMessage()); - } - String tableName = table.getName(); - ArrayList views = table.getViews(); - if (views != null) { - views = New.arrayList(views); - for (TableView view : views) { - table.removeView(view); - } - } - execute("DROP TABLE " + table.getSQL() + " IGNORE", true); - db.renameSchemaObject(session, newTable, tableName); - for (DbObject child : newTable.getChildren()) { - if (child instanceof Sequence) { - continue; - } - String name = child.getName(); - if (name == null || child.getCreateSQL() == null) { - continue; - } - if (name.startsWith(tempName + "_")) { - name = name.substring(tempName.length() + 1); - SchemaObject so = (SchemaObject) child; - if (so instanceof Constraint) { - if (so.getSchema().findConstraint(session, name) != null) { - name = so.getSchema().getUniqueConstraintName(session, newTable); - } - } else if (so instanceof Index) { - if (so.getSchema().findIndex(session, name) != null) { - name = so.getSchema().getUniqueIndexName(session, newTable, name); - } - } - db.renameSchemaObject(session, so, name); - } - } - if (views != null) { - for (TableView view : views) { - String sql = view.getCreateSQL(true, true); - execute(sql, true); - } - } - } - - private Table cloneTableStructure(Column[] columns, Database db, String tempName, ArrayList newColumns) { - for (Column col : columns) { - newColumns.add(col.getClone()); - } - if (type == CommandInterface.ALTER_TABLE_DROP_COLUMN) { - int position = oldColumn.getColumnId(); - newColumns.remove(position); - } else if (type == CommandInterface.ALTER_TABLE_ADD_COLUMN) { - int position; - if (addBefore == null) { - position = columns.length; - } else { - position = table.getColumn(addBefore).getColumnId(); - } - newColumns.add(position, newColumn); - } else if (type == CommandInterface.ALTER_TABLE_ALTER_COLUMN_CHANGE_TYPE) { - int position = oldColumn.getColumnId(); - newColumns.remove(position); - newColumns.add(position, newColumn); - } - - // create a table object in order to get the SQL statement - // can't just use this table, because most column objects are 'shared' - // with the old table - // still need a new id because using 0 would mean: the new table tries - // to use the rows of the table 0 (the meta table) - int id = db.allocateObjectId(); - CreateTableData data = new CreateTableData(); - data.tableName = tempName; - data.id = id; - data.columns = newColumns; - data.temporary = table.isTemporary(); - data.persistData = table.isPersistData(); - data.persistIndexes = table.isPersistIndexes(); - data.isHidden = table.isHidden(); - data.create = true; - data.session = session; - Table newTable = getSchema().createTable(data); - newTable.setComment(table.getComment()); - StringBuilder buff = new StringBuilder(); - buff.append(newTable.getCreateSQL()); - StringBuilder columnList = new StringBuilder(); - for (Column nc : newColumns) { - if (columnList.length() > 0) { - columnList.append(", "); - } - if (type == CommandInterface.ALTER_TABLE_ADD_COLUMN && nc == newColumn) { - Expression def = nc.getDefaultExpression(); - columnList.append(def == null ? "NULL" : def.getSQL()); - } else { - columnList.append(nc.getSQL()); - } - } - buff.append(" AS SELECT "); - if (columnList.length() == 0) { - // special case: insert into test select * from - buff.append('*'); - } else { - buff.append(columnList); - } - buff.append(" FROM ").append(table.getSQL()); - String newTableSQL = buff.toString(); - String newTableName = newTable.getName(); - Schema newTableSchema = newTable.getSchema(); - newTable.removeChildrenAndResources(session); - - execute(newTableSQL, true); - newTable = newTableSchema.getTableOrView(session, newTableName); - ArrayList triggers = New.arrayList(); - for (DbObject child : table.getChildren()) { - if (child instanceof Sequence) { - continue; - } else if (child instanceof Index) { - Index idx = (Index) child; - if (idx.getIndexType().getBelongsToConstraint()) { - continue; - } - } - String createSQL = child.getCreateSQL(); - if (createSQL == null) { - continue; - } - if (child instanceof TableView) { - continue; - } else if (child.getType() == DbObject.TABLE_OR_VIEW) { - DbException.throwInternalError(); - } - String quotedName = Parser.quoteIdentifier(tempName + "_" + child.getName()); - String sql = null; - if (child instanceof ConstraintReferential) { - ConstraintReferential r = (ConstraintReferential) child; - if (r.getTable() != table) { - sql = r.getCreateSQLForCopy(r.getTable(), newTable, quotedName, false); - } - } - if (sql == null) { - sql = child.getCreateSQLForCopy(newTable, quotedName); - } - if (sql != null) { - if (child instanceof TriggerObject) { - triggers.add(sql); - } else { - execute(sql, true); - } - } - } - table.setModified(); - // remove the sequences from the columns (except dropped columns) - // otherwise the sequence is dropped if the table is dropped - for (Column col : newColumns) { - Sequence seq = col.getSequence(); - if (seq != null) { - table.removeSequence(session, seq); - col.setSequence(null); - } - } - for (String sql : triggers) { - execute(sql, true); - } - return newTable; - } - - /** - * Check that all views and other dependent objects. - */ - private void checkViews(SchemaObject sourceTable, SchemaObject newTable) { - String sourceTableName = sourceTable.getName(); - String newTableName = newTable.getName(); - Database db = sourceTable.getDatabase(); - // save the real table under a temporary name - String temp = db.getTempTableName(sourceTableName, session); - db.renameSchemaObject(session, sourceTable, temp); - try { - // have our new table impersonate the target table - db.renameSchemaObject(session, newTable, sourceTableName); - checkViewsAreValid(sourceTable); - } finally { - // always put the source tables back with their proper names - try { - db.renameSchemaObject(session, newTable, newTableName); - } finally { - db.renameSchemaObject(session, sourceTable, sourceTableName); - } - } - } - - /** - * Check that a table or view is still valid. - * - * @param tableOrView the table or view to check - */ - private void checkViewsAreValid(DbObject tableOrView) { - for (DbObject view : tableOrView.getChildren()) { - if (view instanceof TableView) { - String sql = ((TableView) view).getQuery(); - // check if the query is still valid - // do not execute, not even with limit 1, because that could - // have side effects or take a very long time - session.prepare(sql); - checkViewsAreValid(view); - } - } - } - - private void execute(String sql, boolean ddl) { - Prepared command = session.prepare(sql); - command.update(); - if (ddl) { - session.commit(true); - } - } - - private void checkNullable() { - for (Index index : table.getIndexes()) { - if (index.getColumnIndex(oldColumn) < 0) { - continue; - } - IndexType indexType = index.getIndexType(); - if (indexType.isPrimaryKey() || indexType.isHash()) { - throw DbException.get(ErrorCode.COLUMN_IS_PART_OF_INDEX_1, index.getSQL()); - } - } - } - - private void checkNoNullValues() { - String sql = "SELECT COUNT(*) FROM " + table.getSQL() + " WHERE " + oldColumn.getSQL() + " IS NULL"; - Prepared command = session.prepare(sql); - ResultInterface result = command.query(0); - result.next(); - if (result.currentRow()[0].getInt() > 0) { - throw DbException.get(ErrorCode.COLUMN_CONTAINS_NULL_VALUES_1, oldColumn.getSQL()); - } - } - - public void setType(int type) { - this.type = type; - } - - public void setSelectivity(Expression selectivity) { - newSelectivity = selectivity; - } - - public void setDefaultExpression(Expression defaultExpression) { - this.defaultExpression = defaultExpression; - } - - public void setNewColumn(Column newColumn) { - this.newColumn = newColumn; - } - - public int getType() { - return type; - } - - public void setIfNotExists(boolean ifNotExists) { - this.ifNotExists = ifNotExists; - } - -} diff --git a/java/oldies/AlterTableAlterColumn_4076_4129_v1.java b/java/oldies/AlterTableAlterColumn_4076_4129_v1.java deleted file mode 100644 index fda4ef6..0000000 --- a/java/oldies/AlterTableAlterColumn_4076_4129_v1.java +++ /dev/null @@ -1,487 +0,0 @@ -/* - * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License, - * Version 1.0, and under the Eclipse Public License, Version 1.0 - * (http://h2database.com/html/license.html). - * Initial Developer: H2 Group - */ -package org.h2.command.ddl; - -import java.util.ArrayList; -import java.util.HashSet; -import org.h2.command.CommandInterface; -import org.h2.command.Parser; -import org.h2.command.Prepared; -import org.h2.constant.ErrorCode; -import org.h2.constraint.Constraint; -import org.h2.constraint.ConstraintReferential; -import org.h2.engine.Database; -import org.h2.engine.DbObject; -import org.h2.engine.Right; -import org.h2.engine.Session; -import org.h2.expression.Expression; -import org.h2.expression.ExpressionVisitor; -import org.h2.index.Index; -import org.h2.index.IndexType; -import org.h2.message.DbException; -import org.h2.result.ResultInterface; -import org.h2.schema.Schema; -import org.h2.schema.SchemaObject; -import org.h2.schema.Sequence; -import org.h2.schema.TriggerObject; -import org.h2.table.Column; -import org.h2.table.Table; -import org.h2.table.TableView; -import org.h2.util.New; - -/** - * This class represents the statements - * ALTER TABLE ADD, - * ALTER TABLE ADD IF NOT EXISTS, - * ALTER TABLE ALTER COLUMN, - * ALTER TABLE ALTER COLUMN RESTART, - * ALTER TABLE ALTER COLUMN SELECTIVITY, - * ALTER TABLE ALTER COLUMN SET DEFAULT, - * ALTER TABLE ALTER COLUMN SET NOT NULL, - * ALTER TABLE ALTER COLUMN SET NULL, - * ALTER TABLE DROP COLUMN - */ -public class AlterTableAlterColumn extends SchemaCommand { - - private Table table; - private Column oldColumn; - private Column newColumn; - private int type; - private Expression defaultExpression; - private Expression newSelectivity; - private String addBefore; - private boolean ifNotExists; - private ArrayList columnsToAdd; - - public AlterTableAlterColumn(Session session, Schema schema) { - super(session, schema); - } - - public void setTable(Table table) { - this.table = table; - } - - public void setOldColumn(Column oldColumn) { - this.oldColumn = oldColumn; - } - - public void setAddBefore(String before) { - this.addBefore = before; - } - - public int update() { - session.commit(true); - Database db = session.getDatabase(); - session.getUser().checkRight(table, Right.ALL); - table.checkSupportAlter(); - table.lock(session, true, true); - Sequence sequence = oldColumn == null ? null : oldColumn.getSequence(); - if (newColumn != null) { - checkDefaultReferencesTable(newColumn.getDefaultExpression()); - } - if (columnsToAdd != null) { - for (Column column : columnsToAdd) { - checkDefaultReferencesTable(column.getDefaultExpression()); - } - } - switch (type) { - case CommandInterface.ALTER_TABLE_ALTER_COLUMN_NOT_NULL: { - if (!oldColumn.isNullable()) { - // no change - break; - } - checkNoNullValues(); - oldColumn.setNullable(false); - db.update(session, table); - break; - } - case CommandInterface.ALTER_TABLE_ALTER_COLUMN_NULL: { - if (oldColumn.isNullable()) { - // no change - break; - } - checkNullable(); - oldColumn.setNullable(true); - db.update(session, table); - break; - } - case CommandInterface.ALTER_TABLE_ALTER_COLUMN_DEFAULT: { - checkDefaultReferencesTable(defaultExpression); - oldColumn.setSequence(null); - oldColumn.setDefaultExpression(session, defaultExpression); - removeSequence(sequence); - db.update(session, table); - break; - } - case CommandInterface.ALTER_TABLE_ALTER_COLUMN_CHANGE_TYPE: { - // if the change is only increasing the precision, then we don't - // need to copy the table because the length is only a constraint, - // and does not affect the storage structure. - if (oldColumn.isWideningConversion(newColumn)) { - convertAutoIncrementColumn(newColumn); - oldColumn.copy(newColumn); - db.update(session, table); - } else { - oldColumn.setSequence(null); - oldColumn.setDefaultExpression(session, null); - oldColumn.setConvertNullToDefault(false); - if (oldColumn.isNullable() && !newColumn.isNullable()) { - checkNoNullValues(); - } else if (!oldColumn.isNullable() && newColumn.isNullable()) { - checkNullable(); - } - convertAutoIncrementColumn(newColumn); - copyData(); - } - break; - } - case CommandInterface.ALTER_TABLE_ADD_COLUMN: { - // ifNotExists only supported for single column add - if (ifNotExists && columnsToAdd.size() == 1 && table.doesColumnExist(columnsToAdd.get(0).getName())) { - break; - } - for (Column column : columnsToAdd) { - convertAutoIncrementColumn(column); - } - copyData(); - break; - } - case CommandInterface.ALTER_TABLE_DROP_COLUMN: { - if (table.getColumns().length == 1) { - throw DbException.get(ErrorCode.CANNOT_DROP_LAST_COLUMN, oldColumn.getSQL()); - } - table.dropSingleColumnConstraintsAndIndexes(session, oldColumn); - copyData(); - break; - } - case CommandInterface.ALTER_TABLE_ALTER_COLUMN_SELECTIVITY: { - int value = newSelectivity.optimize(session).getValue(session).getInt(); - oldColumn.setSelectivity(value); - db.update(session, table); - break; - } - default: - DbException.throwInternalError("type=" + type); - } - return 0; - } - - private void checkDefaultReferencesTable(Expression defaultExpression) { - if (defaultExpression == null) { - return; - } - HashSet dependencies = New.hashSet(); - ExpressionVisitor visitor = ExpressionVisitor.getDependenciesVisitor(dependencies); - defaultExpression.isEverything(visitor); - if (dependencies.contains(table)) { - throw DbException.get(ErrorCode.COLUMN_IS_REFERENCED_1, defaultExpression.getSQL()); - } - } - - private void convertAutoIncrementColumn(Column c) { - if (c.isAutoIncrement()) { - if (c.isPrimaryKey()) { - c.setOriginalSQL("IDENTITY"); - } else { - int objId = getObjectId(); - c.convertAutoIncrementToSequence(session, getSchema(), objId, table.isTemporary()); - } - } - } - - private void removeSequence(Sequence sequence) { - if (sequence != null) { - table.removeSequence(session, sequence); - sequence.setBelongsToTable(false); - Database db = session.getDatabase(); - db.removeSchemaObject(session, sequence); - } - } - - private void copyData() { - if (table.isTemporary()) { - throw DbException.getUnsupportedException("TEMP TABLE"); - } - Database db = session.getDatabase(); - String baseName = table.getName(); - String tempName = db.getTempTableName(baseName, session); - Column[] columns = table.getColumns(); - ArrayList newColumns = New.arrayList(); - Table newTable = cloneTableStructure(columns, db, tempName, newColumns); - try { - // check if a view would become invalid - // (because the column to drop is referenced or so) - checkViews(table, newTable); - } catch (DbException e) { - execute("DROP TABLE " + newTable.getName(), true); - throw DbException.get(ErrorCode.VIEW_IS_INVALID_2, e, getSQL(), e.getMessage()); - } - String tableName = table.getName(); - ArrayList views = table.getViews(); - if (views != null) { - views = New.arrayList(views); - for (TableView view : views) { - table.removeView(view); - } - } - execute("DROP TABLE " + table.getSQL() + " IGNORE", true); - db.renameSchemaObject(session, newTable, tableName); - for (DbObject child : newTable.getChildren()) { - if (child instanceof Sequence) { - continue; - } - String name = child.getName(); - if (name == null || child.getCreateSQL() == null) { - continue; - } - if (name.startsWith(tempName + "_")) { - name = name.substring(tempName.length() + 1); - SchemaObject so = (SchemaObject) child; - if (so instanceof Constraint) { - if (so.getSchema().findConstraint(session, name) != null) { - name = so.getSchema().getUniqueConstraintName(session, newTable); - } - } else if (so instanceof Index) { - if (so.getSchema().findIndex(session, name) != null) { - name = so.getSchema().getUniqueIndexName(session, newTable, name); - } - } - db.renameSchemaObject(session, so, name); - } - } - if (views != null) { - for (TableView view : views) { - String sql = view.getCreateSQL(true, true); - execute(sql, true); - } - } - } - - private Table cloneTableStructure(Column[] columns, Database db, String tempName, ArrayList newColumns) { - for (Column col : columns) { - newColumns.add(col.getClone()); - } - if (type == CommandInterface.ALTER_TABLE_DROP_COLUMN) { - int position = oldColumn.getColumnId(); - newColumns.remove(position); - } else if (type == CommandInterface.ALTER_TABLE_ADD_COLUMN) { - int position; - if (addBefore == null) { - position = columns.length; - } else { - position = table.getColumn(addBefore).getColumnId(); - } - for (Column column : columnsToAdd) { - newColumns.add(position++, column); - } - } else if (type == CommandInterface.ALTER_TABLE_ALTER_COLUMN_CHANGE_TYPE) { - int position = oldColumn.getColumnId(); - newColumns.remove(position); - newColumns.add(position, newColumn); - } - - // create a table object in order to get the SQL statement - // can't just use this table, because most column objects are 'shared' - // with the old table - // still need a new id because using 0 would mean: the new table tries - // to use the rows of the table 0 (the meta table) - int id = db.allocateObjectId(); - CreateTableData data = new CreateTableData(); - data.tableName = tempName; - data.id = id; - data.columns = newColumns; - data.temporary = table.isTemporary(); - data.persistData = table.isPersistData(); - data.persistIndexes = table.isPersistIndexes(); - data.isHidden = table.isHidden(); - data.create = true; - data.session = session; - Table newTable = getSchema().createTable(data); - newTable.setComment(table.getComment()); - StringBuilder buff = new StringBuilder(); - buff.append(newTable.getCreateSQL()); - StringBuilder columnList = new StringBuilder(); - for (Column nc : newColumns) { - if (columnList.length() > 0) { - columnList.append(", "); - } - if (type == CommandInterface.ALTER_TABLE_ADD_COLUMN && columnsToAdd.contains(nc)) { - Expression def = nc.getDefaultExpression(); - columnList.append(def == null ? "NULL" : def.getSQL()); - } else { - columnList.append(nc.getSQL()); - } - } - buff.append(" AS SELECT "); - if (columnList.length() == 0) { - // special case: insert into test select * from - buff.append('*'); - } else { - buff.append(columnList); - } - buff.append(" FROM ").append(table.getSQL()); - String newTableSQL = buff.toString(); - String newTableName = newTable.getName(); - Schema newTableSchema = newTable.getSchema(); - newTable.removeChildrenAndResources(session); - - execute(newTableSQL, true); - newTable = newTableSchema.getTableOrView(session, newTableName); - ArrayList triggers = New.arrayList(); - for (DbObject child : table.getChildren()) { - if (child instanceof Sequence) { - continue; - } else if (child instanceof Index) { - Index idx = (Index) child; - if (idx.getIndexType().getBelongsToConstraint()) { - continue; - } - } - String createSQL = child.getCreateSQL(); - if (createSQL == null) { - continue; - } - if (child instanceof TableView) { - continue; - } else if (child.getType() == DbObject.TABLE_OR_VIEW) { - DbException.throwInternalError(); - } - String quotedName = Parser.quoteIdentifier(tempName + "_" + child.getName()); - String sql = null; - if (child instanceof ConstraintReferential) { - ConstraintReferential r = (ConstraintReferential) child; - if (r.getTable() != table) { - sql = r.getCreateSQLForCopy(r.getTable(), newTable, quotedName, false); - } - } - if (sql == null) { - sql = child.getCreateSQLForCopy(newTable, quotedName); - } - if (sql != null) { - if (child instanceof TriggerObject) { - triggers.add(sql); - } else { - execute(sql, true); - } - } - } - table.setModified(); - // remove the sequences from the columns (except dropped columns) - // otherwise the sequence is dropped if the table is dropped - for (Column col : newColumns) { - Sequence seq = col.getSequence(); - if (seq != null) { - table.removeSequence(session, seq); - col.setSequence(null); - } - } - for (String sql : triggers) { - execute(sql, true); - } - return newTable; - } - - /** - * Check that all views and other dependent objects. - */ - private void checkViews(SchemaObject sourceTable, SchemaObject newTable) { - String sourceTableName = sourceTable.getName(); - String newTableName = newTable.getName(); - Database db = sourceTable.getDatabase(); - // save the real table under a temporary name - String temp = db.getTempTableName(sourceTableName, session); - db.renameSchemaObject(session, sourceTable, temp); - try { - // have our new table impersonate the target table - db.renameSchemaObject(session, newTable, sourceTableName); - checkViewsAreValid(sourceTable); - } finally { - // always put the source tables back with their proper names - try { - db.renameSchemaObject(session, newTable, newTableName); - } finally { - db.renameSchemaObject(session, sourceTable, sourceTableName); - } - } - } - - /** - * Check that a table or view is still valid. - * - * @param tableOrView the table or view to check - */ - private void checkViewsAreValid(DbObject tableOrView) { - for (DbObject view : tableOrView.getChildren()) { - if (view instanceof TableView) { - String sql = ((TableView) view).getQuery(); - // check if the query is still valid - // do not execute, not even with limit 1, because that could - // have side effects or take a very long time - session.prepare(sql); - checkViewsAreValid(view); - } - } - } - - private void execute(String sql, boolean ddl) { - Prepared command = session.prepare(sql); - command.update(); - if (ddl) { - session.commit(true); - } - } - - private void checkNullable() { - for (Index index : table.getIndexes()) { - if (index.getColumnIndex(oldColumn) < 0) { - continue; - } - IndexType indexType = index.getIndexType(); - if (indexType.isPrimaryKey() || indexType.isHash()) { - throw DbException.get(ErrorCode.COLUMN_IS_PART_OF_INDEX_1, index.getSQL()); - } - } - } - - private void checkNoNullValues() { - String sql = "SELECT COUNT(*) FROM " + table.getSQL() + " WHERE " + oldColumn.getSQL() + " IS NULL"; - Prepared command = session.prepare(sql); - ResultInterface result = command.query(0); - result.next(); - if (result.currentRow()[0].getInt() > 0) { - throw DbException.get(ErrorCode.COLUMN_CONTAINS_NULL_VALUES_1, oldColumn.getSQL()); - } - } - - public void setType(int type) { - this.type = type; - } - - public void setSelectivity(Expression selectivity) { - newSelectivity = selectivity; - } - - public void setDefaultExpression(Expression defaultExpression) { - this.defaultExpression = defaultExpression; - } - - public void setNewColumn(Column newColumn) { - this.newColumn = newColumn; - } - - public int getType() { - return type; - } - - public void setIfNotExists(boolean ifNotExists) { - this.ifNotExists = ifNotExists; - } - - public void setNewColumns(ArrayList columnsToAdd) { - this.columnsToAdd = columnsToAdd; - } -} diff --git a/java/oldies/BasicClient_1018_1024_v0.java b/java/oldies/BasicClient_1018_1024_v0.java deleted file mode 100644 index 9ed3a6d..0000000 --- a/java/oldies/BasicClient_1018_1024_v0.java +++ /dev/null @@ -1,318 +0,0 @@ -package com.google.code.facebookapi; - -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.SortedMap; -import java.util.TreeMap; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.json.JSONArray; -import org.json.JSONException; - -/** - * Basic client taking care of rest call mechanics (signing, etc) to facebook. Little api knowledge, no response interpretation is planned. - */ -public class BasicClient { - - protected static Log log = LogFactory.getLog( BasicClient.class ); - - protected static final String CRLF = "\r\n"; - protected static final String PREF = "--"; - protected static final int UPLOAD_BUFFER_SIZE = 1024; - - protected URL serverUrl; - protected URL serverUrlHttps; - private CommunicationStrategy communicationStrategy; - - protected final String apiKey; - protected final String secret; - protected boolean sessionSecret; - - protected String sessionKey; - - protected boolean batchMode; - protected List queries; - protected String permissionsApiKey; - - public boolean isBatchMode() { - return batchMode; - } - - protected List getQueries() { - return queries; - } - - protected BasicClient( String apiKey, String secret, boolean sessionSecret ) { - this( apiKey, secret, sessionSecret, null ); - } - - protected BasicClient( String apiKey, String secret, boolean sessionSecret, String sessionKey ) { - this( null, null, apiKey, secret, sessionSecret, sessionKey, new DefaultCommunicationStrategy() ); - } - - protected BasicClient( URL serverUrl, URL serverUrlHttps, String apiKey, String secret, boolean sessionSecret, String sessionKey, - CommunicationStrategy communicationStrategy ) { - this.sessionKey = sessionKey; - this.apiKey = apiKey; - this.secret = secret; - this.sessionSecret = sessionSecret || secret.endsWith( "__" ); - this.serverUrl = ( null != serverUrl ) ? serverUrl : FacebookApiUrls.getDefaultServerUrl(); - this.serverUrlHttps = ( null != serverUrlHttps ) ? serverUrlHttps : FacebookApiUrls.getDefaultHttpsServerUrl(); - - this.communicationStrategy = communicationStrategy; - this.batchMode = false; - this.queries = new ArrayList(); - } - - public String getApiKey() { - return apiKey; - } - - public String getSecret() { - return secret; - } - - public boolean isSessionSecret() { - return sessionSecret; - } - - public void beginPermissionsMode( String apiKey ) { - this.permissionsApiKey = apiKey; - } - - public void endPermissionsMode() { - this.permissionsApiKey = null; - } - - public String getSessionKey() { - return sessionKey; - } - - public void setSessionKey( String cacheSessionKey ) { - this.sessionKey = cacheSessionKey; - } - - - public void setServerUrl( String newUrl ) { - String base = newUrl; - if ( base.startsWith( "http" ) ) { - base = base.substring( base.indexOf( "://" ) + 3 ); - } - try { - String url = "http://" + base; - serverUrl = new URL( url ); - } - catch ( MalformedURLException ex ) { - throw BasicClientHelper.runtimeException( ex ); - } - } - - public void setServerUrlHttps( String newUrl ) { - String base = newUrl; - if ( base.startsWith( "https" ) ) { - base = base.substring( base.indexOf( "://" ) + 3 ); - } - try { - String url = "https://" + base; - serverUrlHttps = new URL( url ); - } - catch ( MalformedURLException ex ) { - throw BasicClientHelper.runtimeException( ex ); - } - } - - /** - * Call the specified method, with the given parameters, and return a DOM tree with the results. - * - * @param method - * the fieldName of the method - * @param paramPairs - * a list of arguments to the method - * @throws Exception - * with a description of any errors given to us by the server. - */ - protected String callMethod( String responseFormat, IFacebookMethod method, Pair... paramPairs ) throws FacebookException { - return callMethod( responseFormat, method, Arrays.asList( paramPairs ), null, null ); - } - - /** - * Call the specified method, with the given parameters, and return a DOM tree with the results. - * - * @param method - * the fieldName of the method - * @param paramPairs - * a list of arguments to the method - * @throws Exception - * with a description of any errors given to us by the server. - */ - public String callMethod( String responseFormat, IFacebookMethod method, Collection> paramPairs ) throws FacebookException { - return callMethod( responseFormat, method, paramPairs, null, null ); - } - - protected SortedMap prepareRequestParams( String responseFormat, IFacebookMethod method, Collection> paramPairs ) - throws FacebookException { - SortedMap params = new TreeMap(); - - if ( permissionsApiKey != null ) { - params.put( "call_as_apikey", permissionsApiKey ); - } - - if ( sessionSecret ) { - params.put( "ss", "1" ); - } - - params.put( "method", method.methodName() ); - params.put( "api_key", apiKey ); - params.put( "v", IFacebookRestClient.TARGET_API_VERSION ); - - if ( responseFormat != null ) { - params.put( "format", responseFormat ); - } - - params.put( "call_id", Long.toString( System.currentTimeMillis() ) ); - boolean includeSession = !method.requiresNoSession() && sessionKey != null; - if ( includeSession ) { - params.put( "session_key", sessionKey ); - } - - for ( Pair p : paramPairs ) { - final String key = p.first; - if ( !"sig".equals( "sig" ) ) { - CharSequence oldVal = params.put( key, BasicClientHelper.toString( p.second ) ); - if ( oldVal != null ) { - log.warn( String.format( "For parameter %s, overwrote old value %s with new value %s.", key, oldVal, p.second ) ); - } - } - } - - String signature = FacebookSignatureUtil.generateSignature( params, secret ); - params.put( "sig", signature ); - - return params; - } - - public String callMethod( String responseFormat, IFacebookMethod method, Collection> paramPairs, String fileName, InputStream fileStream ) - throws FacebookException { - SortedMap params = prepareRequestParams( responseFormat, method, paramPairs ); - final boolean fileCall = fileName != null || fileStream != null; - if ( batchMode ) { - if ( fileCall ) { - throw new FacebookException( ErrorCode.GEN_INVALID_PARAMETER, "File upload API calls cannot be batched: " + method.methodName() ); - } - // if we are running in batch mode, don't actually execute the query now, just add it to the list - boolean addToBatch = true; - // FIXME what the heck is going on here?? - if ( method.methodName().equals( FacebookMethod.USERS_GET_LOGGED_IN_USER.methodName() ) ) { - Exception trace = new Exception(); - StackTraceElement[] traceElems = trace.getStackTrace(); - int index = 0; - for ( StackTraceElement elem : traceElems ) { - if ( elem.getMethodName().indexOf( "_" ) != -1 ) { - StackTraceElement caller = traceElems[index + 1]; - final boolean calledFromSelf = caller.getClassName().equals( BasicClient.class.getName() ); - final boolean calledFromAuth = caller.getMethodName().startsWith( "auth_" ); - if ( calledFromSelf && !calledFromAuth ) { - addToBatch = false; - } - break; - } - index++ ; - } - } - if ( addToBatch ) { - queries.add( new BatchQuery( method, params ) ); - // should return null be here or below - // return null; - } - return null; - } - - try { - // FIXME when to use https? - // when called from desktop, some methods require https - boolean doHttps = FacebookMethod.AUTH_GET_SESSION.equals( method ) && "true".equals( params.get( "generate_session_secret" ) ); - URL url = ( doHttps ) ? serverUrlHttps : serverUrl; - if ( fileCall ) { - if ( log.isDebugEnabled() ) { - log.debug( method.methodName() + ": POST-FILE: " + url.toString() + ": " + params ); - } - return communicationStrategy.postRequest( url, params, fileName, fileStream ); - } else { - if ( log.isDebugEnabled() ) { - log.debug( method.methodName() + ": POST: " + url.toString() + ": " + params ); - } - return communicationStrategy.postRequest( url, params ); - } - } - catch ( IOException ex ) { - throw BasicClientHelper.runtimeException( ex ); - } - } - - public void beginBatch() { - batchMode = true; - queries = new ArrayList(); - } - - /** - * Returns a list of String raw responses which will be further broken down by the adapters into the actual individual responses. One string is returned per 20 - * methods in the batch. - */ - public List executeBatch( boolean serial ) throws FacebookException { - batchMode = false; - final List q = queries; - queries = null; - - final int BATCH_LIMIT = 20; - final List result = new ArrayList(); - List buffer = new ArrayList( BATCH_LIMIT ); - while ( !q.isEmpty() ) { - buffer.add( q.remove( 0 ) ); - boolean batchFull = buffer.size() >= BATCH_LIMIT; - if ( batchFull || ( q.isEmpty() ) ) { - List batchRawResponse = batch_run( encodeMethods( buffer ), serial ); - result.addAll( batchRawResponse ); - if ( batchFull ) { - buffer = new ArrayList( BATCH_LIMIT ); - } - } - } - return result; - } - - @SuppressWarnings("unchecked") - protected List batch_run( String methods, boolean serial ) throws FacebookException { - final String call = callMethod( "json", FacebookMethod.BATCH_RUN, Pairs.newPair( "method_feed", methods ), Pairs.newPair10( "serial_only", serial ) ); - try { - JSONArray arr = new JSONArray( call ); - List out = new ArrayList(); - int l = arr.length(); - for ( int i = 0; i < l; i++ ) { - out.add( arr.getString( i ) ); - } - return out; - } - catch ( JSONException ex ) { - throw BasicClientHelper.runtimeException( ex ); - } - } - - protected static String encodeMethods( List queryList ) throws FacebookException { - JSONArray result = new JSONArray(); - for ( BatchQuery query : queryList ) { - if ( query.getMethod().takesFile() ) { - throw new FacebookException( ErrorCode.GEN_INVALID_PARAMETER, "File upload API calls cannot be batched: " + query.getMethod().methodName() ); - } - result.put( BasicClientHelper.delimit( query.getParams().entrySet(), "&", "=", true ) ); - } - return result.toString(); - } - -} diff --git a/java/oldies/BasicClient_1018_1024_v1.java b/java/oldies/BasicClient_1018_1024_v1.java deleted file mode 100644 index a3467fc..0000000 --- a/java/oldies/BasicClient_1018_1024_v1.java +++ /dev/null @@ -1,315 +0,0 @@ -package com.google.code.facebookapi; - -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.SortedMap; -import java.util.TreeMap; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.json.JSONArray; -import org.json.JSONException; - -/** - * Basic client taking care of rest call mechanics (signing, etc) to facebook. Little api knowledge, no response interpretation is planned. - */ -public class BasicClient { - - protected static Log log = LogFactory.getLog( BasicClient.class ); - - protected static final String CRLF = "\r\n"; - protected static final String PREF = "--"; - protected static final int UPLOAD_BUFFER_SIZE = 1024; - - protected URL serverUrl; - protected URL serverUrlHttps; - private CommunicationStrategy communicationStrategy; - - protected final String apiKey; - protected final String secret; - protected boolean sessionSecret; - - protected String sessionKey; - - protected boolean batchMode; - protected List queries; - protected String permissionsApiKey; - - public boolean isBatchMode() { - return batchMode; - } - - protected List getQueries() { - return queries; - } - - protected BasicClient( String apiKey, String secret, boolean sessionSecret ) { - this( apiKey, secret, sessionSecret, null ); - } - - protected BasicClient( String apiKey, String secret, boolean sessionSecret, String sessionKey ) { - this( null, null, apiKey, secret, sessionSecret, sessionKey, new DefaultCommunicationStrategy() ); - } - - protected BasicClient( URL serverUrl, URL serverUrlHttps, String apiKey, String secret, boolean sessionSecret, String sessionKey, - CommunicationStrategy communicationStrategy ) { - this.sessionKey = sessionKey; - this.apiKey = apiKey; - this.secret = secret; - this.sessionSecret = sessionSecret || secret.endsWith( "__" ); - this.serverUrl = ( null != serverUrl ) ? serverUrl : FacebookApiUrls.getDefaultServerUrl(); - this.serverUrlHttps = ( null != serverUrlHttps ) ? serverUrlHttps : FacebookApiUrls.getDefaultHttpsServerUrl(); - - this.communicationStrategy = communicationStrategy; - this.batchMode = false; - this.queries = new ArrayList(); - } - - public String getApiKey() { - return apiKey; - } - - public String getSecret() { - return secret; - } - - public boolean isSessionSecret() { - return sessionSecret; - } - - public void beginPermissionsMode( String apiKey ) { - this.permissionsApiKey = apiKey; - } - - public void endPermissionsMode() { - this.permissionsApiKey = null; - } - - public String getSessionKey() { - return sessionKey; - } - - public void setSessionKey( String cacheSessionKey ) { - this.sessionKey = cacheSessionKey; - } - - - public void setServerUrl( String newUrl ) { - String base = newUrl; - if ( base.startsWith( "http" ) ) { - base = base.substring( base.indexOf( "://" ) + 3 ); - } - try { - String url = "http://" + base; - serverUrl = new URL( url ); - } - catch ( MalformedURLException ex ) { - throw BasicClientHelper.runtimeException( ex ); - } - } - - public void setServerUrlHttps( String newUrl ) { - String base = newUrl; - if ( base.startsWith( "https" ) ) { - base = base.substring( base.indexOf( "://" ) + 3 ); - } - try { - String url = "https://" + base; - serverUrlHttps = new URL( url ); - } - catch ( MalformedURLException ex ) { - throw BasicClientHelper.runtimeException( ex ); - } - } - - /** - * Call the specified method, with the given parameters, and return a DOM tree with the results. - * - * @param method - * the fieldName of the method - * @param paramPairs - * a list of arguments to the method - * @throws Exception - * with a description of any errors given to us by the server. - */ - protected String callMethod( String responseFormat, IFacebookMethod method, Pair... paramPairs ) throws FacebookException { - return callMethod( responseFormat, method, Arrays.asList( paramPairs ), null, null ); - } - - /** - * Call the specified method, with the given parameters, and return a DOM tree with the results. - * - * @param method - * the fieldName of the method - * @param paramPairs - * a list of arguments to the method - * @throws Exception - * with a description of any errors given to us by the server. - */ - public String callMethod( String responseFormat, IFacebookMethod method, Collection> paramPairs ) throws FacebookException { - return callMethod( responseFormat, method, paramPairs, null, null ); - } - - protected SortedMap prepareRequestParams( String responseFormat, IFacebookMethod method, Collection> paramPairs ) - throws FacebookException { - SortedMap params = new TreeMap(); - - for ( Pair p : paramPairs ) { - final String key = p.first; - CharSequence oldVal = params.put( key, BasicClientHelper.toString( p.second ) ); - if ( oldVal != null ) { - log.warn( String.format( "For parameter %s, overwrote old value %s with new value %s.", key, oldVal, p.second ) ); - } - } - - if ( permissionsApiKey != null ) { - params.put( "call_as_apikey", permissionsApiKey ); - } - - params.put( "v", IFacebookRestClient.TARGET_API_VERSION ); - params.put( "call_id", Long.toString( System.currentTimeMillis() ) ); - params.put( "method", method.methodName() ); - if ( responseFormat != null ) { - params.put( "format", responseFormat ); - } - - params.put( "api_key", apiKey ); - boolean includeSession = !method.requiresNoSession() && sessionKey != null; - if ( includeSession ) { - params.put( "session_key", sessionKey ); - } - - params.remove( "sig" ); - if ( sessionSecret ) { - params.put( "ss", "1" ); - } - String signature = FacebookSignatureUtil.generateSignature( params, secret ); - params.put( "sig", signature ); - - return params; - } - - public String callMethod( String responseFormat, IFacebookMethod method, Collection> paramPairs, String fileName, InputStream fileStream ) - throws FacebookException { - SortedMap params = prepareRequestParams( responseFormat, method, paramPairs ); - final boolean fileCall = fileName != null || fileStream != null; - if ( batchMode ) { - if ( fileCall ) { - throw new FacebookException( ErrorCode.GEN_INVALID_PARAMETER, "File upload API calls cannot be batched: " + method.methodName() ); - } - // if we are running in batch mode, don't actually execute the query now, just add it to the list - boolean addToBatch = true; - // FIXME what the heck is going on here?? - if ( method.methodName().equals( FacebookMethod.USERS_GET_LOGGED_IN_USER.methodName() ) ) { - Exception trace = new Exception(); - StackTraceElement[] traceElems = trace.getStackTrace(); - int index = 0; - for ( StackTraceElement elem : traceElems ) { - if ( elem.getMethodName().indexOf( "_" ) != -1 ) { - StackTraceElement caller = traceElems[index + 1]; - final boolean calledFromSelf = caller.getClassName().equals( BasicClient.class.getName() ); - final boolean calledFromAuth = caller.getMethodName().startsWith( "auth_" ); - if ( calledFromSelf && !calledFromAuth ) { - addToBatch = false; - } - break; - } - index++ ; - } - } - if ( addToBatch ) { - queries.add( new BatchQuery( method, params ) ); - // should return null be here or below - // return null; - } - return null; - } - - try { - // FIXME when to use https? - // when called from desktop, some methods require https - boolean doHttps = FacebookMethod.AUTH_GET_SESSION.equals( method ) && "true".equals( params.get( "generate_session_secret" ) ); - URL url = ( doHttps ) ? serverUrlHttps : serverUrl; - if ( fileCall ) { - if ( log.isDebugEnabled() ) { - log.debug( method.methodName() + ": POST-FILE: " + url.toString() + ": " + params ); - } - return communicationStrategy.postRequest( url, params, fileName, fileStream ); - } else { - if ( log.isDebugEnabled() ) { - log.debug( method.methodName() + ": POST: " + url.toString() + ": " + params ); - } - return communicationStrategy.postRequest( url, params ); - } - } - catch ( IOException ex ) { - throw BasicClientHelper.runtimeException( ex ); - } - } - - public void beginBatch() { - batchMode = true; - queries = new ArrayList(); - } - - /** - * Returns a list of String raw responses which will be further broken down by the adapters into the actual individual responses. One string is returned per 20 - * methods in the batch. - */ - public List executeBatch( boolean serial ) throws FacebookException { - batchMode = false; - final List q = queries; - queries = null; - - final int BATCH_LIMIT = 20; - final List result = new ArrayList(); - List buffer = new ArrayList( BATCH_LIMIT ); - while ( !q.isEmpty() ) { - buffer.add( q.remove( 0 ) ); - boolean batchFull = buffer.size() >= BATCH_LIMIT; - if ( batchFull || ( q.isEmpty() ) ) { - List batchRawResponse = batch_run( encodeMethods( buffer ), serial ); - result.addAll( batchRawResponse ); - if ( batchFull ) { - buffer = new ArrayList( BATCH_LIMIT ); - } - } - } - return result; - } - - @SuppressWarnings("unchecked") - protected List batch_run( String methods, boolean serial ) throws FacebookException { - final String call = callMethod( "json", FacebookMethod.BATCH_RUN, Pairs.newPair( "method_feed", methods ), Pairs.newPair10( "serial_only", serial ) ); - try { - JSONArray arr = new JSONArray( call ); - List out = new ArrayList(); - int l = arr.length(); - for ( int i = 0; i < l; i++ ) { - out.add( arr.getString( i ) ); - } - return out; - } - catch ( JSONException ex ) { - throw BasicClientHelper.runtimeException( ex ); - } - } - - protected static String encodeMethods( List queryList ) throws FacebookException { - JSONArray result = new JSONArray(); - for ( BatchQuery query : queryList ) { - if ( query.getMethod().takesFile() ) { - throw new FacebookException( ErrorCode.GEN_INVALID_PARAMETER, "File upload API calls cannot be batched: " + query.getMethod().methodName() ); - } - result.put( BasicClientHelper.delimit( query.getParams().entrySet(), "&", "=", true ) ); - } - return result.toString(); - } - -} diff --git a/java/oldies/EPerm_v0.java b/java/oldies/EPerm_v0.java deleted file mode 100644 index 19d2510..0000000 --- a/java/oldies/EPerm_v0.java +++ /dev/null @@ -1,9 +0,0 @@ -enum Test { - - T1, - - T2, - - T3; - -} diff --git a/java/oldies/EPerm_v1.java b/java/oldies/EPerm_v1.java deleted file mode 100644 index 0c49238..0000000 --- a/java/oldies/EPerm_v1.java +++ /dev/null @@ -1,9 +0,0 @@ -enum Test { - - T3, - - T2, - - T1; - -} diff --git a/java/oldies/Inventory_287c56f97631_5ff114b22264_v0.java b/java/oldies/Inventory_287c56f97631_5ff114b22264_v0.java deleted file mode 100644 index 2db59c4..0000000 --- a/java/oldies/Inventory_287c56f97631_5ff114b22264_v0.java +++ /dev/null @@ -1,728 +0,0 @@ -package org.rsbuddy.tabs; - -import com.rsbuddy.script.methods.Game; -import com.rsbuddy.script.methods.Menu; -import com.rsbuddy.script.methods.Mouse; -import com.rsbuddy.script.methods.Widgets; -import com.rsbuddy.script.task.Task; -import com.rsbuddy.script.util.Random; -import com.rsbuddy.script.wrappers.*; -import com.rsbuddy.script.wrappers.Component; - -import java.awt.*; -import java.util.LinkedList; -import java.util.List; - -/** - * Inventory tab related operations. - */ -public class Inventory { - - public static final int WIDGET = 679; - public static final int WIDGET_PRICE_CHECK = 204; - public static final int WIDGET_EQUIPMENT_BONUSES = 670; - public static final int WIDGET_BANK = 763; - public static final int WIDGET_EXCHANGE = 644; - public static final int WIDGET_SHOP = 621; - public static final int WIDGET_DUNGEONEERING_SHOP = 957; - public static final int WIDGET_BEAST_OF_BURDEN_STORAGE = 665; - - public static final int[] ALT_WIDGETS = {WIDGET_PRICE_CHECK, - WIDGET_EQUIPMENT_BONUSES, WIDGET_BANK, WIDGET_EXCHANGE, - WIDGET_SHOP, WIDGET_DUNGEONEERING_SHOP, - WIDGET_BEAST_OF_BURDEN_STORAGE}; - - /** - * Clicks on the selected inventory item. - * - * @param leftClick true to left-click otherwise; false to - * right-click - * @return true if the inventory item was clicked on; otherwise - * false - */ - public static boolean clickSelectedItem(boolean leftClick) { - Item item = getSelectedItem(); - return item != null && item.click(leftClick); - } - - /** - * Left-clicks on the selected inventory item. - * - * @return true if the selected inventory item was clicked on; - * otherwise false - * @see #clickSelectedItem(boolean) - */ - public static boolean clickSelectedItem() { - return clickSelectedItem(true); - } - - /** - * Checks whether the inventory contains the provided item id. - * - * @param itemId the item id to look for - * @return true if the inventory contains the provided item id; - * otherwise false - * @see #containsOneOf(int...) - * @see #containsAll(int...) - */ - public static boolean contains(int itemId) { - return getItem(itemId) != null; - } - - /** - * Checks whether the inventory contains all of the provided item ids. - * - * @param itemIds the item ids to look for - * @return true if the inventory contains all of the provided item - * ids; otherwise false - * @see #containsOneOf(int...) - */ - public static boolean containsAll(int... itemIds) { - for (int itemId : itemIds) { - if (getItem(itemId) == null) - return false; - } - return true; - } - - /** - * Checks whether the inventory contains one of the provided item ids. - * - * @param itemIds the item ids to check for - * @return true if the inventory contains one of the provided - * items; otherwise false - * @see #containsAll(int...) - */ - public static boolean containsOneOf(int... itemIds) { - return getItems(itemIds).length > 0; - } - - /** - * Drags an item to the specified slot. Slot must be in the range of 0 and - * 27. - * - * @param itemId the item id - * @param slot the slot - * @return true if dragged; otherwise false - */ - public static boolean drag(int itemId, int slot) { - return drag(getItem(itemId), slot); - } - - /** - * Drags an item to the specified inventory slot, which must be in the range - * of 0 and 27. - * - * @param item the inventory item - * @param invSlot the inventory slot - * @return true if dragged; otherwise false - */ - public static boolean drag(Item item, int invSlot) { - if (item != null) { - if (invSlot >= 0 && invSlot <= 27) { - Component slot = getComponent().getComponents()[invSlot]; - if (slot != null) { - Rectangle slotRectangle = slot.getBoundingRect(); - Rectangle itemRectangle = item.getComponent() - .getContentRect(); - if (slotRectangle.contains(itemRectangle)) { - return true; - } - Mouse.move((int) itemRectangle.getCenterX(), - (int) itemRectangle.getCenterY(), 5, 5); - Mouse.drag((int) slotRectangle.getCenterX(), - (int) slotRectangle.getCenterY()); - return true; - } - } - } - return false; - } - - /** - * Drags an item to the specified slot. Slot must be in the range of 1 and - * 28. - * - * @param itemId the item id - * @param slot the slot - * @return true if dragged; otherwise false - */ - @Deprecated - public static boolean dragItem(int itemId, int slot) { - return dragItem(getItem(itemId), slot); - } - - /** - * Drags an item to the specified inventory slot, which must be in the range - * of 1 and 28. - * - * @param item the inventory item - * @param invSlot the inventory slot - * @return true if dragged; otherwise false - */ - @Deprecated - public static boolean dragItem(Item item, int invSlot) { - if (item != null) { - if (invSlot >= 1 && invSlot <= 28) { - Component slot = getComponent().getComponents()[invSlot - 1]; - if (slot != null) { - Rectangle slotRectangle = slot.getBoundingRect(); - Rectangle itemRectangle = item.getComponent() - .getContentRect(); - if (slotRectangle.contains(itemRectangle)) { - return true; - } - Mouse.move((int) itemRectangle.getCenterX(), - (int) itemRectangle.getCenterY(), 5, 5); - Mouse.drag((int) slotRectangle.getCenterX(), - (int) slotRectangle.getCenterY()); - return true; - } - } - } - return false; - } - - /** - * Drops all inventory items excepting those matching with any of the - * provided ids. - * - * @param leftToRight true to span row by row (horizontal precedence); - * false to span column by column (vertical precedence). - * @param itemIds the item ids to exclude - */ - public static void dropAllExcept(boolean leftToRight, int... itemIds) { - if (getCountExcept(itemIds) != 0) { - if (!leftToRight) { - for (int c = 0; c < 4; c++) { - for (int r = 0; r < 7; r++) { - boolean found = false; - for (int i = 0; i < itemIds.length && !found; ++i) { - found = itemIds[i] == getAllItems()[c + r * 4] - .getId(); - } - if (!found) { - dropItem(c, r); - } - } - } - } else { - for (int r = 0; r < 7; r++) { - for (int c = 0; c < 4; c++) { - boolean found = false; - for (int i = 0; i < itemIds.length && !found; ++i) { - found = itemIds[i] == getAllItems()[c + r * 4] - .getId(); - } - if (!found) { - dropItem(c, r); - } - } - } - } - Task.sleep(Random.nextInt(500, 800)); - } - } - - /** - * Drops all inventory items vertically (going down the inventory) excepting - * those matching with any of the provided ids. - * - * @param itemIds the item ids to exclude - * @see #dropAllExcept(boolean, int...) - */ - public static void dropAllExcept(int... itemIds) { - dropAllExcept(false, itemIds); - } - - /** - * Drops the inventory item of the specified column and row. - * - * @param col the column the inventory item is in - * @param row the row the inventory item is in - */ - public static void dropItem(int col, int row) { - if (col < 0 || col > 3 || row < 0 || row > 6) - return; - if (getAllItems()[col + row * 4].getId() == -1) - return; - Point p; - p = Mouse.getLocation(); - if (p.x < 563 + col * 42 || p.x >= 563 + col * 42 + 32 - || p.y < 213 + row * 36 || p.y >= 213 + row * 36 + 32) { - Mouse.move( - getComponent().getComponents()[row * 4 + col].getCenter(), - 10, 10); - } - Mouse.click(false); - Task.sleep(Random.nextInt(10, 25)); - Menu.click("Drop"); - Task.sleep(Random.nextInt(25, 50)); - } - - /** - * Gets all the inventory items. If the tab is not currently open, it will - * not open it and will return the last known array of items. - * - * @return an array instance of Item - */ - public static Item[] getCachedItems() { - Component invIface = Widgets.getComponent(WIDGET, 0); - if (invIface != null) { - Component[] components = invIface.getComponents(); - if (components.length > 0) { - List items = new LinkedList(); - for (int i = 0; i < 28; ++i) { - if (components[i].getItemId() != -1) { - items.add(new Item(components[i])); - } - } - return items.toArray(new Item[items.size()]); - } - } - return new Item[0]; - } - - /** - * Gets the inventory component. - * - * @return the inventory component - */ - public static Component getComponent() { - for (int widget : ALT_WIDGETS) { - Component inventory = Widgets.getComponent(widget, 0); - if (inventory != null && inventory.getAbsLocation().x > 50) { - return inventory; - } - } - - // Tab has to be open for us to get its contents - openTab(); - - return Widgets.getComponent(WIDGET, 0); - } - - /** - * Gets the count of all inventory items ignoring stack sizes. - * - * @return the count - * @see #getCount(boolean) - */ - public static int getCount() { - return getCount(false); - } - - /** - * Gets the count of all inventory items. - * - * @param includeStacks false if stacked items should be counted as single - * items; otherwise true - * @return the count - */ - public static int getCount(boolean includeStacks) { - int count = 0; - Item[] items = getItems(); - for (Item item : items) { - if (item == null) - continue; - int itemId = item.getId(); - if (itemId != -1) { - count += includeStacks ? item.getStackSize() : 1; - } - } - return count; - } - - /** - * Gets the count of all the inventory items matching with any of the - * provided ids ignoring stack sizes. - * - * @param itemIds the item ids to include - * @return the count - * @see #getCount(boolean, int...) - */ - public static int getCount(int... itemIds) { - return getCount(false, itemIds); - } - - /** - * Gets the count of all the inventory items matching with any of the - * provided ids. - * - * @param includeStacks true to count the stack sizes of each item; otherwise - * false - * @param itemIds the item ids to include - * @return the count - */ - public static int getCount(boolean includeStacks, int... itemIds) { - int count = 0; - Item[] items = getItems(itemIds); - for (Item item : items) { - if (item == null) - continue; - int itemId = item.getId(); - if (itemId != -1) { - count += includeStacks ? item.getStackSize() : 1; - } - } - return count; - } - - /** - * Gets the count of all the inventory items excluding the provided ids - * ignoring stack sizes. - * - * @param ids the ids to exclude - * @return the count - * @see #getCountExcept(boolean, int...) - */ - public static int getCountExcept(int... ids) { - return getCountExcept(false, ids); - } - - /** - * Gets the count of all the inventory items excluding any of the provided - * ids. - * - * @param includeStacks true to count the stack sizes of each item; otherwise - * false - * @param ids the ids to exclude - * @return the count - */ - public static int getCountExcept(boolean includeStacks, int... ids) { - int count = 0; - Item[] items = getItems(); - outer: - for (Item item : items) { - if (item == null) - continue; - int itemId = item.getId(); - for (int id : ids) { - if (itemId == id) - continue outer; - } - count += includeStacks ? item.getStackSize() : 1; - } - return count; - } - - /** - * Gets the first inventory item matching with any of the provided ids. - * - * @param ids the ids to look for - * @return the first inventory item matching with any of the provided ids; - * otherwise null - */ - public static Item getItem(int... ids) { - Item[] items = getItems(ids); - for (Item item : items) { - if (item != null) { - return item; - } - } - return null; - } - - /** - * Gets the inventory item at the specified index. - * - * @param index the index of the inventory item - * @return the Item; otherwise null if invalid - */ - public static Item getItemAt(int index) { - Component comp = getComponent().getComponent(index); - return 0 <= index && index < 28 && comp != null && comp.getItemId() != -1 ? new Item(comp) : null; - } - - /** - * Gets all the valid inventory items. - * - * @return an array instance of Item of the current valid - * inventory items - */ - public static Item[] getItems() { - Component invIface = getComponent(); - if (invIface != null) { - Component[] comps = invIface.getComponents(); - if (comps.length > 27) { - List items = new LinkedList(); - for (int i = 0; i < 28; ++i) { - if (comps[i].getItemId() != -1) { - items.add(new Item(comps[i])); - } - } - return items.toArray(new Item[items.size()]); - } - } - return new Item[0]; - } - - /** - * Gets all the inventory items (including empty ones). - * - * @return an array instance of Item of the current inventory - * items - */ - public static Item[] getAllItems() { - Item[] items = new Item[28]; - Component invIface = getComponent(); - if (invIface != null) { - Component[] comps = invIface.getComponents(); - if (comps.length > 27) { - for (int i = 0; i < 28; ++i) { - items[i] = new Item(comps[i]); - } - } - } - return items; - } - - /** - * Gets all the inventory items matching with any of the provided ids. - * - * @param ids the item ids - * @return an array instance of Item - */ - public static Item[] getItems(int... ids) { - List items = new LinkedList(); - for (Item item : getItems()) { - if (item == null) - continue; - int itemId = item.getId(); - for (int id : ids) { - if (itemId == id) { - items.add(item); - break; - } - } - } - return items.toArray(new Item[items.size()]); - } - - /** - * Gets the first id of an inventory item with the given name. - * - * @param name the name of the inventory item to look for - * @return the id of the inventory item; otherwise -1 - */ - public static int getItemId(String name) { - Item[] items = getItems(); - for (Item item : items) { - if (item == null) { - continue; - } - String itemName = item.getComponent().getItemName().toLowerCase(); - if (itemName.contains(name.toLowerCase())) { - return item.getId(); - } - } - return -1; - } - - /** - * Gets the selected inventory item. - * - * @return the selected inventory item; otherwise null if none - * is selected - */ - public static Item getSelectedItem() { - int index = getSelectedItemIndex(); - return index == -1 ? null : getItemAt(index); - } - - /** - * Gets the selected inventory item's index. - * - * @return the index of the current selected inventory item; otherwise -1 if - * none is selected - */ - public static int getSelectedItemIndex() { - Item[] items = getItems(); - for (Item item : items) { - if (item == null) { - continue; - } - Component comp = item.getComponent(); - if (comp.getBorderThickness() == 2) { - return comp.getIndex(); - } - } - return -1; - } - - /** - * Returns the index of the first occurrence of an item in the inventory - * matching with the provided id. - * - * @param id the item id - * @return the index; otherwise -1. - */ - public static int indexOf(int id) { - Item[] items = getItems(); - for (int i = 0; i < items.length; i++) { - if (id == items[i].getId()) { - return i; - } - } - return -1; - } - - /** - * Returns the index of the first occurrence of an item in the inventory - * matching with the provided name. Case-insensitive. - * - * @param name the name of the item - * @return the index; otherwise -1. - */ - public static int indexOf(String name) { - if (name != null && !name.isEmpty()) { - Item[] items = getItems(); - for (int i = 0; i < items.length; i++) { - if (items[i].getName().equalsIgnoreCase(name)) - return i; - } - } - return -1; - } - - /** - * Checks whether the inventory is full. - * - * @return true if the inventory contains 28 items; otherwise - * false - */ - public static boolean isFull() { - return getCount() == 28; - } - - /** - * Checks whether an inventory item is selected. - * - * @return true if an inventory item is selected; otherwise - * false - */ - public static boolean isItemSelected() { - return getSelectedItemIndex() != -1; - } - - /** - * Opens the inventory tab if not already opened. - */ - public static void openTab() { - int tabInventory = Game.TAB_INVENTORY; - if (Game.getCurrentTab() != tabInventory) { - Game.openTab(tabInventory); - } - } - - /** - * Uses two inventory items together. - * - * @param item the inventory item to use on another inventory item - * @param target the other inventory item to be used on - * @return true if the "Use" action had been used on both inventory - * items; otherwise false - */ - public static boolean useItem(Item item, Item target) { - return item != null && target != null && useItem(item, (Object) target); - } - - /** - * Uses an item on a game object. - * - * @param item the item to use - * @param target the game object to be used on by the item - * @return true if the "Use" action had been used on both the - * inventory item and the game object; otherwise false - */ - public static boolean useItem(Item item, GameObject target) { - if (item != null && target != null) { - for (int i = 0, r = Random.nextInt(5, 8); i < r; i++) { - if (!isItemSelected()) { - if (item.interact("Use")) { - for (int j = 0; j < 10 && !isItemSelected(); j++) { - Task.sleep(100, 200); - } - } else { - return false; - } - } - // just make sure in case something bad happened - if (isItemSelected()) { - final String itemName = item.getName(); - final ObjectDefinition targetDef = target.getDef(); - final Model targetModel = target.getModel(); - if (targetDef != null && itemName != null && targetModel != null) { - final String targetName = targetDef.getName(); - Mouse.move(targetModel.getNextPoint()); - final String action = "Use " + itemName.replace("", "") + " -> " + targetName.replace("", ""); - for (int j = 0, s = Random.nextInt(5, 8); j < s; j++) { - if (Menu.contains(action) && Menu.click(action)) { - return true; - } else { - Mouse.move(targetModel.getNextPoint()); - } - } - } - // kay, since that failed, let's try just use - if (target.interact("Use")) { - return true; - } - } - } - } - return false; - } - - /** - * Uses an inventory item on either another inventory item or a game object. - * - * @param item the inventory item to use - * @param target the inventory item or the game object to be used on by the - * inventory item - * @return true if the "Use" action had been used on both the - * inventory item and the game object/other inventory item; - * otherwise false - */ - private static boolean useItem(Item item, Object target) { - if (isItemSelected()) { - Item selectedItem = getSelectedItem(); - int selectedItemId = selectedItem.getId(); - if (item.getId() != selectedItemId) { - if (!selectedItem.interact("Cancel")) { - return false; - } - } else if (target instanceof Item) { - Item t = (Item) target; - if (selectedItemId != t.getId() - && selectedItemId != item.getId()) { - if (!selectedItem.interact("Cancel")) { - return false; - } - } - } - } - for (int i = 0, r = Random.nextInt(5, 8); i < r; i++) { - if (isItemSelected()) { - boolean success = false; - for (int j = 0, k = Random.nextInt(5, 8); j < k; j++) { - try { - Item t = (Item) target; - if (t.interact("Use")) { - success = true; - break; - } - Task.sleep(150, 300); - } catch (final ClassCastException e) { - return false; - } - } - return success; - } - item.interact("Use"); - Task.sleep(150, 300); - } - return false; - } - -} diff --git a/java/oldies/Inventory_287c56f97631_5ff114b22264_v1.java b/java/oldies/Inventory_287c56f97631_5ff114b22264_v1.java deleted file mode 100644 index bea553a..0000000 --- a/java/oldies/Inventory_287c56f97631_5ff114b22264_v1.java +++ /dev/null @@ -1,773 +0,0 @@ -package org.rsbuddy.tabs; - -import com.rsbuddy.script.methods.Game; -import com.rsbuddy.script.methods.Menu; -import com.rsbuddy.script.methods.Mouse; -import com.rsbuddy.script.methods.Widgets; -import com.rsbuddy.script.task.Task; -import com.rsbuddy.script.util.Filter; -import com.rsbuddy.script.util.Random; -import com.rsbuddy.script.wrappers.*; -import com.rsbuddy.script.wrappers.Component; - -import java.awt.*; -import java.util.LinkedList; -import java.util.List; - -/** - * Inventory tab related operations. - */ -public class Inventory { - - public static final int WIDGET = 679; - public static final int WIDGET_PRICE_CHECK = 204; - public static final int WIDGET_EQUIPMENT_BONUSES = 670; - public static final int WIDGET_BANK = 763; - public static final int WIDGET_EXCHANGE = 644; - public static final int WIDGET_SHOP = 621; - public static final int WIDGET_DUNGEONEERING_SHOP = 957; - public static final int WIDGET_BEAST_OF_BURDEN_STORAGE = 665; - - public static final int[] ALT_WIDGETS = {WIDGET_PRICE_CHECK, - WIDGET_EQUIPMENT_BONUSES, WIDGET_BANK, WIDGET_EXCHANGE, - WIDGET_SHOP, WIDGET_DUNGEONEERING_SHOP, - WIDGET_BEAST_OF_BURDEN_STORAGE}; - - /** - * Clicks on the selected inventory item. - * - * @param leftClick true to left-click otherwise; false to - * right-click - * @return true if the inventory item was clicked on; otherwise - * false - */ - public static boolean clickSelectedItem(boolean leftClick) { - Item item = getSelectedItem(); - return item != null && item.click(leftClick); - } - - /** - * Left-clicks on the selected inventory item. - * - * @return true if the selected inventory item was clicked on; - * otherwise false - * @see #clickSelectedItem(boolean) - */ - public static boolean clickSelectedItem() { - return clickSelectedItem(true); - } - - /** - * Checks whether the inventory contains the provided item id. - * - * @param itemId the item id to look for - * @return true if the inventory contains the provided item id; - * otherwise false - * @see #containsOneOf(int...) - * @see #containsAll(int...) - */ - public static boolean contains(int itemId) { - return getItem(itemId) != null; - } - - /** - * Checks whether the inventory contains all of the provided item ids. - * - * @param itemIds the item ids to look for - * @return true if the inventory contains all of the provided item - * ids; otherwise false - * @see #containsOneOf(int...) - */ - public static boolean containsAll(int... itemIds) { - for (int itemId : itemIds) { - if (getItem(itemId) == null) - return false; - } - return true; - } - - /** - * Checks whether the inventory contains one of the provided item ids. - * - * @param itemIds the item ids to check for - * @return true if the inventory contains one of the provided - * items; otherwise false - * @see #containsAll(int...) - */ - public static boolean containsOneOf(int... itemIds) { - return getItems(itemIds).length > 0; - } - - /** - * Drags an item to the specified slot. Slot must be in the range of 0 and - * 27. - * - * @param itemId the item id - * @param slot the slot - * @return true if dragged; otherwise false - */ - public static boolean drag(int itemId, int slot) { - return drag(getItem(itemId), slot); - } - - /** - * Drags an item to the specified inventory slot, which must be in the range - * of 0 and 27. - * - * @param item the inventory item - * @param invSlot the inventory slot - * @return true if dragged; otherwise false - */ - public static boolean drag(Item item, int invSlot) { - if (item != null) { - if (invSlot >= 0 && invSlot <= 27) { - Component slot = getComponent().getComponents()[invSlot]; - if (slot != null) { - Rectangle slotRectangle = slot.getBoundingRect(); - Rectangle itemRectangle = item.getComponent() - .getContentRect(); - if (slotRectangle.contains(itemRectangle)) { - return true; - } - Mouse.move((int) itemRectangle.getCenterX(), - (int) itemRectangle.getCenterY(), 5, 5); - Mouse.drag((int) slotRectangle.getCenterX(), - (int) slotRectangle.getCenterY()); - return true; - } - } - } - return false; - } - - /** - * Drags an item to the specified slot. Slot must be in the range of 1 and - * 28. - * - * @param itemId the item id - * @param slot the slot - * @return true if dragged; otherwise false - */ - @Deprecated - public static boolean dragItem(int itemId, int slot) { - return dragItem(getItem(itemId), slot); - } - - /** - * Drags an item to the specified inventory slot, which must be in the range - * of 1 and 28. - * - * @param item the inventory item - * @param invSlot the inventory slot - * @return true if dragged; otherwise false - */ - @Deprecated - public static boolean dragItem(Item item, int invSlot) { - if (item != null) { - if (invSlot >= 1 && invSlot <= 28) { - Component slot = getComponent().getComponents()[invSlot - 1]; - if (slot != null) { - Rectangle slotRectangle = slot.getBoundingRect(); - Rectangle itemRectangle = item.getComponent() - .getContentRect(); - if (slotRectangle.contains(itemRectangle)) { - return true; - } - Mouse.move((int) itemRectangle.getCenterX(), - (int) itemRectangle.getCenterY(), 5, 5); - Mouse.drag((int) slotRectangle.getCenterX(), - (int) slotRectangle.getCenterY()); - return true; - } - } - } - return false; - } - - /** - * Drops all inventory items excepting those matching with any of the - * provided ids. - * - * @param leftToRight true to span row by row (horizontal precedence); - * false to span column by column (vertical precedence). - * @param itemIds the item ids to exclude - */ - public static void dropAllExcept(boolean leftToRight, int... itemIds) { - if (getCountExcept(itemIds) != 0) { - if (!leftToRight) { - for (int c = 0; c < 4; c++) { - for (int r = 0; r < 7; r++) { - boolean found = false; - for (int i = 0; i < itemIds.length && !found; ++i) { - found = itemIds[i] == getAllItems()[c + r * 4] - .getId(); - } - if (!found) { - dropItem(c, r); - } - } - } - } else { - for (int r = 0; r < 7; r++) { - for (int c = 0; c < 4; c++) { - boolean found = false; - for (int i = 0; i < itemIds.length && !found; ++i) { - found = itemIds[i] == getAllItems()[c + r * 4] - .getId(); - } - if (!found) { - dropItem(c, r); - } - } - } - } - Task.sleep(Random.nextInt(500, 800)); - } - } - - /** - * Drops all inventory items vertically (going down the inventory) excepting - * those matching with any of the provided ids. - * - * @param itemIds the item ids to exclude - * @see #dropAllExcept(boolean, int...) - */ - public static void dropAllExcept(int... itemIds) { - dropAllExcept(false, itemIds); - } - - /** - * Drops the inventory item of the specified column and row. - * - * @param col the column the inventory item is in - * @param row the row the inventory item is in - */ - public static void dropItem(int col, int row) { - if (col < 0 || col > 3 || row < 0 || row > 6) - return; - if (getAllItems()[col + row * 4].getId() == -1) - return; - Point p; - p = Mouse.getLocation(); - if (p.x < 563 + col * 42 || p.x >= 563 + col * 42 + 32 - || p.y < 213 + row * 36 || p.y >= 213 + row * 36 + 32) { - Mouse.move( - getComponent().getComponents()[row * 4 + col].getCenter(), - 10, 10); - } - Mouse.click(false); - Task.sleep(Random.nextInt(10, 25)); - Menu.click("Drop"); - Task.sleep(Random.nextInt(25, 50)); - } - - /** - * Gets all the inventory items. If the tab is not currently open, it will - * not open it and will return the last known array of items. - * - * @return an array instance of Item - */ - public static Item[] getCachedItems() { - Component invIface = Widgets.getComponent(WIDGET, 0); - if (invIface != null) { - Component[] components = invIface.getComponents(); - if (components.length > 0) { - List items = new LinkedList(); - for (int i = 0; i < 28; ++i) { - if (components[i].getItemId() != -1) { - items.add(new Item(components[i])); - } - } - return items.toArray(new Item[items.size()]); - } - } - return new Item[0]; - } - - /** - * Gets the inventory component. - * - * @return the inventory component - */ - public static Component getComponent() { - for (int widget : ALT_WIDGETS) { - Component inventory = Widgets.getComponent(widget, 0); - if (inventory != null && inventory.getAbsLocation().x > 50) { - return inventory; - } - } - - // Tab has to be open for us to get its contents - openTab(); - - return Widgets.getComponent(WIDGET, 0); - } - - /** - * Gets the count of all inventory items ignoring stack sizes. - * - * @return the count - * @see #getCount(boolean) - */ - public static int getCount() { - return getCount(false); - } - - /** - * Gets the count of all inventory items. - * - * @param includeStacks false if stacked items should be counted as single - * items; otherwise true - * @return the count - */ - public static int getCount(boolean includeStacks) { - int count = 0; - Item[] items = getItems(); - for (Item item : items) { - if (item == null) - continue; - int itemId = item.getId(); - if (itemId != -1) { - count += includeStacks ? item.getStackSize() : 1; - } - } - return count; - } - - /** - * Gets the count of all the inventory items matching with any of the - * provided ids ignoring stack sizes. - * - * @param itemIds the item ids to include - * @return the count - * @see #getCount(boolean, int...) - */ - public static int getCount(int... itemIds) { - return getCount(false, itemIds); - } - - /** - * Gets the count of all the inventory items matching with any of the - * provided ids. - * - * @param includeStacks true to count the stack sizes of each item; otherwise - * false - * @param itemIds the item ids to include - * @return the count - */ - public static int getCount(boolean includeStacks, int... itemIds) { - int count = 0; - Item[] items = getItems(itemIds); - for (Item item : items) { - if (item == null) - continue; - int itemId = item.getId(); - if (itemId != -1) { - count += includeStacks ? item.getStackSize() : 1; - } - } - return count; - } - - /** - * Gets the count of all the inventory items excluding the provided ids - * ignoring stack sizes. - * - * @param ids the ids to exclude - * @return the count - * @see #getCountExcept(boolean, int...) - */ - public static int getCountExcept(int... ids) { - return getCountExcept(false, ids); - } - - /** - * Gets the count of all the inventory items excluding any of the provided - * ids. - * - * @param includeStacks true to count the stack sizes of each item; otherwise - * false - * @param ids the ids to exclude - * @return the count - */ - public static int getCountExcept(boolean includeStacks, int... ids) { - int count = 0; - Item[] items = getItems(); - outer: - for (Item item : items) { - if (item == null) - continue; - int itemId = item.getId(); - for (int id : ids) { - if (itemId == id) - continue outer; - } - count += includeStacks ? item.getStackSize() : 1; - } - return count; - } - - /** - * Gets the first inventory item matching with any of the provided ids. - * - * @param ids the ids to look for - * @return the first inventory item matching with any of the provided ids; - * otherwise null - */ - public static Item getItem(int... ids) { - Item[] items = getItems(ids); - if (items.length > 0) { - return items[0]; - } else { - return null; - } - } - - /** - * Gets the first inventory item matching with any of the provided ids. - * - * @param filter the filter to use - * @return the first inventory item matching with any of the provided ids; - * otherwise null - */ - public static Item getItem(final Filter filter) { - Item[] items = getItems(filter); - if (items.length > 0) { - return items[0]; - } else { - return null; - } - } - - /** - * Gets the inventory item at the specified index. - * - * @param index the index of the inventory item - * @return the Item; otherwise null if invalid - */ - public static Item getItemAt(int index) { - Component comp = getComponent().getComponent(index); - return 0 <= index && index < 28 && comp != null && comp.getItemId() != -1 ? new Item(comp) : null; - } - - /** - * Gets all the valid inventory items. - * - * @return an array instance of Item of the current valid - * inventory items - */ - public static Item[] getItems() { - Component invIface = getComponent(); - if (invIface != null) { - Component[] comps = invIface.getComponents(); - if (comps.length > 27) { - List items = new LinkedList(); - for (int i = 0; i < 28; ++i) { - if (comps[i].getItemId() != -1) { - items.add(new Item(comps[i])); - } - } - return items.toArray(new Item[items.size()]); - } - } - return new Item[0]; - } - - /** - * Gets all the inventory items (including empty ones). - * - * @return an array instance of Item of the current inventory - * items - */ - public static Item[] getAllItems() { - Item[] items = new Item[28]; - Component invIface = getComponent(); - if (invIface != null) { - Component[] comps = invIface.getComponents(); - if (comps.length > 27) { - for (int i = 0; i < 28; ++i) { - items[i] = new Item(comps[i]); - } - } - } - return items; - } - - /** - * Gets all the inventory items matching with any of the provided ids. - * - * @param filter the Item Filter to use - * @return an array instance of Item - */ - public static Item[] getItems(final Filter filter) { - List items = new LinkedList(); - for (Item item : getItems()) { - if (item == null) - continue; - if (filter.accept(item)) { - items.add(item); - } - } - return items.toArray(new Item[items.size()]); - } - - /** - * Gets all the inventory items matching with any of the provided ids. - * - * @param ids the item ids - * @return an array instance of Item - */ - public static Item[] getItems(final int... ids) { - return getItems(new Filter() { - public boolean accept(final Item item) { - for (int id : ids) { - if (item.getId() == id) { - return true; - } - } - return false; - } - }); - } - - /** - * Gets all the inventory items matching with any of the provided names. - * - * @param names the item names - * @return an array instance of Item - */ - public static Item[] getItems(final String... names) { - return getItems(new Filter() { - public boolean accept(final Item item) { - for (String name : names) { - if (name != null && item.getName() != null && item.getName().contains(name)) { - return true; - } - } - return false; - } - }); - } - - /** - * Gets the first id of an inventory item with the given name. - * - * @param name the name of the inventory item to look for - * @return the id of the inventory item; otherwise -1 - */ - public static int getItemId(String name) { - Item[] items = getItems(name); - if (items.length > 0) { - return items[0].getId(); - } else { - return -1; - } - } - - /** - * Gets the selected inventory item. - * - * @return the selected inventory item; otherwise null if none - * is selected - */ - public static Item getSelectedItem() { - int index = getSelectedItemIndex(); - return index == -1 ? null : getItemAt(index); - } - - /** - * Gets the selected inventory item's index. - * - * @return the index of the current selected inventory item; otherwise -1 if - * none is selected - */ - public static int getSelectedItemIndex() { - Item[] items = getItems(); - for (Item item : items) { - if (item == null) { - continue; - } - Component comp = item.getComponent(); - if (comp.getBorderThickness() == 2) { - return comp.getIndex(); - } - } - return -1; - } - - /** - * Returns the index of the first occurrence of an item in the inventory - * matching with the provided id. - * - * @param id the item id - * @return the index; otherwise -1. - */ - public static int indexOf(int id) { - Item[] items = getItems(); - for (int i = 0; i < items.length; i++) { - if (id == items[i].getId()) { - return i; - } - } - return -1; - } - - /** - * Returns the index of the first occurrence of an item in the inventory - * matching with the provided name. Case-insensitive. - * - * @param name the name of the item - * @return the index; otherwise -1. - */ - public static int indexOf(String name) { - if (name != null && !name.isEmpty()) { - Item[] items = getItems(); - for (int i = 0; i < items.length; i++) { - if (items[i].getName().equalsIgnoreCase(name)) - return i; - } - } - return -1; - } - - /** - * Checks whether the inventory is full. - * - * @return true if the inventory contains 28 items; otherwise - * false - */ - public static boolean isFull() { - return getCount() == 28; - } - - /** - * Checks whether an inventory item is selected. - * - * @return true if an inventory item is selected; otherwise - * false - */ - public static boolean isItemSelected() { - return getSelectedItemIndex() != -1; - } - - /** - * Opens the inventory tab if not already opened. - */ - public static void openTab() { - int tabInventory = Game.TAB_INVENTORY; - if (Game.getCurrentTab() != tabInventory) { - Game.openTab(tabInventory); - } - } - - /** - * Uses two inventory items together. - * - * @param item the inventory item to use on another inventory item - * @param target the other inventory item to be used on - * @return true if the "Use" action had been used on both inventory - * items; otherwise false - */ - public static boolean useItem(Item item, Item target) { - return item != null && target != null && useItem(item, (Object) target); - } - - /** - * Uses an item on a game object. - * - * @param item the item to use - * @param target the game object to be used on by the item - * @return true if the "Use" action had been used on both the - * inventory item and the game object; otherwise false - */ - public static boolean useItem(Item item, GameObject target) { - if (item != null && target != null) { - for (int i = 0, r = Random.nextInt(5, 8); i < r; i++) { - if (!isItemSelected()) { - if (item.interact("Use")) { - for (int j = 0; j < 10 && !isItemSelected(); j++) { - Task.sleep(100, 200); - } - } else { - return false; - } - } - // just make sure in case something bad happened - if (isItemSelected()) { - final String itemName = item.getName(); - final ObjectDefinition targetDef = target.getDef(); - final Model targetModel = target.getModel(); - if (targetDef != null && itemName != null && targetModel != null) { - final String targetName = targetDef.getName(); - Mouse.move(targetModel.getNextPoint()); - final String action = "Use " + itemName.replace("", "") + " -> " + targetName.replace("", ""); - for (int j = 0, s = Random.nextInt(5, 8); j < s; j++) { - if (Menu.contains(action) && Menu.click(action)) { - return true; - } else { - Mouse.move(targetModel.getNextPoint()); - } - } - } - // kay, since that failed, let's try just use - if (target.interact("Use")) { - return true; - } - } - } - } - return false; - } - - /** - * Uses an inventory item on either another inventory item or a game object. - * - * @param item the inventory item to use - * @param target the inventory item or the game object to be used on by the - * inventory item - * @return true if the "Use" action had been used on both the - * inventory item and the game object/other inventory item; - * otherwise false - */ - private static boolean useItem(Item item, Object target) { - if (isItemSelected()) { - Item selectedItem = getSelectedItem(); - int selectedItemId = selectedItem.getId(); - if (item.getId() != selectedItemId) { - if (!selectedItem.interact("Cancel")) { - return false; - } - } else if (target instanceof Item) { - Item t = (Item) target; - if (selectedItemId != t.getId() - && selectedItemId != item.getId()) { - if (!selectedItem.interact("Cancel")) { - return false; - } - } - } - } - for (int i = 0, r = Random.nextInt(5, 8); i < r; i++) { - if (isItemSelected()) { - boolean success = false; - for (int j = 0, k = Random.nextInt(5, 8); j < k; j++) { - try { - Item t = (Item) target; - if (t.interact("Use")) { - success = true; - break; - } - Task.sleep(150, 300); - } catch (final ClassCastException e) { - return false; - } - } - return success; - } - item.interact("Use"); - Task.sleep(150, 300); - } - return false; - } - -} diff --git a/java/oldies/Perm_v0.java b/java/oldies/Perm_v0.java deleted file mode 100644 index f96ab7a..0000000 --- a/java/oldies/Perm_v0.java +++ /dev/null @@ -1,15 +0,0 @@ -class Test { - - public static String f1; - - public static String f2; - - public static String f3; - - public static String f4; - - public static String f5; - - public static String f6; - -} \ No newline at end of file diff --git a/java/oldies/Perm_v1.java b/java/oldies/Perm_v1.java deleted file mode 100644 index c2ae0b0..0000000 --- a/java/oldies/Perm_v1.java +++ /dev/null @@ -1,14 +0,0 @@ -class Test { - - public static String f4; - - public static String f3; - - public static String f2; - - public static String f6; - - public static String f5; - - public static String f1; -} \ No newline at end of file diff --git a/java/oldies/ResultsProducer_v0.java b/java/oldies/ResultsProducer_v0.java deleted file mode 100644 index c312a38..0000000 --- a/java/oldies/ResultsProducer_v0.java +++ /dev/null @@ -1,179 +0,0 @@ -package fr.labri.vpraxis.refact.benchmark; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.text.DecimalFormat; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import fr.labri.vpraxis.actions.Action; -import fr.labri.vpraxis.actions.io.IActionReader; -import fr.labri.vpraxis.actions.io.xml.XMLActionReader; -import fr.labri.vpraxis.actions.utils.Pair; -import fr.labri.vpraxis.refact.StatesMatcher; - -public class ResultsProducer { - - public static void main(String[] args) { - ResultsProducer r = new ResultsProducer(args[0]); - r.run(); - } - - private String rootPath; - - private FileWriter CSVWriter; - - private FileWriter HTMLWriter; - - private Map>> expValsMap; - - private int tfound = 0; - - private int texact = 0; - - private int texpert = 0; - - private static DecimalFormat nb = new DecimalFormat("#0.00"); - - public ResultsProducer(String rootPath) { - this.rootPath = rootPath; - } - - public void run() { - try { - loadExpValsMap(); - - CSVWriter = new FileWriter(rootPath + ".res.csv"); - HTMLWriter = new FileWriter(rootPath + ".res.html"); - appendHTMLHeader(); - - for(long rev : new TreeSet(expValsMap.keySet())) - handleRevision(rev); - - double tprec = (double) texact / (double) tfound; - double trec = (double) texact / (double) texpert; - - HTMLWriter.append("

Global indicators

\n"); - HTMLWriter.append("

Found : " + tfound + ", expert : " + texpert + ", exact: " + texact + "

\n"); - HTMLWriter.append("

Precision : " + nb.format(tprec) + ", Rappel : " + nb.format(trec) + "

\n"); - - HTMLWriter.append("\n\n\n"); - - HTMLWriter.close(); - CSVWriter.close(); - } - - catch (IOException e) { - e.printStackTrace(); - } - } - - public void handleRevision(long rev) throws IOException { - IActionReader rprevs = new XMLActionReader(rootPath + "_" + (rev-1) + ".xml"); - IActionReader rcurs = new XMLActionReader(rootPath + "_" + (rev) + ".xml"); - - List prevs = rprevs.read(); - List curs = rcurs.read(); - - HTMLWriter.append("

Mappings between rev. " + (rev-1) + " and rev. " + rev + "

\n"); - HTMLWriter.append("\n"); - - long tic = System.currentTimeMillis(); - StatesMatcher matcher = new StatesMatcher(prevs, curs , 0.5D, 0.95D, 0.75D, new double[] {0.15,0.65,0.20}, 10); - Set> mappings = matcher.computeMappings(); - long toc = System.currentTimeMillis(); - - int found = mappings.size(); - tfound += found; - int expert = expValsMap.get(rev).size(); - texpert += expert; - - int exact = 0; - - Set> scorrect = new TreeSet>(new StringPairComparator()); - Set> sincorrect = new TreeSet>(new StringPairComparator()); - Set> smissing = new TreeSet>(new StringPairComparator()); - - for(Pair mapping : mappings) { - if ( expValsMap.get(rev).contains(mapping) ) { - exact++; - scorrect.add(mapping); - } - else - sincorrect.add(mapping); - } - - texact += exact; - - for(Pair mapping : expValsMap.get(rev)) - if ( !scorrect.contains(mapping) ) - smissing.add(mapping); - - double prec = (double) exact / (double) found; - double rec = (double) exact / (double) expert; - - HTMLWriter.append("

Found : " + found + ", expert : " + expert + ", exact: " + exact + "

\n"); - HTMLWriter.append("

Precision : " + nb.format(prec) + ", rappel : " + nb.format(rec) + "

\n"); - - appendRows(scorrect,"correct"); - appendRows(sincorrect,"incorrect"); - appendRows(smissing,"missing"); - - HTMLWriter.append("
\n"); - - CSVWriter.append(rev + ";" + prec + ";" + rec + ";" + (toc-tic) + "\n"); - } - - private void appendRows(Set> mappings,String cls) throws IOException { - for( Pair mapping : mappings ) - HTMLWriter.append("" + enc(mapping.getFirst()) + "" + enc(mapping.getSecond()) + "\n"); - } - - private void appendHTMLHeader() throws IOException { - HTMLWriter.append("\n"); - HTMLWriter.append("\n"); - HTMLWriter.append("" + rootPath + "\n"); - HTMLWriter.append("\n"); - HTMLWriter.append("\n"); - HTMLWriter.append("\n"); - HTMLWriter.append("
\n"); - } - - private void appendCSS() throws IOException { - HTMLWriter.append("body { margin:0; padding:0; color: black; background-color: #CECECE; font-family: Calibri, Helvetica, DejaVuSansCondensed, sans-serif; font-size:100%; width: 100%; text-align: center;}p { display: inline; margin: 0; padding: 0.25em; font-size: 85%; }h1 { padding: 0; margin-bottom: 1em; font-size:125%; font-weight:bold; text-align: left; color: #A50E37; border-bottom: 1px solid #7BA05B;}div { margin:0; padding:0;}table { border-collapse: collapse; font-size : 75%; width: 100%; margin: 0; padding: 0;}.container { margin: 1em auto; padding: 1em; width:90%; background-color: white; text-align: left; -webkit-border-radius: 1em; -moz-border-radius: 1em;}th { margin:0; padding:0; font-weight : bold; font-size : 100%;}tr { margin:0; padding:0;}td { margin:0; padding:0; width: 50%; border:1px solid black;}.correct { background-color: rgb(96,175,92);}.incorrect { background-color: rgb(228,149,31);}.missing { background-color: white;}"); - HTMLWriter.append("\n"); - } - - private void loadExpValsMap() throws FileNotFoundException, IOException { - expValsMap = new HashMap>>(); - BufferedReader r = new BufferedReader(new FileReader(new File(rootPath + ".csv"))); - while ( r.ready() ) { - String l = r.readLine(); - String[] tokens = l.split("\\;"); - long rev = Long.parseLong(tokens[0].trim()); - String src = tokens[1].trim(); - String tgt = tokens[2].trim(); - - if ( !expValsMap.containsKey(rev) ) - expValsMap.put(rev,new HashSet>()); - - expValsMap.get(rev).add(new Pair(src,tgt)); - } - r.close(); - } - - private static String enc(String s) { - return s.replaceAll("\\<","<").replaceAll("\\>",">"); - } - -} diff --git a/java/oldies/ResultsProducer_v1.java b/java/oldies/ResultsProducer_v1.java deleted file mode 100644 index 3049ea2..0000000 --- a/java/oldies/ResultsProducer_v1.java +++ /dev/null @@ -1,212 +0,0 @@ -package fr.labri.vpraxis.refact.benchmark; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.text.DecimalFormat; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import fr.labri.vpraxis.actions.Action; -import fr.labri.vpraxis.actions.io.IActionReader; -import fr.labri.vpraxis.actions.io.xml.XMLActionReader; -import fr.labri.vpraxis.actions.utils.Pair; -import fr.labri.vpraxis.refact.StatesMatcher; - -public class ResultsProducer { - - public static void main(String[] args) { - ResultsProducer r = new ResultsProducer(args[0]); - r.run(); - } - - private String rootPath; - - private FileWriter CSVWriter; - - private FileWriter HTMLWriter; - - private Map>> expMappingsMap; - - private Map expTransfsMap; - - private int tfound = 0; - - private int texact = 0; - - private int texpert = 0; - - private long ttime = 0; - - private static DecimalFormat nb = new DecimalFormat("#0.00"); - - public ResultsProducer(String rootPath) { - this.rootPath = rootPath; - } - - public void run() { - try { - loadExpertData(); - - CSVWriter = new FileWriter(rootPath + ".res.csv"); - HTMLWriter = new FileWriter(rootPath + ".res.html"); - appendHTMLHeader(); - - for(long rev : new TreeSet(expMappingsMap.keySet())) - handleRevision(rev); - - double tprec = (double) texact / (double) tfound; - double trec = (double) texact / (double) texpert; - - HTMLWriter.append("

Global indicators

\n"); - HTMLWriter.append("Found : " + tfound + "\n"); - HTMLWriter.append("Expert : " + texpert + "\n"); - HTMLWriter.append("Exact : " + texact + "\n"); - HTMLWriter.append("Inexact : " + (tfound-texact) + "\n"); - HTMLWriter.append("Precision : " + nb.format(tprec) + "\n"); - HTMLWriter.append("Recall : " + nb.format(trec) + "\n"); - HTMLWriter.append("Time : " + ttime + "\n"); - - HTMLWriter.append("
\n\n\n"); - - HTMLWriter.close(); - CSVWriter.close(); - } - - catch (IOException e) { - e.printStackTrace(); - } - } - - public void handleRevision(long rev) throws IOException { - IActionReader rprevs = new XMLActionReader(rootPath + "_" + (rev-1) + ".xml"); - IActionReader rcurs = new XMLActionReader(rootPath + "_" + (rev) + ".xml"); - - List prevs = rprevs.read(); - List curs = rcurs.read(); - - HTMLWriter.append("

Mappings between rev. " + (rev-1) + " and rev. " + rev + "

\n"); - - long tic = System.currentTimeMillis(); - StatesMatcher matcher = new StatesMatcher(prevs, curs , 0.5D, 0.95D, 0.75D, new double[] {0.15,0.65,0.20}, 10); - Set> mappings = matcher.computeMappings(); - long time = System.currentTimeMillis() - tic; - ttime += time; - - int found = mappings.size(); - tfound += found; - int expert = expMappingsMap.get(rev).size(); - texpert += expert; - - int exact = 0; - - Set> scorrect = new TreeSet>(new StringPairComparator()); - Set> sincorrect = new TreeSet>(new StringPairComparator()); - Set> smissing = new TreeSet>(new StringPairComparator()); - - for(Pair mapping : mappings) { - if ( expMappingsMap.get(rev).contains(mapping) ) { - exact++; - scorrect.add(mapping); - } - else - sincorrect.add(mapping); - } - - texact += exact; - - for(Pair mapping : expMappingsMap.get(rev)) - if ( !scorrect.contains(mapping) ) - smissing.add(mapping); - - double prec = (double) exact / (double) found; - double rec = (double) exact / (double) expert; - - HTMLWriter.append("Found : " + found + "\n"); - HTMLWriter.append("Expert : " + expert + "\n"); - HTMLWriter.append("Exact : " + exact + "\n"); - HTMLWriter.append("Inexact : " + (found-exact) + "\n"); - HTMLWriter.append("Precision : " + nb.format(prec) + "\n"); - HTMLWriter.append("Recall : " + nb.format(rec) + "\n"); - HTMLWriter.append("Time : " + time + "\n"); - - HTMLWriter.append("\n"); - appendRows(scorrect,"correct"); - appendRows(sincorrect,"incorrect"); - appendRows(smissing,"missing"); - HTMLWriter.append("
\n"); - - CSVWriter.append(rev + ";" + prec + ";" + rec + ";" + time + "\n"); - } - - private void appendRows(Set> mappings,String cls) throws IOException { - for( Pair mapping : mappings ) - HTMLWriter.append("" + enc(mapping.getFirst()) + "" + enc(mapping.getSecond()) + "\n"); - } - - private void appendHTMLHeader() throws IOException { - HTMLWriter.append("\n"); - HTMLWriter.append("\n"); - HTMLWriter.append("" + rootPath + "\n"); - HTMLWriter.append("\n"); - HTMLWriter.append("\n"); - HTMLWriter.append("\n"); - HTMLWriter.append("
\n"); - HTMLWriter.append("

Result for " + rootPath + "

\n"); - } - - private void appendCSS() throws IOException { - HTMLWriter.append("body { margin:0; padding:0; color: black; background-color: #CECECE; font-family: Calibri, Helvetica, DejaVuSansCondensed, sans-serif; font-size:100%; width: 100%; text-align: center;}p { display: inline; margin: 0; padding: 0.25em; font-size : 85%;}h1 { padding: 0; margin-bottom: 1em; font-size:150%; font-weight:bold; text-align: left; color: black;}h2 { padding: 0; margin-bottom: 0.5em; font-size:125%; font-weight:bold; text-align: left; color: #A50E37; border-bottom: 1px solid #7BA05B;}div { margin:0; padding:0;}table { border-collapse: collapse; font-size : 75%; width: 100%; margin: 0; padding: 0;}.container { margin: 1em auto; padding: 1em; width:90%; background-color: white; text-align: left; -webkit-border-radius: 1em; -moz-border-radius: 1em;}th { margin:0; padding:0; font-weight : bold; font-size : 100%;}tr { margin:0; padding:0;}td { margin:0; padding:0; width: 50%; border:1px solid black;}.correct { background-color: rgb(96,175,92);}.incorrect { background-color: rgb(228,149,31);}.missing { background-color: white;}.info { font-weight: bold; margin-left : 40px; font-size: 85%;}"); - HTMLWriter.append("\n"); - } - - private void loadExpertData() throws FileNotFoundException, IOException { - expMappingsMap = new HashMap>>(); - expTransfsMap = new HashMap(); - - BufferedReader r = new BufferedReader(new FileReader(new File(rootPath + ".csv"))); - - int n = 0; - while ( r.ready() ) { - String l = r.readLine(); - String[] tokens = l.split("\\;"); - - if ( n != 0 && !"".equals(tokens[1])) { - - long rev = Long.parseLong(tokens[0].trim()); - String src = tokens[1].trim(); - String tgt = tokens[2].trim(); - - if ( !expMappingsMap.containsKey(rev) ) - expMappingsMap.put(rev,new HashSet>()); - - expMappingsMap.get(rev).add(new Pair(src,tgt)); - - String[] transfs = tokens[3].split(","); - for(String transf : transfs ) - if ( !expTransfsMap.containsKey(transf) ) - expTransfsMap.put(transf,1); - else - expTransfsMap.put(transf,expTransfsMap.get(transf)+1); - } - n++; - } - r.close(); - - - } - - private static String enc(String s) { - return s.replaceAll("\\<","<").replaceAll("\\>",">"); - } - -} diff --git a/java/oldies/Slides_v0.java b/java/oldies/Slides_v0.java deleted file mode 100644 index f1a8a10..0000000 --- a/java/oldies/Slides_v0.java +++ /dev/null @@ -1,11 +0,0 @@ -class Test { - - void foo(int z) { - int x = 12; - x++; - x++; - int y = x + 16; - System.out.println(z+y); - } - -} \ No newline at end of file diff --git a/java/oldies/Slides_v1.java b/java/oldies/Slides_v1.java deleted file mode 100644 index eec6401..0000000 --- a/java/oldies/Slides_v1.java +++ /dev/null @@ -1,16 +0,0 @@ -class Test { - - void dispFoo(int z) { - int y = getY(); - System.out.println(z+y); - } - - int getY() { - int x = 12; - x++; - x++; - int y = x + 16; - return y; - } - -} \ No newline at end of file diff --git a/java/oldies/jnamed_1.68_1.69_v0.java b/java/oldies/jnamed_1.68_1.69_v0.java deleted file mode 100644 index 6c2a66b..0000000 --- a/java/oldies/jnamed_1.68_1.69_v0.java +++ /dev/null @@ -1,700 +0,0 @@ -import java.lang.reflect.*; -import java.io.*; -import java.net.*; -import java.util.*; -import org.xbill.DNS.*; -import org.xbill.DNS.utils.*; - -/** @author Brian Wellington <bwelling@xbill.org> */ - -public class jnamed { - -static final int FLAG_DNSSECOK = 1; -static final int FLAG_SIGONLY = 2; - -Map caches; -Map znames; -Map TSIGs; - -public -jnamed(String conffile) throws IOException { - FileInputStream fs; - List ports = new ArrayList(); - List addresses = new ArrayList(); - try { - fs = new FileInputStream(conffile); - } - catch (Exception e) { - System.out.println("Cannot open " + conffile); - return; - } - - caches = new HashMap(); - znames = new HashMap(); - TSIGs = new HashMap(); - - BufferedReader br = new BufferedReader(new InputStreamReader(fs)); - String line = null; - while ((line = br.readLine()) != null) { - StringTokenizer st = new StringTokenizer(line); - if (!st.hasMoreTokens()) - continue; - String keyword = st.nextToken(); - if (!st.hasMoreTokens()) { - System.out.println("Invalid line: " + line); - continue; - } - if (keyword.charAt(0) == '#') - continue; - if (keyword.equals("primary")) - addPrimaryZone(st.nextToken(), st.nextToken()); - else if (keyword.equals("secondary")) - addSecondaryZone(st.nextToken(), st.nextToken()); - else if (keyword.equals("cache")) { - Cache cache = new Cache(st.nextToken()); - caches.put(new Short(DClass.IN), cache); - } - else if (keyword.equals("key")) - addTSIG(st.nextToken(), st.nextToken()); - else if (keyword.equals("port")) - ports.add(Short.valueOf(st.nextToken())); - else if (keyword.equals("address")) { - String addr = st.nextToken(); - addresses.add(InetAddress.getByName(addr)); - } else { - System.out.println("ignoring invalid keyword: " + - keyword); - } - - } - - if (ports.size() == 0) - ports.add(new Short((short)53)); - - if (addresses.size() == 0) - addresses.add(null); - - Iterator iaddr = addresses.iterator(); - while (iaddr.hasNext()) { - InetAddress addr = (InetAddress) iaddr.next(); - Iterator iport = ports.iterator(); - while (iport.hasNext()) { - short port = ((Short)iport.next()).shortValue(); - String addrString; - addUDP(addr, port); - addTCP(addr, port); - if (addr == null) - addrString = "0.0.0.0"; - else - addrString = addr.getHostAddress(); - System.out.println("jnamed: listening on " + - addrString + "#" + port); - } - } - System.out.println("jnamed: running"); -} - -public void -addPrimaryZone(String zname, String zonefile) throws IOException { - Name origin = null; - Cache cache = getCache(DClass.IN); - if (zname != null) - origin = Name.fromString(zname, Name.root); - Zone newzone = new Zone(zonefile, cache, origin); - znames.put(newzone.getOrigin(), newzone); -} - -public void -addSecondaryZone(String zone, String remote) throws IOException { - Cache cache = getCache(DClass.IN); - Name zname = Name.fromString(zone, Name.root); - Zone newzone = new Zone(zname, DClass.IN, remote, cache); - znames.put(zname, newzone); -} - -public void -addTSIG(String namestr, String key) throws IOException { - Name name = Name.fromString(namestr, Name.root); - TSIGs.put(name, base64.fromString(key)); -} - -public Cache -getCache(short dclass) { - Cache c = (Cache) caches.get(new Short(dclass)); - if (c == null) { - c = new Cache(dclass); - caches.put(new Short(dclass), c); - } - return c; -} - -public Zone -findBestZone(Name name) { - Zone foundzone = null; - foundzone = (Zone) znames.get(name); - if (foundzone != null) - return foundzone; - int labels = name.labels(); - for (int i = 1; i < labels; i++) { - Name tname = new Name(name, i); - foundzone = (Zone) znames.get(tname); - if (foundzone != null) - return foundzone; - } - return null; -} - -public RRset -findExactMatch(Name name, short type, short dclass, boolean glue) { - Zone zone = findBestZone(name); - if (zone != null) - return zone.findExactMatch(name, type); - else { - RRset [] rrsets; - Cache cache = getCache(dclass); - if (glue) - rrsets = cache.findAnyRecords(name, type); - else - rrsets = cache.findRecords(name, type); - if (rrsets == null) - return null; - else - return rrsets[0]; /* not quite right */ - } -} - -void -addRRset(Name name, Message response, RRset rrset, byte section, int flags) { - for (byte s = 1; s <= section; s++) - if (response.findRRset(name, rrset.getType(), s)) - return; - if ((flags & FLAG_SIGONLY) == 0) { - Iterator it = rrset.rrs(); - while (it.hasNext()) { - Record r = (Record) it.next(); - if (!name.isWild() && r.getName().isWild()) - r = r.withName(name); - response.addRecord(r, section); - } - } - if ((flags & (FLAG_SIGONLY | FLAG_DNSSECOK)) != 0) { - Iterator it = rrset.sigs(); - while (it.hasNext()) { - Record r = (Record) it.next(); - if (!name.isWild() && r.getName().isWild()) - r = r.withName(name); - response.addRecord(r, section); - } - } -} - -private void -addSOA(Message response, Zone zone) { - response.addRecord(zone.getSOA(), Section.AUTHORITY); -} - -private void -addNS(Message response, Zone zone, int flags) { - RRset nsRecords = zone.getNS(); - addRRset(nsRecords.getName(), response, nsRecords, - Section.AUTHORITY, flags); -} - -private void -addCacheNS(Message response, Cache cache, Name name) { - SetResponse sr = cache.lookupRecords(name, Type.NS, Credibility.HINT); - if (!sr.isDelegation()) - return; - RRset nsRecords = sr.getNS(); - Iterator it = nsRecords.rrs(); - while (it.hasNext()) { - Record r = (Record) it.next(); - response.addRecord(r, Section.AUTHORITY); - } -} - -private void -addGlue(Message response, Name name, int flags) { - RRset a = findExactMatch(name, Type.A, DClass.IN, true); - if (a == null) - return; - addRRset(name, response, a, Section.ADDITIONAL, flags); -} - -private void -addAdditional2(Message response, int section, int flags) { - Record [] records = response.getSectionArray(section); - for (int i = 0; i < records.length; i++) { - Record r = records[i]; - Name glueName = null; - switch (r.getType()) { - case Type.MX: - glueName = ((MXRecord)r).getTarget(); - break; - case Type.NS: - glueName = ((NSRecord)r).getTarget(); - break; - case Type.KX: - glueName = ((KXRecord)r).getTarget(); - break; - case Type.NAPTR: - glueName = ((NAPTRRecord)r).getReplacement(); - break; - case Type.SRV: - glueName = ((SRVRecord)r).getTarget(); - break; - default: - break; - } - if (glueName != null) - addGlue(response, glueName, flags); - } -} - -void -addAdditional(Message response, int flags) { - addAdditional2(response, Section.ANSWER, flags); - addAdditional2(response, Section.AUTHORITY, flags); -} - -byte -addAnswer(Message response, Name name, short type, short dclass, - int iterations, int flags) -{ - SetResponse sr; - byte rcode = Rcode.NOERROR; - - if (iterations > 6) - return Rcode.NOERROR; - - if (type == Type.SIG) { - type = Type.ANY; - flags |= FLAG_SIGONLY; - } - - Zone zone = findBestZone(name); - if (zone != null) - sr = zone.findRecords(name, type); - else { - Cache cache = getCache(dclass); - sr = cache.lookupRecords(name, type, - Credibility.NONAUTH_ANSWER); - } - - if (sr.isUnknown()) { - addCacheNS(response, getCache(dclass), name); - } - if (sr.isNXDOMAIN()) { - response.getHeader().setRcode(Rcode.NXDOMAIN); - if (zone != null) { - addSOA(response, zone); - if (iterations == 0) - response.getHeader().setFlag(Flags.AA); - } - rcode = Rcode.NXDOMAIN; - } - else if (sr.isNXRRSET()) { - if (zone != null) { - addSOA(response, zone); - if (iterations == 0) - response.getHeader().setFlag(Flags.AA); - } - } - else if (sr.isDelegation()) { - RRset nsRecords = sr.getNS(); - addRRset(nsRecords.getName(), response, nsRecords, - Section.AUTHORITY, flags); - } - else if (sr.isCNAME()) { - RRset rrset = new RRset(); - CNAMERecord cname = sr.getCNAME(); - rrset.addRR(cname); - addRRset(name, response, rrset, Section.ANSWER, flags); - if (zone != null && iterations == 0) - response.getHeader().setFlag(Flags.AA); - rcode = addAnswer(response, cname.getTarget(), - type, dclass, iterations + 1, flags); - } - else if (sr.isDNAME()) { - RRset rrset = new RRset(); - DNAMERecord dname = sr.getDNAME(); - rrset.addRR(dname); - addRRset(name, response, rrset, Section.ANSWER, flags); - Name newname = name.fromDNAME(dname); - if (newname == null) - return Rcode.SERVFAIL; - try { - rrset = new RRset(); - rrset.addRR(new CNAMERecord(name, dclass, 0, newname)); - addRRset(name, response, rrset, Section.ANSWER, flags); - } - catch (IOException e) {} - if (zone != null && iterations == 0) - response.getHeader().setFlag(Flags.AA); - rcode = addAnswer(response, newname, type, dclass, - iterations + 1, flags); - } - else if (sr.isSuccessful()) { - RRset [] rrsets = sr.answers(); - for (int i = 0; i < rrsets.length; i++) - addRRset(name, response, rrsets[i], - Section.ANSWER, flags); - if (zone != null) { - addNS(response, zone, flags); - if (iterations == 0) - response.getHeader().setFlag(Flags.AA); - } - else - addCacheNS(response, getCache(dclass), name); - } - return rcode; -} - -TSIG -findTSIG(Name name) { - byte [] key = (byte []) TSIGs.get(name); - if (key != null) - return new TSIG(name, key); - else - return null; -} - -Message -doAXFR(Name name, Message query, TSIG tsig, TSIGRecord qtsig, Socket s) { - Zone zone = (Zone) znames.get(name); - boolean first = true; - if (zone == null) { -/* System.out.println("no zone " + name + " to AXFR");*/ - return errorMessage(query, Rcode.REFUSED); - } - Enumeration e = zone.AXFR(); - try { - DataOutputStream dataOut; - dataOut = new DataOutputStream(s.getOutputStream()); - int id = query.getHeader().getID(); - while (e.hasMoreElements()) { - RRset rrset = (RRset) e.nextElement(); - Message response = new Message(); - Header header = response.getHeader(); - header.setID(id); - header.setFlag(Flags.QR); - header.setFlag(Flags.AA); - addRRset(rrset.getName(), response, rrset, - Section.ANSWER, FLAG_DNSSECOK); - tsig.applyAXFR(response, qtsig, first); - qtsig = response.getTSIG(); - first = false; - byte [] out = response.toWire(); - dataOut.writeShort(out.length); - dataOut.write(out); - } - } - catch (IOException ex) { - System.out.println("AXFR failed"); - } - try { - s.close(); - } - catch (IOException ex) { - } - return null; -} - -/* - * Note: a null return value means that the caller doesn't need to do - * anything. Currently this only happens if this is an AXFR request over - * TCP. - */ -Message -generateReply(Message query, byte [] in, Socket s) { - Header header; - boolean badversion; - int maxLength; - boolean sigonly; - SetResponse sr; - int flags = 0; - - header = query.getHeader(); - if (header.getFlag(Flags.QR)) - return null; - if (header.getRcode() != Rcode.NOERROR) - return errorMessage(query, Rcode.FORMERR); - if (header.getOpcode() != Opcode.QUERY) - return errorMessage(query, Rcode.NOTIMPL); - - Record queryRecord = query.getQuestion(); - - TSIGRecord queryTSIG = query.getTSIG(); - TSIG tsig = null; - if (queryTSIG != null) { - tsig = findTSIG(queryTSIG.getName()); - if (tsig == null || - tsig.verify(query, in, null) != Rcode.NOERROR) - return formerrMessage(in); - } - - OPTRecord queryOPT = query.getOPT(); - if (queryOPT != null && queryOPT.getVersion() > 0) - badversion = true; - - if (s != null) - maxLength = 65535; - else if (queryOPT != null) - maxLength = queryOPT.getPayloadSize(); - else - maxLength = 512; - - if (queryOPT != null && (queryOPT.getFlags() & Flags.DO) != 0) - flags = FLAG_DNSSECOK; - - Message response = new Message(); - response.getHeader().setID(query.getHeader().getID()); - response.getHeader().setFlag(Flags.QR); - if (query.getHeader().getFlag(Flags.RD)); - response.getHeader().setFlag(Flags.RD); - response.addRecord(queryRecord, Section.QUESTION); - - Name name = queryRecord.getName(); - short type = queryRecord.getType(); - short dclass = queryRecord.getDClass(); - if (type == Type.AXFR && s != null) - return doAXFR(name, query, tsig, queryTSIG, s); - if (!Type.isRR(type) && type != Type.ANY) - return errorMessage(query, Rcode.NOTIMPL); - - byte rcode = addAnswer(response, name, type, dclass, 0, flags); - if (rcode != Rcode.NOERROR && rcode != Rcode.NXDOMAIN) - return errorMessage(query, rcode); - - addAdditional(response, flags); - if (queryTSIG != null) { - try { - if (tsig != null) - tsig.apply(response, queryTSIG); - } - catch (IOException e) { - } - } - try { - response.freeze(); - byte [] out = response.toWire(); - if (out.length > maxLength) { - response.thaw(); - truncate(response, out.length, maxLength); - if (tsig != null) - tsig.apply(response, queryTSIG); - } - } - catch (IOException e) { - } - return response; -} - -public int -truncateSection(Message in, int maxLength, int length, int section) { - int removed = 0; - Record [] records = in.getSectionArray(section); - for (int i = records.length - 1; i >= 0; i--) { - Record r = records[i]; - removed += r.getWireLength(); - length -= r.getWireLength(); - in.removeRecord(r, section); - if (length > maxLength) - continue; - else { - for (int j = i - 1; j >= 0; j--) { - Record r2 = records[j]; - if (!r.getName().equals(r2.getName()) || - r.getType() != r2.getType() || - r.getDClass() != r2.getDClass()) - break; - removed += r2.getWireLength(); - length -= r2.getWireLength(); - in.removeRecord(r2, section); - } - return removed; - } - } - return removed; -} - -public void -truncate(Message in, int length, int maxLength) { - TSIGRecord tsig = in.getTSIG(); - if (tsig != null) - maxLength -= tsig.getWireLength(); - - length -= truncateSection(in, maxLength, length, Section.ADDITIONAL); - if (length < maxLength) - return; - - in.getHeader().setFlag(Flags.TC); - if (tsig != null) { - in.removeAllRecords(Section.ANSWER); - in.removeAllRecords(Section.AUTHORITY); - return; - } - length -= truncateSection(in, maxLength, length, Section.AUTHORITY); - if (length < maxLength) - return; - length -= truncateSection(in, maxLength, length, Section.ANSWER); -} - -public Message -formerrMessage(byte [] in) { - Header header; - try { - header = new Header(new DataByteInputStream(in)); - } - catch (IOException e) { - header = new Header(0); - } - Message response = new Message(); - response.setHeader(header); - for (int i = 0; i < 4; i++) - response.removeAllRecords(i); - header.setRcode(Rcode.FORMERR); - return response; -} - -public Message -errorMessage(Message query, short rcode) { - Header header = query.getHeader(); - Message response = new Message(); - response.setHeader(header); - for (int i = 0; i < 4; i++) - response.removeAllRecords(i); - if (rcode == Rcode.SERVFAIL) - response.addRecord(query.getQuestion(), Section.QUESTION); - header.setRcode(rcode); - return response; -} - -public void -serveTCP(InetAddress addr, short port) { - try { - ServerSocket sock = new ServerSocket(port, 128, addr); - while (true) { - Socket s = sock.accept(); - int inLength; - DataInputStream dataIn; - DataOutputStream dataOut; - byte [] in; - - try { - InputStream is = s.getInputStream(); - dataIn = new DataInputStream(is); - inLength = dataIn.readUnsignedShort(); - in = new byte[inLength]; - dataIn.readFully(in); - } - catch (InterruptedIOException e) { - s.close(); - continue; - } - Message query, response; - try { - query = new Message(in); - response = generateReply(query, in, s); - if (response == null) - continue; - } - catch (IOException e) { - response = formerrMessage(in); - } - byte [] out = response.toWire(); - dataOut = new DataOutputStream(s.getOutputStream()); - dataOut.writeShort(out.length); - dataOut.write(out); - s.close(); - } - } - catch (IOException e) { - String addrString; - if (addr == null) - addrString = "0.0.0.0"; - else - addrString = addr.getHostAddress(); - System.out.println("serveTCP(" + addrString + "#" + port + - "): " + e); - } -} - -public void -serveUDP(InetAddress addr, short port) { - try { - DatagramSocket sock = new DatagramSocket(port, addr); - while (true) { - short udpLength = 512; - byte [] in = new byte[udpLength]; - DatagramPacket dp = new DatagramPacket(in, in.length); - try { - sock.receive(dp); - } - catch (InterruptedIOException e) { - continue; - } - Message query, response; - try { - query = new Message(in); - response = generateReply(query, in, null); - if (response == null) - continue; - } - catch (IOException e) { - response = formerrMessage(in); - } - byte [] out = response.toWire(); - - dp = new DatagramPacket(out, out.length, - dp.getAddress(), dp.getPort()); - sock.send(dp); - } - } - catch (IOException e) { - String addrString; - if (addr == null) - addrString = "0.0.0.0"; - else - addrString = addr.getHostAddress(); - System.out.println("serveUDP(" + addrString + "#" + port + - "): " + e); - } -} - -public void -addTCP(final InetAddress addr, final short port) { - Thread t; - t = new Thread(new Runnable() { - public void run() {serveTCP(addr, port);}}); - t.start(); -} - -public void -addUDP(final InetAddress addr, final short port) { - Thread t; - t = new Thread(new Runnable() { - public void run() {serveUDP(addr, port);}}); - t.start(); -} - -public static void main(String [] args) { - if (args.length > 1) { - System.out.println("usage: jnamed [conf]"); - System.exit(0); - } - jnamed s; - try { - String conf; - if (args.length == 1) - conf = args[0]; - else - conf = "jnamed.conf"; - s = new jnamed(conf); - } - catch (IOException e) { - System.out.println(e); - } -} - -} diff --git a/java/oldies/jnamed_1.68_1.69_v1.java b/java/oldies/jnamed_1.68_1.69_v1.java deleted file mode 100644 index e7023c5..0000000 --- a/java/oldies/jnamed_1.68_1.69_v1.java +++ /dev/null @@ -1,698 +0,0 @@ -import java.lang.reflect.*; -import java.io.*; -import java.net.*; -import java.util.*; -import org.xbill.DNS.*; -import org.xbill.DNS.utils.*; - -/** @author Brian Wellington <bwelling@xbill.org> */ - -public class jnamed { - -static final int FLAG_DNSSECOK = 1; -static final int FLAG_SIGONLY = 2; - -Map caches; -Map znames; -Map TSIGs; - -public -jnamed(String conffile) throws IOException { - FileInputStream fs; - List ports = new ArrayList(); - List addresses = new ArrayList(); - try { - fs = new FileInputStream(conffile); - } - catch (Exception e) { - System.out.println("Cannot open " + conffile); - return; - } - - caches = new HashMap(); - znames = new HashMap(); - TSIGs = new HashMap(); - - BufferedReader br = new BufferedReader(new InputStreamReader(fs)); - String line = null; - while ((line = br.readLine()) != null) { - StringTokenizer st = new StringTokenizer(line); - if (!st.hasMoreTokens()) - continue; - String keyword = st.nextToken(); - if (!st.hasMoreTokens()) { - System.out.println("Invalid line: " + line); - continue; - } - if (keyword.charAt(0) == '#') - continue; - if (keyword.equals("primary")) - addPrimaryZone(st.nextToken(), st.nextToken()); - else if (keyword.equals("secondary")) - addSecondaryZone(st.nextToken(), st.nextToken()); - else if (keyword.equals("cache")) { - Cache cache = new Cache(st.nextToken()); - caches.put(new Short(DClass.IN), cache); - } - else if (keyword.equals("key")) - addTSIG(st.nextToken(), st.nextToken()); - else if (keyword.equals("port")) - ports.add(Short.valueOf(st.nextToken())); - else if (keyword.equals("address")) { - String addr = st.nextToken(); - addresses.add(InetAddress.getByName(addr)); - } else { - System.out.println("ignoring invalid keyword: " + - keyword); - } - - } - - if (ports.size() == 0) - ports.add(new Short((short)53)); - - if (addresses.size() == 0) - addresses.add(null); - - Iterator iaddr = addresses.iterator(); - while (iaddr.hasNext()) { - InetAddress addr = (InetAddress) iaddr.next(); - Iterator iport = ports.iterator(); - while (iport.hasNext()) { - short port = ((Short)iport.next()).shortValue(); - String addrString; - addUDP(addr, port); - addTCP(addr, port); - if (addr == null) - addrString = "0.0.0.0"; - else - addrString = addr.getHostAddress(); - System.out.println("jnamed: listening on " + - addrString + "#" + port); - } - } - System.out.println("jnamed: running"); -} - -public void -addPrimaryZone(String zname, String zonefile) throws IOException { - Name origin = null; - Cache cache = getCache(DClass.IN); - if (zname != null) - origin = Name.fromString(zname, Name.root); - Zone newzone = new Zone(zonefile, cache, origin); - znames.put(newzone.getOrigin(), newzone); -} - -public void -addSecondaryZone(String zone, String remote) throws IOException { - Cache cache = getCache(DClass.IN); - Name zname = Name.fromString(zone, Name.root); - Zone newzone = new Zone(zname, DClass.IN, remote, cache); - znames.put(zname, newzone); -} - -public void -addTSIG(String namestr, String key) throws IOException { - Name name = Name.fromString(namestr, Name.root); - TSIGs.put(name, base64.fromString(key)); -} - -public Cache -getCache(short dclass) { - Cache c = (Cache) caches.get(new Short(dclass)); - if (c == null) { - c = new Cache(dclass); - caches.put(new Short(dclass), c); - } - return c; -} - -public Zone -findBestZone(Name name) { - Zone foundzone = null; - foundzone = (Zone) znames.get(name); - if (foundzone != null) - return foundzone; - int labels = name.labels(); - for (int i = 1; i < labels; i++) { - Name tname = new Name(name, i); - foundzone = (Zone) znames.get(tname); - if (foundzone != null) - return foundzone; - } - return null; -} - -public RRset -findExactMatch(Name name, short type, short dclass, boolean glue) { - Zone zone = findBestZone(name); - if (zone != null) - return zone.findExactMatch(name, type); - else { - RRset [] rrsets; - Cache cache = getCache(dclass); - if (glue) - rrsets = cache.findAnyRecords(name, type); - else - rrsets = cache.findRecords(name, type); - if (rrsets == null) - return null; - else - return rrsets[0]; /* not quite right */ - } -} - -void -addRRset(Name name, Message response, RRset rrset, byte section, int flags) { - for (byte s = 1; s <= section; s++) - if (response.findRRset(name, rrset.getType(), s)) - return; - if ((flags & FLAG_SIGONLY) == 0) { - Iterator it = rrset.rrs(); - while (it.hasNext()) { - Record r = (Record) it.next(); - if (r.getName().isWild() && !name.isWild()) - r = r.withName(name); - response.addRecord(r, section); - } - } - if ((flags & (FLAG_SIGONLY | FLAG_DNSSECOK)) != 0) { - Iterator it = rrset.sigs(); - while (it.hasNext()) { - Record r = (Record) it.next(); - if (r.getName().isWild() && !name.isWild()) - r = r.withName(name); - response.addRecord(r, section); - } - } -} - -private final void -addSOA(Message response, Zone zone) { - response.addRecord(zone.getSOA(), Section.AUTHORITY); -} - -private final void -addNS(Message response, Zone zone, int flags) { - RRset nsRecords = zone.getNS(); - addRRset(nsRecords.getName(), response, nsRecords, - Section.AUTHORITY, flags); -} - -private final void -addCacheNS(Message response, Cache cache, Name name) { - SetResponse sr = cache.lookupRecords(name, Type.NS, Credibility.HINT); - if (!sr.isDelegation()) - return; - RRset nsRecords = sr.getNS(); - Iterator it = nsRecords.rrs(); - while (it.hasNext()) { - Record r = (Record) it.next(); - response.addRecord(r, Section.AUTHORITY); - } -} - -private void -addGlue(Message response, Name name, int flags) { - RRset a = findExactMatch(name, Type.A, DClass.IN, true); - if (a == null) - return; - addRRset(name, response, a, Section.ADDITIONAL, flags); -} - -private void -addAdditional2(Message response, int section, int flags) { - Record [] records = response.getSectionArray(section); - for (int i = 0; i < records.length; i++) { - Record r = records[i]; - Name glueName = null; - switch (r.getType()) { - case Type.MX: - glueName = ((MXRecord)r).getTarget(); - break; - case Type.NS: - glueName = ((NSRecord)r).getTarget(); - break; - case Type.KX: - glueName = ((KXRecord)r).getTarget(); - break; - case Type.NAPTR: - glueName = ((NAPTRRecord)r).getReplacement(); - break; - case Type.SRV: - glueName = ((SRVRecord)r).getTarget(); - break; - default: - break; - } - if (glueName != null) - addGlue(response, glueName, flags); - } -} - -private final void -addAdditional(Message response, int flags) { - addAdditional2(response, Section.ANSWER, flags); - addAdditional2(response, Section.AUTHORITY, flags); -} - -byte -addAnswer(Message response, Name name, short type, short dclass, - int iterations, int flags) -{ - SetResponse sr; - byte rcode = Rcode.NOERROR; - - if (iterations > 6) - return Rcode.NOERROR; - - if (type == Type.SIG) { - type = Type.ANY; - flags |= FLAG_SIGONLY; - } - - Zone zone = findBestZone(name); - if (zone != null) - sr = zone.findRecords(name, type); - else { - Cache cache = getCache(dclass); - sr = cache.lookupRecords(name, type, - Credibility.NONAUTH_ANSWER); - } - - if (sr.isUnknown()) { - addCacheNS(response, getCache(dclass), name); - } - if (sr.isNXDOMAIN()) { - response.getHeader().setRcode(Rcode.NXDOMAIN); - if (zone != null) { - addSOA(response, zone); - if (iterations == 0) - response.getHeader().setFlag(Flags.AA); - } - rcode = Rcode.NXDOMAIN; - } - else if (sr.isNXRRSET()) { - if (zone != null) { - addSOA(response, zone); - if (iterations == 0) - response.getHeader().setFlag(Flags.AA); - } - } - else if (sr.isDelegation()) { - RRset nsRecords = sr.getNS(); - addRRset(nsRecords.getName(), response, nsRecords, - Section.AUTHORITY, flags); - } - else if (sr.isCNAME()) { - RRset rrset = new RRset(); - CNAMERecord cname = sr.getCNAME(); - rrset.addRR(cname); - addRRset(name, response, rrset, Section.ANSWER, flags); - if (zone != null && iterations == 0) - response.getHeader().setFlag(Flags.AA); - rcode = addAnswer(response, cname.getTarget(), - type, dclass, iterations + 1, flags); - } - else if (sr.isDNAME()) { - RRset rrset = new RRset(); - DNAMERecord dname = sr.getDNAME(); - rrset.addRR(dname); - addRRset(name, response, rrset, Section.ANSWER, flags); - Name newname = name.fromDNAME(dname); - if (newname == null) - return Rcode.SERVFAIL; - try { - rrset = new RRset(); - rrset.addRR(new CNAMERecord(name, dclass, 0, newname)); - addRRset(name, response, rrset, Section.ANSWER, flags); - } - catch (IOException e) {} - if (zone != null && iterations == 0) - response.getHeader().setFlag(Flags.AA); - rcode = addAnswer(response, newname, type, dclass, - iterations + 1, flags); - } - else if (sr.isSuccessful()) { - RRset [] rrsets = sr.answers(); - for (int i = 0; i < rrsets.length; i++) - addRRset(name, response, rrsets[i], - Section.ANSWER, flags); - if (zone != null) { - addNS(response, zone, flags); - if (iterations == 0) - response.getHeader().setFlag(Flags.AA); - } - else - addCacheNS(response, getCache(dclass), name); - } - return rcode; -} - -TSIG -findTSIG(Name name) { - byte [] key = (byte []) TSIGs.get(name); - if (key != null) - return new TSIG(name, key); - else - return null; -} - -Message -doAXFR(Name name, Message query, TSIG tsig, TSIGRecord qtsig, Socket s) { - Zone zone = (Zone) znames.get(name); - boolean first = true; - if (zone == null) - return errorMessage(query, Rcode.REFUSED); - Enumeration e = zone.AXFR(); - try { - DataOutputStream dataOut; - dataOut = new DataOutputStream(s.getOutputStream()); - int id = query.getHeader().getID(); - while (e.hasMoreElements()) { - RRset rrset = (RRset) e.nextElement(); - Message response = new Message(); - Header header = response.getHeader(); - header.setID(id); - header.setFlag(Flags.QR); - header.setFlag(Flags.AA); - addRRset(rrset.getName(), response, rrset, - Section.ANSWER, FLAG_DNSSECOK); - tsig.applyAXFR(response, qtsig, first); - qtsig = response.getTSIG(); - first = false; - byte [] out = response.toWire(); - dataOut.writeShort(out.length); - dataOut.write(out); - } - } - catch (IOException ex) { - System.out.println("AXFR failed"); - } - try { - s.close(); - } - catch (IOException ex) { - } - return null; -} - -/* - * Note: a null return value means that the caller doesn't need to do - * anything. Currently this only happens if this is an AXFR request over - * TCP. - */ -Message -generateReply(Message query, byte [] in, Socket s) { - Header header; - boolean badversion; - int maxLength; - boolean sigonly; - SetResponse sr; - int flags = 0; - - header = query.getHeader(); - if (header.getFlag(Flags.QR)) - return null; - if (header.getRcode() != Rcode.NOERROR) - return errorMessage(query, Rcode.FORMERR); - if (header.getOpcode() != Opcode.QUERY) - return errorMessage(query, Rcode.NOTIMPL); - - Record queryRecord = query.getQuestion(); - - TSIGRecord queryTSIG = query.getTSIG(); - TSIG tsig = null; - if (queryTSIG != null) { - tsig = findTSIG(queryTSIG.getName()); - if (tsig == null || - tsig.verify(query, in, null) != Rcode.NOERROR) - return formerrMessage(in); - } - - OPTRecord queryOPT = query.getOPT(); - if (queryOPT != null && queryOPT.getVersion() > 0) - badversion = true; - - if (s != null) - maxLength = 65535; - else if (queryOPT != null) - maxLength = queryOPT.getPayloadSize(); - else - maxLength = 512; - - if (queryOPT != null && (queryOPT.getFlags() & Flags.DO) != 0) - flags = FLAG_DNSSECOK; - - Message response = new Message(); - response.getHeader().setID(query.getHeader().getID()); - response.getHeader().setFlag(Flags.QR); - if (query.getHeader().getFlag(Flags.RD)); - response.getHeader().setFlag(Flags.RD); - response.addRecord(queryRecord, Section.QUESTION); - - Name name = queryRecord.getName(); - short type = queryRecord.getType(); - short dclass = queryRecord.getDClass(); - if (type == Type.AXFR && s != null) - return doAXFR(name, query, tsig, queryTSIG, s); - if (!Type.isRR(type) && type != Type.ANY) - return errorMessage(query, Rcode.NOTIMPL); - - byte rcode = addAnswer(response, name, type, dclass, 0, flags); - if (rcode != Rcode.NOERROR && rcode != Rcode.NXDOMAIN) - return errorMessage(query, rcode); - - addAdditional(response, flags); - if (queryTSIG != null) { - try { - if (tsig != null) - tsig.apply(response, queryTSIG); - } - catch (IOException e) { - } - } - try { - response.freeze(); - byte [] out = response.toWire(); - if (out.length > maxLength) { - response.thaw(); - truncate(response, out.length, maxLength); - if (tsig != null) - tsig.apply(response, queryTSIG); - } - } - catch (IOException e) { - } - return response; -} - -public int -truncateSection(Message in, int maxLength, int length, int section) { - int removed = 0; - Record [] records = in.getSectionArray(section); - for (int i = records.length - 1; i >= 0; i--) { - Record r = records[i]; - removed += r.getWireLength(); - length -= r.getWireLength(); - in.removeRecord(r, section); - if (length > maxLength) - continue; - else { - for (int j = i - 1; j >= 0; j--) { - Record r2 = records[j]; - if (!r.getName().equals(r2.getName()) || - r.getType() != r2.getType() || - r.getDClass() != r2.getDClass()) - break; - removed += r2.getWireLength(); - length -= r2.getWireLength(); - in.removeRecord(r2, section); - } - return removed; - } - } - return removed; -} - -public void -truncate(Message in, int length, int maxLength) { - TSIGRecord tsig = in.getTSIG(); - if (tsig != null) - maxLength -= tsig.getWireLength(); - - length -= truncateSection(in, maxLength, length, Section.ADDITIONAL); - if (length < maxLength) - return; - - in.getHeader().setFlag(Flags.TC); - if (tsig != null) { - in.removeAllRecords(Section.ANSWER); - in.removeAllRecords(Section.AUTHORITY); - return; - } - length -= truncateSection(in, maxLength, length, Section.AUTHORITY); - if (length < maxLength) - return; - length -= truncateSection(in, maxLength, length, Section.ANSWER); -} - -public Message -formerrMessage(byte [] in) { - Header header; - try { - header = new Header(new DataByteInputStream(in)); - } - catch (IOException e) { - header = new Header(0); - } - Message response = new Message(); - response.setHeader(header); - for (int i = 0; i < 4; i++) - response.removeAllRecords(i); - header.setRcode(Rcode.FORMERR); - return response; -} - -public Message -errorMessage(Message query, short rcode) { - Header header = query.getHeader(); - Message response = new Message(); - response.setHeader(header); - for (int i = 0; i < 4; i++) - response.removeAllRecords(i); - if (rcode == Rcode.SERVFAIL) - response.addRecord(query.getQuestion(), Section.QUESTION); - header.setRcode(rcode); - return response; -} - -public void -serveTCP(InetAddress addr, short port) { - try { - ServerSocket sock = new ServerSocket(port, 128, addr); - while (true) { - Socket s = sock.accept(); - int inLength; - DataInputStream dataIn; - DataOutputStream dataOut; - byte [] in; - - try { - InputStream is = s.getInputStream(); - dataIn = new DataInputStream(is); - inLength = dataIn.readUnsignedShort(); - in = new byte[inLength]; - dataIn.readFully(in); - } - catch (InterruptedIOException e) { - s.close(); - continue; - } - Message query, response; - try { - query = new Message(in); - response = generateReply(query, in, s); - if (response == null) - continue; - } - catch (IOException e) { - response = formerrMessage(in); - } - byte [] out = response.toWire(); - dataOut = new DataOutputStream(s.getOutputStream()); - dataOut.writeShort(out.length); - dataOut.write(out); - s.close(); - } - } - catch (IOException e) { - String addrString; - if (addr == null) - addrString = "0.0.0.0"; - else - addrString = addr.getHostAddress(); - System.out.println("serveTCP(" + addrString + "#" + port + - "): " + e); - } -} - -public void -serveUDP(InetAddress addr, short port) { - try { - DatagramSocket sock = new DatagramSocket(port, addr); - while (true) { - short udpLength = 512; - byte [] in = new byte[udpLength]; - DatagramPacket dp = new DatagramPacket(in, in.length); - try { - sock.receive(dp); - } - catch (InterruptedIOException e) { - continue; - } - Message query, response; - try { - query = new Message(in); - response = generateReply(query, in, null); - if (response == null) - continue; - } - catch (IOException e) { - response = formerrMessage(in); - } - byte [] out = response.toWire(); - - dp = new DatagramPacket(out, out.length, - dp.getAddress(), dp.getPort()); - sock.send(dp); - } - } - catch (IOException e) { - String addrString; - if (addr == null) - addrString = "0.0.0.0"; - else - addrString = addr.getHostAddress(); - System.out.println("serveUDP(" + addrString + "#" + port + - "): " + e); - } -} - -public void -addTCP(final InetAddress addr, final short port) { - Thread t; - t = new Thread(new Runnable() { - public void run() {serveTCP(addr, port);}}); - t.start(); -} - -public void -addUDP(final InetAddress addr, final short port) { - Thread t; - t = new Thread(new Runnable() { - public void run() {serveUDP(addr, port);}}); - t.start(); -} - -public static void main(String [] args) { - if (args.length > 1) { - System.out.println("usage: jnamed [conf]"); - System.exit(0); - } - jnamed s; - try { - String conf; - if (args.length == 1) - conf = args[0]; - else - conf = "jnamed.conf"; - s = new jnamed(conf); - } - catch (IOException e) { - System.out.println(e); - } -} - -} diff --git a/java/oldies/update_1.70_1.71_v0.java b/java/oldies/update_1.70_1.71_v0.java deleted file mode 100644 index 31069cd..0000000 --- a/java/oldies/update_1.70_1.71_v0.java +++ /dev/null @@ -1,700 +0,0 @@ -// Copyright (c) 1999 Brian Wellington (bwelling@xbill.org) -// Portions Copyright (c) 1999 Network Associates, Inc. - -import java.net.*; -import java.io.*; -import java.util.*; -import org.xbill.DNS.*; -import org.xbill.DNS.utils.*; - -/** @author Brian Wellington <bwelling@xbill.org> */ - -public class update { - -Message query, response; -Resolver res; -String server = null; -Name zone = Name.root; -int defaultTTL; -short defaultClass = DClass.IN; -PrintStream log = null; - -void -print(Object o) { - System.out.println(o); - if (log != null) - log.println(o); -} - -public -update(InputStream in) throws IOException { - List inputs = new LinkedList(); - List istreams = new LinkedList(); - - query = new Message(); - query.getHeader().setOpcode(Opcode.UPDATE); - - InputStreamReader isr = new InputStreamReader(in); - BufferedReader br = new BufferedReader(isr); - - inputs.add(br); - istreams.add(in); - - while (true) { - try { - String line = null; - do { - InputStream is; - is = (InputStream)istreams.get(0); - br = (BufferedReader)inputs.get(0); - - if (is == System.in) - System.out.print("> "); - - line = br.readLine(); - if (line == null) { - br.close(); - inputs.remove(0); - istreams.remove(0); - if (inputs.isEmpty()) - return; - } - } while (line == null); - - if (log != null) - log.println("> " + line); - - if (line.length() == 0 || line.charAt(0) == '#') - continue; - - /* Allows cut and paste from other update sessions */ - if (line.charAt(0) == '>') - line = line.substring(1); - - Tokenizer st = new Tokenizer(line); - Tokenizer.Token token = st.get(); - - if (token.isEOL()) - continue; - String operation = token.value; - - if (operation.equals("server")) { - server = st.getString(); - res = new SimpleResolver(server); - token = st.get(); - if (token.isString()) { - String portstr = token.value; - res.setPort(Short.parseShort(portstr)); - } - } - - else if (operation.equals("key")) { - String keyname = st.getString(); - String keydata = st.getString(); - if (res == null) - res = new SimpleResolver(server); - res.setTSIGKey(keyname, keydata); - } - - else if (operation.equals("edns")) { - if (res == null) - res = new SimpleResolver(server); - res.setEDNS(st.getUInt16()); - } - - else if (operation.equals("port")) { - if (res == null) - res = new SimpleResolver(server); - res.setPort(st.getUInt16()); - } - - else if (operation.equals("tcp")) { - if (res == null) - res = new SimpleResolver(server); - res.setTCP(true); - } - - else if (operation.equals("class")) { - short newClass = DClass.value(st.getString()); - if (newClass > 0) - defaultClass = newClass; - else - print("Invalid class " + newClass); - } - - else if (operation.equals("ttl")) - defaultTTL = st.getTTL(); - - else if (operation.equals("origin") || - operation.equals("zone")) - { - zone = st.getName(Name.root); - } - - else if (operation.equals("require")) - doRequire(st); - - else if (operation.equals("prohibit")) - doProhibit(st); - - else if (operation.equals("add")) - doAdd(st); - - else if (operation.equals("delete")) - doDelete(st); - - else if (operation.equals("glue")) - doGlue(st); - - else if (operation.equals("help") || - operation.equals("?")) - { - token = st.get(); - if (token.isString()) - help(token.value); - else - help(null); - } - - else if (operation.equals("echo")) - print(line.substring(4).trim()); - - else if (operation.equals("send")) { - if (res == null) - res = new SimpleResolver(server); - sendUpdate(); - query = new Message(); - query.getHeader().setOpcode(Opcode.UPDATE); - } - - else if (operation.equals("show")) { - print(query); - } - - else if (operation.equals("clear")) { - query = new Message(); - query.getHeader().setOpcode(Opcode.UPDATE); - } - - else if (operation.equals("query")) - doQuery(st); - - else if (operation.equals("quit") || - operation.equals("q")) - { - if (log != null) - log.close(); - Iterator it = inputs.iterator(); - while (it.hasNext()) { - BufferedReader tbr; - tbr = (BufferedReader) it.next(); - tbr.close(); - } - System.exit(0); - } - - else if (operation.equals("file")) - doFile(st, inputs, istreams); - - else if (operation.equals("log")) - doLog(st); - - else if (operation.equals("assert")) { - if (doAssert(st) == false) - return; - } - - else if (operation.equals("sleep")) { - long interval = st.getUInt32(); - try { - Thread.sleep(interval); - } - catch (InterruptedException e) { - } - } - - else if (operation.equals("date")) { - Date now = new Date(); - token = st.get(); - if (token.isString() && - token.value.equals("-ms")) - print(Long.toString(now.getTime())); - else - print(now); - } - - else - print("invalid keyword: " + operation); - } - catch (TextParseException tpe) { - System.out.println(tpe.getMessage()); - } - catch (NullPointerException npe) { - System.out.println("Parse error"); - } - catch (InterruptedIOException iioe) { - System.out.println("Operation timed out"); - } - catch (SocketException se) { - System.out.println("Socket error"); - } - catch (IOException ioe) { - System.out.println(ioe); - } - } -} - -void -sendUpdate() throws IOException { - if (query.getHeader().getCount(Section.UPDATE) == 0) { - print("Empty update message. Ignoring."); - return; - } - if (query.getHeader().getCount(Section.ZONE) == 0) { - Name updzone; - updzone = zone; - short dclass = defaultClass; - if (updzone == null) { - Record [] recs = query.getSectionArray(Section.UPDATE); - for (int i = 0; i < recs.length; i++) { - if (updzone == null) - updzone = new Name(recs[i].getName(), - 1); - if (recs[i].getDClass() != DClass.NONE && - recs[i].getDClass() != DClass.ANY) - { - dclass = recs[i].getDClass(); - break; - } - } - } - Record soa = Record.newRecord(updzone, Type.SOA, dclass); - query.addRecord(soa, Section.ZONE); - } - - response = res.send(query); - if (response == null) - return; - - print(response); -} - -/* - * [ttl] [class] - * Ignore the class, if present. - */ -Record -parseRR(Tokenizer st, short classValue, int TTLValue) -throws IOException -{ - Name name = st.getName(zone); - int ttl; - short type; - Record record; - - String s = st.getString(); - - try { - ttl = TTL.parseTTL(s); - s = st.getString(); - } - catch (NumberFormatException e) { - ttl = TTLValue; - } - - if (DClass.value(s) >= 0) { - classValue = DClass.value(s); - s = st.getString(); - } - - if ((type = Type.value(s)) < 0) - throw new IOException("Invalid type: " + s); - - record = Record.fromString(name, type, classValue, ttl, st, zone); - if (record != null) - return (record); - else - throw new IOException("Parse error"); -} - -void -doRequire(Tokenizer st) throws IOException { - Tokenizer.Token token; - Name name; - Record record; - short type; - short dclass; - - name = st.getName(zone); - token = st.get(); - if (token.isString()) { - if ((type = Type.value(token.value)) < 0) - throw new IOException("Invalid type: " + token.value); - token = st.get(); - boolean iseol = token.isEOL(); - st.unget(); - if (!iseol) { - record = Record.fromString(name, type, defaultClass, - 0, st, zone); - } else - record = Record.newRecord(name, type, DClass.ANY, 0); - } else - record = Record.newRecord(name, Type.ANY, DClass.ANY, 0); - - query.addRecord(record, Section.PREREQ); - print(record); -} - -void -doProhibit(Tokenizer st) throws IOException { - Tokenizer.Token token; - String s; - Name name; - Record record; - short type; - - name = st.getName(zone); - token = st.get(); - if (token.isString()) { - if ((type = Type.value(token.value)) < 0) - throw new IOException("Invalid type: " + token.value); - } else - type = Type.ANY; - record = Record.newRecord(name, type, DClass.NONE, 0); - query.addRecord(record, Section.PREREQ); - print(record); -} - -void -doAdd(Tokenizer st) throws IOException { - Record record = parseRR(st, defaultClass, defaultTTL); - query.addRecord(record, Section.UPDATE); - print(record); -} - -void -doDelete(Tokenizer st) throws IOException { - Tokenizer.Token token; - String s; - Name name; - Record record; - short type; - short dclass; - - name = st.getName(zone); - token = st.get(); - if (token.isString()) { - s = token.value; - if ((dclass = DClass.value(s)) >= 0) { - s = st.getString(); - } - if ((type = Type.value(s)) < 0) - throw new IOException("Invalid type: " + s); - token = st.get(); - boolean iseol = token.isEOL(); - st.unget(); - if (!iseol) { - record = Record.fromString(name, type, DClass.NONE, - 0, st, zone); - } else - record = Record.newRecord(name, type, DClass.ANY, 0); - } - else - record = Record.newRecord(name, Type.ANY, DClass.ANY, 0); - - query.addRecord(record, Section.UPDATE); - print(record); -} - -void -doGlue(Tokenizer st) throws IOException { - Record record = parseRR(st, defaultClass, defaultTTL); - query.addRecord(record, Section.ADDITIONAL); - print(record); -} - -void -doQuery(Tokenizer st) throws IOException { - Record rec; - Tokenizer.Token token; - - Name name = null; - short type = Type.A, dclass = defaultClass; - - name = st.getName(zone); - token = st.get(); - if (token.isString()) { - type = Type.value(token.value); - if (type < 0) - throw new IOException("Invalid type"); - token = st.get(); - if (token.isString()) { - dclass = DClass.value(token.value); - if (dclass < 0) - throw new IOException("Invalid class"); - } - } - - rec = Record.newRecord(name, type, dclass); - Message newQuery = Message.newQuery(rec); - if (res == null) - res = new SimpleResolver(server); - response = res.send(newQuery); - print(response); -} - -void -doFile(Tokenizer st, List inputs, List istreams) throws IOException { - String s = st.getString(); - InputStream is; - try { - if (s.equals("-")) - is = System.in; - else - is = new FileInputStream(s); - istreams.add(0, is); - inputs.add(new BufferedReader(new InputStreamReader(is))); - } - catch (FileNotFoundException e) { - print(s + " not found"); - } -} - -void -doLog(Tokenizer st) throws IOException { - String s = st.getString(); - try { - FileOutputStream fos = new FileOutputStream(s); - log = new PrintStream(fos); - } - catch (Exception e) { - print("Error opening " + s); - } -} - -boolean -doAssert(Tokenizer st) throws IOException { - String field = st.getString(); - String expected = st.getString(); - String value = null; - boolean flag = true; - int section; - - if (response == null) { - print("No response has been received"); - return true; - } - if (field.equalsIgnoreCase("rcode")) { - short rcode = response.getHeader().getRcode(); - if (rcode != Rcode.value(expected)) { - value = Rcode.string(rcode); - flag = false; - } - } - else if (field.equalsIgnoreCase("serial")) { - Record [] answers = response.getSectionArray(Section.ANSWER); - if (answers.length < 1 || !(answers[0] instanceof SOARecord)) - print("Invalid response (no SOA)"); - else { - SOARecord soa = (SOARecord) answers[0]; - int serial = soa.getSerial(); - if (serial != Integer.parseInt(expected)) { - value = new Integer(serial).toString(); - flag = false; - } - } - } - else if (field.equalsIgnoreCase("tsig")) { - if (response.isSigned()) { - if (response.isVerified()) - value = "ok"; - else - value = "failed"; - } - else - value = "unsigned"; - if (!value.equalsIgnoreCase(expected)) - flag = false; - } - else if ((section = Section.value(field)) >= 0) { - int count = response.getHeader().getCount(section); - if (count != Integer.parseInt(expected)) { - value = new Integer(count).toString(); - flag = false; - } - } - else - print("Invalid assertion keyword: " + field); - - if (flag == false) { - print("Expected " + field + " " + expected + - ", received " + value); - while (true) { - Tokenizer.Token token = st.get(); - if (!token.isString()) - break; - print(token.value); - } - st.unget(); - } - return flag; -} - -static void -help(String topic) { - System.out.println(); - if (topic == null) - System.out.println("The following are supported commands:\n" + - "add assert class clear date delete\n" + - "echo file glue help log key\n" + - "edns origin port prohibit query quit\n" + - "require send server show sleep tcp\n" + - "ttl zone #\n"); - - else if (topic.equalsIgnoreCase("add")) - System.out.println( - "add [ttl] [class] \n\n" + - "specify a record to be added\n"); - else if (topic.equalsIgnoreCase("assert")) - System.out.println( - "assert [msg]\n\n" + - "asserts that the value of the field in the last\n" + - "response matches the value specified. If not,\n" + - "the message is printed (if present) and the\n" + - "program exits. The field may be any of ,\n" + - ", , , , , or .\n"); - else if (topic.equalsIgnoreCase("class")) - System.out.println( - "class \n\n" + - "class of the zone to be updated (default: IN)\n"); - else if (topic.equalsIgnoreCase("clear")) - System.out.println( - "clear\n\n" + - "clears the current update packet\n"); - else if (topic.equalsIgnoreCase("date")) - System.out.println( - "date [-ms]\n\n" + - "prints the current date and time in human readable\n" + - "format or as the number of milliseconds since the\n" + - "epoch"); - else if (topic.equalsIgnoreCase("delete")) - System.out.println( - "delete [ttl] [class] \n" + - "delete \n" + - "delete \n\n" + - "specify a record or set to be deleted, or that\n" + - "all records at a name should be deleted\n"); - else if (topic.equalsIgnoreCase("echo")) - System.out.println( - "echo \n\n" + - "prints the text\n"); - else if (topic.equalsIgnoreCase("file")) - System.out.println( - "file \n\n" + - "opens the specified file as the new input source\n" + - "(- represents stdin)\n"); - else if (topic.equalsIgnoreCase("glue")) - System.out.println( - "glue [ttl] [class] \n\n" + - "specify an additional record\n"); - else if (topic.equalsIgnoreCase("help")) - System.out.println( - "?/help\n" + - "help [topic]\n\n" + - "prints a list of commands or help about a specific\n" + - "command\n"); - else if (topic.equalsIgnoreCase("log")) - System.out.println( - "log \n\n" + - "opens the specified file and uses it to log output\n"); - else if (topic.equalsIgnoreCase("key")) - System.out.println( - "key \n\n" + - "TSIG key used to sign messages\n"); - else if (topic.equalsIgnoreCase("edns")) - System.out.println( - "edns \n\n" + - "EDNS level specified when sending messages\n"); - else if (topic.equalsIgnoreCase("origin")) - System.out.println( - "origin \n\n" + - "\n"); - else if (topic.equalsIgnoreCase("port")) - System.out.println( - "port \n\n" + - "UDP/TCP port messages are sent to (default: 53)\n"); - else if (topic.equalsIgnoreCase("prohibit")) - System.out.println( - "prohibit \n" + - "prohibit \n\n" + - "require that a set or name is not present\n"); - else if (topic.equalsIgnoreCase("query")) - System.out.println( - "query [type [class]] \n\n" + - "issues a query\n"); - else if (topic.equalsIgnoreCase("q") || - topic.equalsIgnoreCase("quit")) - System.out.println( - "q/quit\n\n" + - "quits the program\n"); - else if (topic.equalsIgnoreCase("require")) - System.out.println( - "require [ttl] [class] \n" + - "require \n" + - "require \n\n" + - "require that a record, set, or name is present\n"); - else if (topic.equalsIgnoreCase("send")) - System.out.println( - "send\n\n" + - "sends and resets the current update packet\n"); - else if (topic.equalsIgnoreCase("server")) - System.out.println( - "server [port]\n\n" + - "server that receives send updates/queries\n"); - else if (topic.equalsIgnoreCase("show")) - System.out.println( - "show\n\n" + - "shows the current update packet\n"); - else if (topic.equalsIgnoreCase("sleep")) - System.out.println( - "sleep \n\n" + - "pause for interval before next command\n"); - else if (topic.equalsIgnoreCase("tcp")) - System.out.println( - "tcp\n\n" + - "TCP should be used to send all messages\n"); - else if (topic.equalsIgnoreCase("ttl")) - System.out.println( - "ttl \n\n" + - "default ttl of added records (default: 0)\n"); - else if (topic.equalsIgnoreCase("zone")) - System.out.println( - "zone \n\n" + - "zone to update (default: .\n"); - else if (topic.equalsIgnoreCase("#")) - System.out.println( - "# \n\n" + - "a comment\n"); - else - System.out.println ("Topic '" + topic + "' unrecognized\n"); -} - -public static void -main(String args[]) throws IOException { - - InputStream in = null; - if (args.length == 1) { - try { - in = new FileInputStream(args[0]); - } - catch (FileNotFoundException e) { - System.out.println(args[0] + " not found."); - System.exit(-1); - } - } - else - in = System.in; - update u = new update(in); -} - -} diff --git a/java/oldies/update_1.70_1.71_v1.java b/java/oldies/update_1.70_1.71_v1.java deleted file mode 100644 index dee2fb6..0000000 --- a/java/oldies/update_1.70_1.71_v1.java +++ /dev/null @@ -1,697 +0,0 @@ -// Copyright (c) 1999 Brian Wellington (bwelling@xbill.org) -// Portions Copyright (c) 1999 Network Associates, Inc. - -import java.net.*; -import java.io.*; -import java.util.*; -import org.xbill.DNS.*; -import org.xbill.DNS.utils.*; - -/** @author Brian Wellington <bwelling@xbill.org> */ - -public class update { - -Message query, response; -Resolver res; -String server = null; -Name zone = Name.root; -int defaultTTL; -short defaultClass = DClass.IN; -PrintStream log = null; - -void -print(Object o) { - System.out.println(o); - if (log != null) - log.println(o); -} - -public -update(InputStream in) throws IOException { - List inputs = new LinkedList(); - List istreams = new LinkedList(); - - query = new Message(); - query.getHeader().setOpcode(Opcode.UPDATE); - - InputStreamReader isr = new InputStreamReader(in); - BufferedReader br = new BufferedReader(isr); - - inputs.add(br); - istreams.add(in); - - while (true) { - try { - String line = null; - do { - InputStream is; - is = (InputStream)istreams.get(0); - br = (BufferedReader)inputs.get(0); - - if (is == System.in) - System.out.print("> "); - - line = br.readLine(); - if (line == null) { - br.close(); - inputs.remove(0); - istreams.remove(0); - if (inputs.isEmpty()) - return; - } - } while (line == null); - - if (log != null) - log.println("> " + line); - - if (line.length() == 0 || line.charAt(0) == '#') - continue; - - /* Allows cut and paste from other update sessions */ - if (line.charAt(0) == '>') - line = line.substring(1); - - Tokenizer st = new Tokenizer(line); - Tokenizer.Token token = st.get(); - - if (token.isEOL()) - continue; - String operation = token.value; - - if (operation.equals("server")) { - server = st.getString(); - res = new SimpleResolver(server); - token = st.get(); - if (token.isString()) { - String portstr = token.value; - res.setPort(Short.parseShort(portstr)); - } - } - - else if (operation.equals("key")) { - String keyname = st.getString(); - String keydata = st.getString(); - if (res == null) - res = new SimpleResolver(server); - res.setTSIGKey(keyname, keydata); - } - - else if (operation.equals("edns")) { - if (res == null) - res = new SimpleResolver(server); - res.setEDNS(st.getUInt16()); - } - - else if (operation.equals("port")) { - if (res == null) - res = new SimpleResolver(server); - res.setPort(st.getUInt16()); - } - - else if (operation.equals("tcp")) { - if (res == null) - res = new SimpleResolver(server); - res.setTCP(true); - } - - else if (operation.equals("class")) { - short newClass = DClass.value(st.getString()); - if (newClass > 0) - defaultClass = newClass; - else - print("Invalid class " + newClass); - } - - else if (operation.equals("ttl")) - defaultTTL = st.getTTL(); - - else if (operation.equals("origin") || - operation.equals("zone")) - { - zone = st.getName(Name.root); - } - - else if (operation.equals("require")) - doRequire(st); - - else if (operation.equals("prohibit")) - doProhibit(st); - - else if (operation.equals("add")) - doAdd(st); - - else if (operation.equals("delete")) - doDelete(st); - - else if (operation.equals("glue")) - doGlue(st); - - else if (operation.equals("help") || - operation.equals("?")) - { - token = st.get(); - if (token.isString()) - help(token.value); - else - help(null); - } - - else if (operation.equals("echo")) - print(line.substring(4).trim()); - - else if (operation.equals("send")) { - sendUpdate(); - query = new Message(); - query.getHeader().setOpcode(Opcode.UPDATE); - } - - else if (operation.equals("show")) { - print(query); - } - - else if (operation.equals("clear")) { - query = new Message(); - query.getHeader().setOpcode(Opcode.UPDATE); - } - - else if (operation.equals("query")) - doQuery(st); - - else if (operation.equals("quit") || - operation.equals("q")) - { - if (log != null) - log.close(); - Iterator it = inputs.iterator(); - while (it.hasNext()) { - BufferedReader tbr; - tbr = (BufferedReader) it.next(); - tbr.close(); - } - System.exit(0); - } - - else if (operation.equals("file")) - doFile(st, inputs, istreams); - - else if (operation.equals("log")) - doLog(st); - - else if (operation.equals("assert")) { - if (doAssert(st) == false) - return; - } - - else if (operation.equals("sleep")) { - long interval = st.getUInt32(); - try { - Thread.sleep(interval); - } - catch (InterruptedException e) { - } - } - - else if (operation.equals("date")) { - Date now = new Date(); - token = st.get(); - if (token.isString() && - token.value.equals("-ms")) - print(Long.toString(now.getTime())); - else - print(now); - } - - else - print("invalid keyword: " + operation); - } - catch (TextParseException tpe) { - System.out.println(tpe.getMessage()); - } - catch (NullPointerException npe) { - System.out.println("Parse error"); - } - catch (InterruptedIOException iioe) { - System.out.println("Operation timed out"); - } - catch (SocketException se) { - System.out.println("Socket error"); - } - catch (IOException ioe) { - System.out.println(ioe); - } - } -} - -void -sendUpdate() throws IOException { - if (query.getHeader().getCount(Section.UPDATE) == 0) { - print("Empty update message. Ignoring."); - return; - } - if (query.getHeader().getCount(Section.ZONE) == 0) { - Name updzone; - updzone = zone; - short dclass = defaultClass; - if (updzone == null) { - Record [] recs = query.getSectionArray(Section.UPDATE); - for (int i = 0; i < recs.length; i++) { - if (updzone == null) - updzone = new Name(recs[i].getName(), - 1); - if (recs[i].getDClass() != DClass.NONE && - recs[i].getDClass() != DClass.ANY) - { - dclass = recs[i].getDClass(); - break; - } - } - } - Record soa = Record.newRecord(updzone, Type.SOA, dclass); - query.addRecord(soa, Section.ZONE); - } - - if (res == null) - res = new SimpleResolver(server); - response = res.send(query); - print(response); -} - -/* - * [ttl] [class] - * Ignore the class, if present. - */ -Record -parseRR(Tokenizer st, short classValue, int TTLValue) -throws IOException -{ - Name name = st.getName(zone); - int ttl; - short type; - Record record; - - String s = st.getString(); - - try { - ttl = TTL.parseTTL(s); - s = st.getString(); - } - catch (NumberFormatException e) { - ttl = TTLValue; - } - - if (DClass.value(s) >= 0) { - classValue = DClass.value(s); - s = st.getString(); - } - - if ((type = Type.value(s)) < 0) - throw new IOException("Invalid type: " + s); - - record = Record.fromString(name, type, classValue, ttl, st, zone); - if (record != null) - return (record); - else - throw new IOException("Parse error"); -} - -void -doRequire(Tokenizer st) throws IOException { - Tokenizer.Token token; - Name name; - Record record; - short type; - short dclass; - - name = st.getName(zone); - token = st.get(); - if (token.isString()) { - if ((type = Type.value(token.value)) < 0) - throw new IOException("Invalid type: " + token.value); - token = st.get(); - boolean iseol = token.isEOL(); - st.unget(); - if (!iseol) { - record = Record.fromString(name, type, defaultClass, - 0, st, zone); - } else - record = Record.newRecord(name, type, DClass.ANY, 0); - } else - record = Record.newRecord(name, Type.ANY, DClass.ANY, 0); - - query.addRecord(record, Section.PREREQ); - print(record); -} - -void -doProhibit(Tokenizer st) throws IOException { - Tokenizer.Token token; - String s; - Name name; - Record record; - short type; - - name = st.getName(zone); - token = st.get(); - if (token.isString()) { - if ((type = Type.value(token.value)) < 0) - throw new IOException("Invalid type: " + token.value); - } else - type = Type.ANY; - record = Record.newRecord(name, type, DClass.NONE, 0); - query.addRecord(record, Section.PREREQ); - print(record); -} - -void -doAdd(Tokenizer st) throws IOException { - Record record = parseRR(st, defaultClass, defaultTTL); - query.addRecord(record, Section.UPDATE); - print(record); -} - -void -doDelete(Tokenizer st) throws IOException { - Tokenizer.Token token; - String s; - Name name; - Record record; - short type; - short dclass; - - name = st.getName(zone); - token = st.get(); - if (token.isString()) { - s = token.value; - if ((dclass = DClass.value(s)) >= 0) { - s = st.getString(); - } - if ((type = Type.value(s)) < 0) - throw new IOException("Invalid type: " + s); - token = st.get(); - boolean iseol = token.isEOL(); - st.unget(); - if (!iseol) { - record = Record.fromString(name, type, DClass.NONE, - 0, st, zone); - } else - record = Record.newRecord(name, type, DClass.ANY, 0); - } - else - record = Record.newRecord(name, Type.ANY, DClass.ANY, 0); - - query.addRecord(record, Section.UPDATE); - print(record); -} - -void -doGlue(Tokenizer st) throws IOException { - Record record = parseRR(st, defaultClass, defaultTTL); - query.addRecord(record, Section.ADDITIONAL); - print(record); -} - -void -doQuery(Tokenizer st) throws IOException { - Record rec; - Tokenizer.Token token; - - Name name = null; - short type = Type.A, dclass = defaultClass; - - name = st.getName(zone); - token = st.get(); - if (token.isString()) { - type = Type.value(token.value); - if (type < 0) - throw new IOException("Invalid type"); - token = st.get(); - if (token.isString()) { - dclass = DClass.value(token.value); - if (dclass < 0) - throw new IOException("Invalid class"); - } - } - - rec = Record.newRecord(name, type, dclass); - Message newQuery = Message.newQuery(rec); - if (res == null) - res = new SimpleResolver(server); - response = res.send(newQuery); - print(response); -} - -void -doFile(Tokenizer st, List inputs, List istreams) throws IOException { - String s = st.getString(); - InputStream is; - try { - if (s.equals("-")) - is = System.in; - else - is = new FileInputStream(s); - istreams.add(0, is); - inputs.add(new BufferedReader(new InputStreamReader(is))); - } - catch (FileNotFoundException e) { - print(s + " not found"); - } -} - -void -doLog(Tokenizer st) throws IOException { - String s = st.getString(); - try { - FileOutputStream fos = new FileOutputStream(s); - log = new PrintStream(fos); - } - catch (Exception e) { - print("Error opening " + s); - } -} - -boolean -doAssert(Tokenizer st) throws IOException { - String field = st.getString(); - String expected = st.getString(); - String value = null; - boolean flag = true; - int section; - - if (response == null) { - print("No response has been received"); - return true; - } - if (field.equalsIgnoreCase("rcode")) { - short rcode = response.getHeader().getRcode(); - if (rcode != Rcode.value(expected)) { - value = Rcode.string(rcode); - flag = false; - } - } - else if (field.equalsIgnoreCase("serial")) { - Record [] answers = response.getSectionArray(Section.ANSWER); - if (answers.length < 1 || !(answers[0] instanceof SOARecord)) - print("Invalid response (no SOA)"); - else { - SOARecord soa = (SOARecord) answers[0]; - int serial = soa.getSerial(); - if (serial != Integer.parseInt(expected)) { - value = new Integer(serial).toString(); - flag = false; - } - } - } - else if (field.equalsIgnoreCase("tsig")) { - if (response.isSigned()) { - if (response.isVerified()) - value = "ok"; - else - value = "failed"; - } - else - value = "unsigned"; - if (!value.equalsIgnoreCase(expected)) - flag = false; - } - else if ((section = Section.value(field)) >= 0) { - int count = response.getHeader().getCount(section); - if (count != Integer.parseInt(expected)) { - value = new Integer(count).toString(); - flag = false; - } - } - else - print("Invalid assertion keyword: " + field); - - if (flag == false) { - print("Expected " + field + " " + expected + - ", received " + value); - while (true) { - Tokenizer.Token token = st.get(); - if (!token.isString()) - break; - print(token.value); - } - st.unget(); - } - return flag; -} - -static void -help(String topic) { - System.out.println(); - if (topic == null) - System.out.println("The following are supported commands:\n" + - "add assert class clear date delete\n" + - "echo file glue help log key\n" + - "edns origin port prohibit query quit\n" + - "require send server show sleep tcp\n" + - "ttl zone #\n"); - - else if (topic.equalsIgnoreCase("add")) - System.out.println( - "add [ttl] [class] \n\n" + - "specify a record to be added\n"); - else if (topic.equalsIgnoreCase("assert")) - System.out.println( - "assert [msg]\n\n" + - "asserts that the value of the field in the last\n" + - "response matches the value specified. If not,\n" + - "the message is printed (if present) and the\n" + - "program exits. The field may be any of ,\n" + - ", , , , , or .\n"); - else if (topic.equalsIgnoreCase("class")) - System.out.println( - "class \n\n" + - "class of the zone to be updated (default: IN)\n"); - else if (topic.equalsIgnoreCase("clear")) - System.out.println( - "clear\n\n" + - "clears the current update packet\n"); - else if (topic.equalsIgnoreCase("date")) - System.out.println( - "date [-ms]\n\n" + - "prints the current date and time in human readable\n" + - "format or as the number of milliseconds since the\n" + - "epoch"); - else if (topic.equalsIgnoreCase("delete")) - System.out.println( - "delete [ttl] [class] \n" + - "delete \n" + - "delete \n\n" + - "specify a record or set to be deleted, or that\n" + - "all records at a name should be deleted\n"); - else if (topic.equalsIgnoreCase("echo")) - System.out.println( - "echo \n\n" + - "prints the text\n"); - else if (topic.equalsIgnoreCase("file")) - System.out.println( - "file \n\n" + - "opens the specified file as the new input source\n" + - "(- represents stdin)\n"); - else if (topic.equalsIgnoreCase("glue")) - System.out.println( - "glue [ttl] [class] \n\n" + - "specify an additional record\n"); - else if (topic.equalsIgnoreCase("help")) - System.out.println( - "?/help\n" + - "help [topic]\n\n" + - "prints a list of commands or help about a specific\n" + - "command\n"); - else if (topic.equalsIgnoreCase("log")) - System.out.println( - "log \n\n" + - "opens the specified file and uses it to log output\n"); - else if (topic.equalsIgnoreCase("key")) - System.out.println( - "key \n\n" + - "TSIG key used to sign messages\n"); - else if (topic.equalsIgnoreCase("edns")) - System.out.println( - "edns \n\n" + - "EDNS level specified when sending messages\n"); - else if (topic.equalsIgnoreCase("origin")) - System.out.println( - "origin \n\n" + - "\n"); - else if (topic.equalsIgnoreCase("port")) - System.out.println( - "port \n\n" + - "UDP/TCP port messages are sent to (default: 53)\n"); - else if (topic.equalsIgnoreCase("prohibit")) - System.out.println( - "prohibit \n" + - "prohibit \n\n" + - "require that a set or name is not present\n"); - else if (topic.equalsIgnoreCase("query")) - System.out.println( - "query [type [class]] \n\n" + - "issues a query\n"); - else if (topic.equalsIgnoreCase("q") || - topic.equalsIgnoreCase("quit")) - System.out.println( - "q/quit\n\n" + - "quits the program\n"); - else if (topic.equalsIgnoreCase("require")) - System.out.println( - "require [ttl] [class] \n" + - "require \n" + - "require \n\n" + - "require that a record, set, or name is present\n"); - else if (topic.equalsIgnoreCase("send")) - System.out.println( - "send\n\n" + - "sends and resets the current update packet\n"); - else if (topic.equalsIgnoreCase("server")) - System.out.println( - "server [port]\n\n" + - "server that receives send updates/queries\n"); - else if (topic.equalsIgnoreCase("show")) - System.out.println( - "show\n\n" + - "shows the current update packet\n"); - else if (topic.equalsIgnoreCase("sleep")) - System.out.println( - "sleep \n\n" + - "pause for interval before next command\n"); - else if (topic.equalsIgnoreCase("tcp")) - System.out.println( - "tcp\n\n" + - "TCP should be used to send all messages\n"); - else if (topic.equalsIgnoreCase("ttl")) - System.out.println( - "ttl \n\n" + - "default ttl of added records (default: 0)\n"); - else if (topic.equalsIgnoreCase("zone")) - System.out.println( - "zone \n\n" + - "zone to update (default: .\n"); - else if (topic.equalsIgnoreCase("#")) - System.out.println( - "# \n\n" + - "a comment\n"); - else - System.out.println ("Topic '" + topic + "' unrecognized\n"); -} - -public static void -main(String args[]) throws IOException { - - InputStream in = null; - if (args.length >= 1) { - try { - in = new FileInputStream(args[0]); - } - catch (FileNotFoundException e) { - System.out.println(args[0] + " not found."); - System.exit(1); - } - } - else - in = System.in; - update u = new update(in); -} - -} diff --git a/java/simple/AnnotationsTest.java b/java/simple/AnnotationsTest.java deleted file mode 100644 index 4f68927..0000000 --- a/java/simple/AnnotationsTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package fr.labri.gumtree.client.batch; - -import static org.junit.Assert.*; - -import org.junit.Test; - -public class AnnotationsTest { - @Test - public void testOne() throws Exception { - assertEquals(1,2); - } - - @Test - public void testTwo() throws Exception { - assertEquals(1,2); - assertTrue(true); - } -} diff --git a/java/spl/notepad/Variant00001java/About.java b/java/spl/notepad/Variant00001java/About.java deleted file mode 100644 index fb751fd..0000000 --- a/java/spl/notepad/Variant00001java/About.java +++ /dev/null @@ -1,25 +0,0 @@ -import javax.swing.*; - -/** - *A CLASS FOR CREATING ABOUT PANEL - */ -public class About extends JPanel { - - private static final long serialVersionUID = 1; - - - public About(){ - //Create a Label & an image icon in it - JLabel label1 = new JLabel(new ImageIcon(this.getClass().getResource("images/java.gif"))); - //adding label1 to the JPanel - this.add(label1); - //Create a Label & put a HTML script - JLabel label2 = new JLabel("
  • JAVA??? Notepad
  • Ver# 2.0

  • " - +"
  • Coded by: Salah Al-Thubaiti

  • KFUPM, CS

  • " - +"

    CopyRight??? 2001-2002

  • "); - //adding label2 to the JPanel - this.add(label2); - } - - -} diff --git a/java/spl/notepad/Variant00001java/Actions.java b/java/spl/notepad/Variant00001java/Actions.java deleted file mode 100644 index 7d7fc2a..0000000 --- a/java/spl/notepad/Variant00001java/Actions.java +++ /dev/null @@ -1,468 +0,0 @@ -import java.io.*; -import java.util.*; -import java.awt.event.*; -import javax.swing.*; - -/** - *A PUBLIC CLASS FOR ACTIONS.JAVA - */ -public class Actions { - - //declaration of the private variables used in the program - private int returnVal; - - //for JFileChooser - private int option; - - //for using it into JOptionPane - private String fileContent = null; - - //to get the text from the text area - private String fileName = null; - - //for using the name of the file - private JFileChooser jfc = new JFileChooser("."); - - //for using a open & save dialog - private ExampleFileFilter filter = new ExampleFileFilter(); - - //for filtering the file - Notepad n; - - //for using the object in the Notepad.java - public Fonts font = new Fonts(); - - - - public Actions(Notepad n){ - this.n = n; - } - - - /** - *If we want to write a new text, first we want to know if the text area is empty or not, - *second we want to know if the text was saved or not. - *If the text area isn't empty & the text wasn't saved before this time, then the program display -> - *for the user an option for saving the text in a new file or in the same file - */ - public void neW(){ - /** - *if the text area isn't empty & if the text area hasn't - *a text not saved before (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - /** - *here, we have two things, first if the text wasn't be opened or saved before - *second if the text was be opened or saved - */ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - //if the user click on YES button, - //then the program will save the text & make a new text area - if(option == 0){ - //to save the text into a new file - saveAs(); - //to create new getTextArea() after saving the old getTextArea() - n.getTextArea().setText(""); - } - //if the user click on NO button - if(option == 1){ - //to create new getTextArea() without saving the old getTextArea() - n.getTextArea().setText(""); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will save the text into the old file & - *make a new text area,,, - */ - if(option == 0){ - save(); - //to create new getTextArea() after saving the old getTextArea() - n.getTextArea().setText(""); - } - //if the user click on NO button - if(option == 1){ - //to create new getTextArea() without saving the old getTextArea() - n.getTextArea().setText(""); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to write a new text,,, this option will be actived - */ - else{ - n.getTextArea().setText(""); - } - n.setTitle("Untitled - JAVA??? Notepad"); - } - - - /** - *If we want to open a new text, first we want to know if the text area - * is empty or not, second we want to kwnow if the text was saved or not. - *If the text area isn't empty & the text wasn't saved befor this time, - *then the program display for the user an option for saving the text - *in a new file or in the same file - */ - public void opeN(){ - /** - *if the text area isn't empty & if the text area hasn't a text which - *not saved befor (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - /** - *here, we have 2 thing, first if the text wasn't be opened or saved befor - *second if the text was be opened or saved - */ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - //if the user click on YES button, - //then the program will be saved the text & opened a new documents - if(option == 0){ - //for saving the text in a new file - saveAs(); - //for opening the new documents - open(); - } - /** - *if the user click on NO button, - *the program will be opened the new documents - */ - if(option == 1){ - //for opening the new documents - open(); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will save the text into the same file & - *open the new documents - */ - if(option == 0){ - //for saving the text into the same file - save(); - //for opening the new documents - open(); - } - /** - *if the user click on NO button, - *the program will be opened the new documents - */ - if(option == 1){ - //for opening the new documents - open(); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to open a new document,,, this option will be actived - */ - else{ - //for opening the new documents - open(); - } - } - - - /** - *THIS IS FOR SAVE ACTION, SaveAs ACTION has saveAs() method - *If we want to save a new text, then we want to know - *if the text was saved befor or not. - *If the text wasn't be saved befor, then we will use saveAs() - *If the text was be save befor, then we will use save() - */ - public void savE(){ - /** - *if String fileName is null, then using saveAs(). - *Because there was no file was be saved - */ - if(fileName == null){ - saveAs(); - } - /** - *if String fileName has a String (file name), then using save(). - *Because we want to save the new text in the same file. - *if the user want to save the all text (old & new text) in a new file, -> - *he can presses SaveAs button (@saveAs()) - */ - else{ - save(); - } - } - - - /** - *THIS FROM SUN??? WEBSITE (@Print.java) - *if we want to print the text, we can do this by print method - */ - public void prinT(){ - //import printer class - Print.printComponent(n.getTextArea()); - } - - - /** - *If we want to exit from the program, - *first we want to know if the text area is empty or not, - *second we want to kwnow if the text was saved or not. - *If the text area isn't empty & the text wasn't saved befor this time, - *then the program display -> - *for the user an option for saving the text in a new file or in the same file - */ - public void exiT(){ - /** - *if the text area isn't empty & if the text area hasn't a text which - *not saved befor (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will be saved the text & close the program - */ - if(option == 0){ - //for saving the text into new file - saveAs(); - //for closing the program - System.exit(0); - } - /** - *if the user click on NO button, - *then the program will be closed without save the text - */ - if(option == 1){ - //for closing the program - System.exit(0); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will be saved the text & close the program - */ - if(option == 0){ - //for saving the text into the same file - save(); - //for closing the program - System.exit(0); - } - /** - *if the user click on NO button, - *then the program will be closed without save the text - */ - if(option == 1){ - //for closing the program - System.exit(0); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to close the program. This option will be actived - */ - else{ - //for closing the program - System.exit(0); - } - } - - - //to select all the text - public void selectALL(){ - n.getTextArea().selectAll(); - } - - - //for wraping the line & wraping the style word - public void lineWraP(){ - if(n.getLineWrap().isSelected()){ - /** - *make the line wrap & wrap style word is true - *when the line wrap is selected - */ - n.getTextArea().setLineWrap(true); - n.getTextArea().setWrapStyleWord(true); - } - else{ - /** - *make the line wrap & wrap style word is false - *when the line wrap isn't selected - */ - n.getTextArea().setLineWrap(false); - n.getTextArea().setWrapStyleWord(false); - } - } - - - /** - *@see FONTS.JAVA - *this is a font class which is for changing the font, style & size - */ - public void fonT(){ - font.setVisible(true); //setting the visible is true - font.pack(); //pack the panel - //making an action for ok button, so we can change the font - font.getOkjb().addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - n.getTextArea().setFont(font.font()); - //after we chose the font, then the JDialog will be closed - font.setVisible(false); - } - }); - //making an action for cancel button, so we can return to the old font. - font.getCajb().addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - //after we cancel the, then the JDialog will be closed - font.setVisible(false); - } - }); - } - - - /** - *@see ABOUT.JAVA - *it's a Message Dialog to show the information about this program - */ - public void abouT(){ - JOptionPane.showMessageDialog(null, new About(),"About Notepad",JOptionPane.PLAIN_MESSAGE); - } - - - /** - *THIS IS THE WAY FOR OPENING THE TEXT FILE - */ - public void open(){ - //filter the kind of files, we want only TXT file - filter.addExtension("txt"); - //to set a description for the file (TXT) - filter.setDescription("TXT Documents"); - //setting the FileFilter to JFileChooser - jfc.setFileFilter(filter); - returnVal = jfc.showOpenDialog(n); //to show JFileChooser - if(returnVal == JFileChooser.APPROVE_OPTION){ - //to erase any text in the text area before adding new text - n.getTextArea().setText(null); - try{ - //to get the name of the selected file - fileName = jfc.getSelectedFile().getPath(); - //to read the selected file - Reader in = new FileReader(jfc.getSelectedFile()); - //100000 is the max. char can be written in the text area - char[] buff = new char[100000]; - int nch; - while((nch = in.read(buff, 0, buff.length)) != -1) - n.getTextArea().append(new String(buff, 0, nch)); - //to get more text from the file if the array wasn't full - fileContent = n.getTextArea().getText(); - } - catch(FileNotFoundException x){} - catch(IOException ioe){ - System.err.println("I/O Error on Open"); - } - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - /** - *THIS IS THE WAY FOR SAVING THE TEXT IN THE SAME FILE - */ - public void save(){ - //initializing 'fout' to write all text in the selected file - try{ - PrintWriter fout = new PrintWriter(new FileWriter(jfc.getSelectedFile())); - //for getting the text from the text area - fileContent = n.getTextArea().getText(); - //using StringTokenizer for the 'fileContent' String - StringTokenizer st=new StringTokenizer(fileContent,System.getProperty("line.separator")); - while(st.hasMoreTokens()){ - //write the string (text) in the selected file - fout.println(st.nextToken()); - } - //closing fout - fout.close(); - } - catch(IOException ioe){ - System.err.println("I/O Error on Save"); - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - /** - *THIS IS THE WAY FOR SAVING THE TEXT IN A NEW FILE - */ - public void saveAs(){ - //filter the kind of files, we want only TXT file - filter.addExtension("txt"); - //to set a description for the file (TXT) - filter.setDescription("TXT Documents"); - //setting the FileFilter to JFileChooser - jfc.setFileFilter(filter); - returnVal = jfc.showSaveDialog(n); - if(returnVal == JFileChooser.APPROVE_OPTION){ - //initializing the PrintWriter, to save the text in a new file - PrintWriter fout = null; - try{ - fout = new PrintWriter(new FileWriter(jfc.getSelectedFile() + ".txt")); - //getting the text from the text area - fileContent = n.getTextArea().getText(); - //getting the name of the selected file - fileName = jfc.getSelectedFile().getPath(); - //using StringTokenizer for the 'fileContent' String - StringTokenizer st=new StringTokenizer(fileContent,System.getProperty("line.separator")); - while(st.hasMoreTokens()){ - //write the string (text) in the selected file - fout.println(st.nextToken()); - } - //closing 'fout' - fout.close(); - } - catch(IOException ioe){ - System.err.println ("I/O Error on Save"); - } - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - -} diff --git a/java/spl/notepad/Variant00001java/Center.java b/java/spl/notepad/Variant00001java/Center.java deleted file mode 100644 index 1715525..0000000 --- a/java/spl/notepad/Variant00001java/Center.java +++ /dev/null @@ -1,37 +0,0 @@ -import java.awt.*; -/** - *A PUBLIC CLASS FOR CENTER.JAVA - */ -public class Center { - - Notepad n; - - //for using the object in the Notepad.java - Fonts f; - - //for using the object in the Fonts.java - public Center(Notepad n){ - this.n = n; - } - - - public Center(Fonts f){ - this.f = f; - } - - - public void nCenter(){ - //Centering the window - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - n.setLocation((screenSize.width-n.getWidth())/2,(screenSize.height-n.getHeight())/2); - } - - - public void fCenter(){ - //Centering the window - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - f.setLocation((screenSize.width-f.getWidth())/2,(screenSize.height-f.getHeight())/2); - } - - -} diff --git a/java/spl/notepad/Variant00001java/ExampleFileFilter.java b/java/spl/notepad/Variant00001java/ExampleFileFilter.java deleted file mode 100644 index 47b0dd6..0000000 --- a/java/spl/notepad/Variant00001java/ExampleFileFilter.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (c) 2002 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * -Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * -Redistribution in binary form must reproduct the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING - * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT - * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT - * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS - * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST - * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, - * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY - * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN - * IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that Software is not designed, licensed or intended for - * use in the design, construction, operation or maintenance of any nuclear - * facility. - */ - -/* - * @(#)ExampleFileFilter.java 1.13 02/06/13 - */ - - - -//import the packages for using the classes in them into the program -import java.io.File; -import java.util.Hashtable; -import java.util.Enumeration; -import javax.swing.filechooser.*; - -/** - * A convenience implementation of FileFilter that filters out - * all files except for those type extensions that it knows about. - * - * Extensions are of the type ".foo", which is typically found on - * Windows and Unix boxes, but not on Macinthosh. Case is ignored. - * - * Example - create a new filter that filerts out all files - * but gif and jpg image files: - * - * JFileChooser chooser = new JFileChooser(); - * ExampleFileFilter filter = new ExampleFileFilter( - * new String{"gif", "jpg"}, "JPEG & GIF Images") - * chooser.addChoosableFileFilter(filter); - * chooser.showOpenDialog(this); - * - * @version 1.13 06/13/02 - * @author Jeff Dinkins - */ -public class ExampleFileFilter extends FileFilter { - - -// private static String TYPE_UNKNOWN = "Type Unknown"; -// private static String HIDDEN_FILE = "Hidden File"; - - private Hashtable filters = null; - - - private String description = null; - - - private String fullDescription = null; - - - private boolean useExtensionsInDescription = true; - - - - /** - * Creates a file filter. If no filters are added, then all - * files are accepted. - * - * @see #addExtension - */ - public ExampleFileFilter(){ - this.filters = new Hashtable(); - } - - - - /** - * Creates a file filter that accepts files with the given extension. - * Example: new ExampleFileFilter("jpg"); - * - * @see #addExtension - */ - public ExampleFileFilter(String extension){ - this(extension,null); - } - - - - /** - * Creates a file filter that accepts the given file type. - * Example: new ExampleFileFilter("jpg", "JPEG Image Images"); - * - * Note that the "." before the extension is not needed. If - * provided, it will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String extension, String description){ - this(); - if(extension!=null) addExtension(extension); - if(description!=null) setDescription(description); - } - - - - /** - * Creates a file filter from the given string array. - * Example: new ExampleFileFilter(String {"gif", "jpg"}); - * - * Note that the "." before the extension is not needed adn - * will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String[] filters){ - this(filters, null); - } - - - - /** - * Creates a file filter from the given string array and description. - * Example: new ExampleFileFilter(String {"gif", "jpg"}, "Gif and JPG Images"); - * - * Note that the "." before the extension is not needed and will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String[] filters, String description){ - this(); - for (int i = 0; i < filters.length; i++){ - // add filters one by one - addExtension(filters[i]); - } - if(description!=null) setDescription(description); - } - - - - /** - * Return true if this file should be shown in the directory pane, - * false if it shouldn't. - * - * Files that begin with "." are ignored. - * - * @see #getExtension - * @see FileFilter#accepts - */ - public boolean accept(File f){ - if(f != null){ - if(f.isDirectory()){ - return true; - } - String extension = getExtension(f); - if(extension != null && filters.get(getExtension(f)) != null){ - return true; - }; - } - return false; - } - - - - /** - * Return the extension portion of the file's name . - * - * @see #getExtension - * @see FileFilter#accept - */ - public String getExtension(File f){ - if(f != null){ - String filename = f.getName(); - int i = filename.lastIndexOf('.'); - if(i>0 && i(5); - } - filters.put(extension.toLowerCase(), this); - fullDescription = null; - } - - - - /** - * Returns the human readable description of this filter. For - * example: "JPEG and GIF Image Files (*.jpg, *.gif)" - * - * @see setDescription - * @see setExtensionListInDescription - * @see isExtensionListInDescription - * @see FileFilter#getDescription - */ - @SuppressWarnings("rawtypes") - public String getDescription(){ - if(fullDescription == null) { - if(description == null || isExtensionListInDescription()){ - fullDescription = description==null ? "(" : description + " ("; - // build the description from the extension list - Enumeration extensions = filters.keys(); - if(extensions != null){ - fullDescription += "." + (String) extensions.nextElement(); - while (extensions.hasMoreElements()) { - fullDescription += ", ." + (String) extensions.nextElement(); - } - } - fullDescription += ")"; - } else { - fullDescription = description; - } - } - return fullDescription; - } - - - - /** - * Sets the human readable description of this filter. For - * example: filter.setDescription("Gif and JPG Images"); - * - * @see setDescription - * @see setExtensionListInDescription - * @see isExtensionListInDescription - */ - public void setDescription(String description){ - this.description = description; - fullDescription = null; - } - - - - /** - * Determines whether the extension list (.jpg, .gif, etc) should - * show up in the human readable description. - * - * Only relevent if a description was provided in the constructor - * or using setDescription(); - * - * @see getDescription - * @see setDescription - * @see isExtensionListInDescription - */ - public void setExtensionListInDescription(boolean b){ - useExtensionsInDescription = b; - fullDescription = null; - } - - - - /** - * Returns whether the extension list (.jpg, .gif, etc) should - * show up in the human readable description. - * - * Only relevent if a description was provided in the constructor - * or using setDescription(); - * - * @see getDescription - * @see setDescription - * @see setExtensionListInDescription - */ - public boolean isExtensionListInDescription(){ - return useExtensionsInDescription; - } - - -} diff --git a/java/spl/notepad/Variant00001java/Fonts.java b/java/spl/notepad/Variant00001java/Fonts.java deleted file mode 100644 index e63be0b..0000000 --- a/java/spl/notepad/Variant00001java/Fonts.java +++ /dev/null @@ -1,136 +0,0 @@ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - -/** - *A class for creating JFontDialog - */ -public class Fonts extends JDialog { - - private static final long serialVersionUID = 1L; - - - /** - *@see Center.java - *this class to make the JDialog in the center - */ - public Center center = new Center(this); - - - - //declaration of the private variables used in the program - private JPanel jp = new JPanel(); - - - private JLabel fjl = new JLabel("Fonts: "); - - - private JComboBox fjcb = new JComboBox(); - - - /** - *-> GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames() <- - * WE USING THIS METHOD TO GET ALL FONT IN THE SYSTEM (OS) - */ - private String fonts[]=GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); - - - private JLabel sjl = new JLabel("Sizes: "); - - - private JComboBox sjcb = new JComboBox(); - - - private String sizes[] = {"8","10","12","14","16","18","20","24","28","32","48","72"}; - - - private JLabel tjl = new JLabel("Types: "); - - - private JComboBox tjcb = new JComboBox(); - - - private String types[] = {"Regular", "Bold", "Italic", "Bold Italic"}; - - - private JLabel jjl = new JLabel("Preview:"); - - - private JLabel jl = new JLabel("AaBaCcDdeEfFgGhHjJ"); - - - private JButton okjb = new JButton("OK"); - - - private JButton cajb = new JButton("Cancel"); - - - //for using ok & cancel button @Actions.java - public JButton getOkjb(){ - return okjb; - } - - - public JButton getCajb(){ - return cajb; - } - - - //Constructor of Fonts - public Fonts(){ - //for setting the title - setTitle("Font Dialog"); - setResizable(false); - /** - *setting the layout (GridLayout: 5 rows & 2 columns) - *add font JLabel, add font JComboBox - *add type JLabel, add type JComboBox - *add size JLabel, add size JComboBox - *add preview JLabel,add test JLabel - *add ok button, add cancel button - */ - jp.setLayout(new GridLayout(5,2,1,1)); - jp.add(fjl); - jp.add(fjcb = new JComboBox(fonts)); - jp.add(sjl); - jp.add(sjcb = new JComboBox(sizes)); - jp.add(tjl); - jp.add(tjcb = new JComboBox(types)); - jp.add(jjl); - jl.setBorder(BorderFactory.createEtchedBorder()); - jp.add(jl); - jp.add(okjb); - jp.add(cajb); - //add JPanel to the Container - this.getContentPane().add(jp); - /** - *for making JDialog at the center, - *@Center.java - */ - center.fCenter(); - //add action listener to Font JComboBox to get the selected item for setting the preview - fjcb.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - jl.setFont(new Font(String.valueOf(fjcb.getSelectedItem()),tjcb.getSelectedIndex(),14)); - } - }); - //add action listener to Type JComboBox to get the selected index for setting the preview - tjcb.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - jl.setFont(new Font(String.valueOf(fjcb.getSelectedItem()),tjcb.getSelectedIndex(),14)); - } - }); - } - - - /* - *@return font value: (Font,Type,Size) - */ - public Font font(){ - Font font = new Font(String.valueOf(fjcb.getSelectedItem()), tjcb.getSelectedIndex(), - Integer.parseInt(String.valueOf(sjcb.getSelectedItem()))); - return font; - } - - -} diff --git a/java/spl/notepad/Variant00001java/Notepad.java b/java/spl/notepad/Variant00001java/Notepad.java deleted file mode 100644 index 7356753..0000000 --- a/java/spl/notepad/Variant00001java/Notepad.java +++ /dev/null @@ -1,305 +0,0 @@ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - -/** - *A PUBLIC CLASS FOR NOTEPAD.JAVA - */ -public class Notepad extends JFrame { - - private static final long serialVersionUID = 1; - - - //for using the methods in these classes - public Actions actions = new Actions(this); - - - public Center center = new Center(this); - - - - //declaration of the private variables used in the program - //create the text area - private JTextArea textArea; - - - //create the Menu Bar that contains the JMenu "filE, ediT, vieW, formaT, helP" - private JMenuBar Menubar; - - - //Create the menu that contains the items - private JMenu filE, ediT, vieW, formaT, helP; - - - //Create the menu items - private JMenuItem neW, opeN, savE, saveAS, prinT, exiT, fonT, abouT, - cuT, copY, pastE, selectALL; - - - private JCheckBoxMenuItem lineWraP; - - - //Create the Tool Bar that contains the JButton - private JToolBar toolBar; - - - //Create the buttons - private JButton newButton, openButton, saveButton, saveAsButton, printButton, - fontButton, aboutButton; - - - - //for using lineWrap & textArea @Actions.java - public JCheckBoxMenuItem getLineWrap(){ - return lineWraP; - } - - - public JTextArea getTextArea(){ - return textArea; - } - - - //Constructor of Notepad - public Notepad(){ - //set the title for Notepad and set the size for it. - setTitle("Untitled - JAVA??? Notepad"); - setSize(800,600); - - //get the graphical user interface components display area - Container cp = getContentPane(); - /** - *adding the text area, - *adding the tool bar & - *adding the scroll pane to the container - */ - cp.add(textArea = new JTextArea()); - cp.add("North", toolBar = new JToolBar("Tool Bar")); - cp.add(new JScrollPane(textArea)); - - //for setting the menu bar - setJMenuBar(Menubar= new JMenuBar()); - //adding file, edit, view, format, help to the menu bar - Menubar.add(filE = new JMenu("File")); - Menubar.add(ediT = new JMenu("Edit")); - Menubar.add(vieW = new JMenu("View")); - Menubar.add(formaT = new JMenu("Format")); - Menubar.add(helP = new JMenu("Help")); - - /** - *adding neW, opeN, savE, saveAS, prinT & exiT to the filE Menu, - *adding a small image icon to the menu item & - *adding separator between the menu item - */ - filE.add(neW = new JMenuItem("New", new ImageIcon(this.getClass().getResource("images/new.gif")))); - filE.add(opeN = new JMenuItem("Open", new ImageIcon(this.getClass().getResource("images/open.gif")))); - filE.add(savE = new JMenuItem("Save", new ImageIcon(this.getClass().getResource("images/save.gif")))); - filE.add(saveAS = new JMenuItem("Save As", new ImageIcon(this.getClass().getResource("images/saveAs.gif")))); - filE.add(prinT = new JMenuItem("Print", new ImageIcon(this.getClass().getResource("images/print.gif")))); - filE.add(exiT = new JMenuItem("Exit")); //, new ImageIcon(this.getClass().getResource("images/exit.gif")))); -- exit.gif missing - filE.insertSeparator(4); - filE.insertSeparator(6); - - /** - *adding undO, redO, cuT, copY, pastE, finD, findNexT & selectALL to the ediT Menu, - *adding a small image icon to the menu item & - *adding separator between the menu item - */ - ediT.add(selectALL= new JMenuItem("Select All")); - //ediT.insertSeparator(2); - //ediT.insertSeparator(6); - - /** - *adding lineWraP & fonT to the formaT Menu, - *adding abouT to the helP Menu & - *adding a small image icon to the menu item - */ - formaT.add(lineWraP = new JCheckBoxMenuItem("Line Wrap")); - formaT.add(fonT = new JMenuItem("Font", new ImageIcon(this.getClass().getResource("images/font.gif")))); - helP.add(abouT = new JMenuItem("About Notepad", new ImageIcon(this.getClass().getResource("images/about.gif")))); - - /** - *allowing the file menu to be selected by pressing ALT + F - *allowing the edit menu to be selected by pressing ALT + E - *allowing the view menu to be selected by pressing ALT + V - *allowing the format menu to be selected by pressing ALT + O - *allowing the help menu to be selected by pressing ALT + H - */ - filE.setMnemonic('f'); - ediT.setMnemonic('e'); - vieW.setMnemonic('v'); - formaT.setMnemonic('o'); - helP.setMnemonic('h'); - - /** - *allowing the neW menu item to be selected by pressing ALT + N - *allowing the opeN menu item to be selected by pressing ALT + O - *allowing the savE menu item to be selected by pressing ALT + S - *allowing the prinT menu item to be selected by pressing ALT + P - *allowing the exiT menu item to be selected by pressing ALT + F4 - *allowing the cuT menu item to be selected by pressing ALT + X - *allowing the copY menu item to be selected by pressing ALT + C - *allowing the pastE menu item to be selected by pressing ALT + V - *allowing the selectAll menu item to be selected by pressing ALT + A - */ - neW.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK)); - opeN.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK)); - savE.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK)); - prinT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.CTRL_MASK)); - exiT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, ActionEvent.CTRL_MASK)); - selectALL.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.CTRL_MASK)); - - /** - *adding newButton, openButton, saveButton, saveAsButton, printButton, undoButton, - *redoButton, cutButton, copyButton, pasteButton, fontButton & aboutButton to the tool bar, - *adding a small image icon to the menu item & - *adding separator between the button - */ - toolBar.add(newButton = new JButton(new ImageIcon(this.getClass().getResource("images/new.gif")))); - toolBar.add(openButton = new JButton(new ImageIcon(this.getClass().getResource("images/open.gif")))); - toolBar.add(saveButton = new JButton(new ImageIcon(this.getClass().getResource("images/save.gif")))); - toolBar.add(saveAsButton= new JButton(new ImageIcon(this.getClass().getResource("images/saveAs.gif")))); - toolBar.add(printButton = new JButton(new ImageIcon(this.getClass().getResource("images/print.gif")))); - toolBar.addSeparator(); - toolBar.add(fontButton = new JButton(new ImageIcon(this.getClass().getResource("images/font.gif")))); - toolBar.add(aboutButton = new JButton(new ImageIcon(this.getClass().getResource("images/about.gif")))); - - //adding a tool tip text to the button for descriping the image icon. - newButton.setToolTipText("New"); - openButton.setToolTipText("Open"); - saveButton.setToolTipText("Save"); - saveAsButton.setToolTipText("Save As"); - printButton.setToolTipText("Print"); - fontButton.setToolTipText("Font"); - aboutButton.setToolTipText("About Notepad"); - - /** - *setting the default close operation to false & - *using own action (exiT action @Actions.java) - */ - setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); - addWindowListener(new WindowAdapter(){ - public void windowClosing(WindowEvent e){ - actions.exiT(); - } - }); - /** - *adding action listener for menu item: neW, opeN, savE, saveAS, prinT, exiT, - *redO, undO, copY, cuT, pastE, finD, findNexT, selectALL, lineWraP, fonT & abouT - *the actions was written @Actions.java - */ - neW.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.neW(); - } - }); - opeN.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.opeN(); - } - }); - savE.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.savE(); - } - }); - saveAS.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.saveAs(); - } - }); - prinT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.prinT(); - } - }); - exiT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.exiT(); - } - }); - selectALL.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.selectALL(); - } - }); - lineWraP.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.lineWraP(); - } - }); - fonT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.fonT(); - } - }); - abouT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.abouT(); - } - }); - - /** - *adding action listener for the button in the tool bar: newButton, openButton, - *saveButton, saveAsButton, printButton, redoButton, undoButton, copyButton, - *cutButton, pasteButton, findButton, selectALL, lineWraP, fontButton & aboutButton - *the actions was written @Actions.java - */ - newButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.neW(); - } - }); - openButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.opeN(); - } - }); - saveButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.savE(); - } - }); - saveAsButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.saveAs(); - } - }); - printButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.prinT(); - } - }); - fontButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.fonT(); - } - }); - aboutButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.abouT(); - } - }); - - /** - *Setting the Line Wrap & Wrap Style Word features are true - */ - textArea.setLineWrap(true); - textArea.setWrapStyleWord(true); - /** - *for making the program at the center, - *@see Center.java - */ - center.nCenter(); - show(); - } - - - //Main Method - public static void main(String[] args){ - new Notepad(); - - } - - -} diff --git a/java/spl/notepad/Variant00001java/Print.java b/java/spl/notepad/Variant00001java/Print.java deleted file mode 100644 index 132daed..0000000 --- a/java/spl/notepad/Variant00001java/Print.java +++ /dev/null @@ -1,64 +0,0 @@ -import java.awt.*; -import java.awt.print.*; -import javax.swing.*; - -/** - *A class for creating a printer option. - */ -public class Print implements Printable { - - private Component componentToBePrinted; - - - - public static void printComponent(Component c){ - new Print(c).print(); - } - - - public Print(Component componentToBePrinted){ - this.componentToBePrinted = componentToBePrinted; - } - - - public void print(){ - PrinterJob printJob = PrinterJob.getPrinterJob(); - printJob.setPrintable(this); - if(printJob.printDialog()) - try{ - printJob.print(); - } - catch(PrinterException pe){ - System.out.println("Error printing: " + pe); - } - } - - - public int print(Graphics g, PageFormat pageFormat, int pageIndex){ - if(pageIndex > 0){ - return(NO_SUCH_PAGE); - } - else{ - Graphics2D g2d = (Graphics2D)g; - g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); - disableDoubleBuffering(componentToBePrinted); - componentToBePrinted.paint(g2d); - enableDoubleBuffering(componentToBePrinted); - return(PAGE_EXISTS); - } - } - - - public static void disableDoubleBuffering(Component c){ - RepaintManager currentManager = RepaintManager.currentManager(c); - currentManager.setDoubleBufferingEnabled(false); - } - - - public static void enableDoubleBuffering(Component c){ - RepaintManager currentManager = RepaintManager.currentManager(c); - currentManager.setDoubleBufferingEnabled(true); - } - - -} diff --git a/java/spl/notepad/Variant00002java/About.java b/java/spl/notepad/Variant00002java/About.java deleted file mode 100644 index fb751fd..0000000 --- a/java/spl/notepad/Variant00002java/About.java +++ /dev/null @@ -1,25 +0,0 @@ -import javax.swing.*; - -/** - *A CLASS FOR CREATING ABOUT PANEL - */ -public class About extends JPanel { - - private static final long serialVersionUID = 1; - - - public About(){ - //Create a Label & an image icon in it - JLabel label1 = new JLabel(new ImageIcon(this.getClass().getResource("images/java.gif"))); - //adding label1 to the JPanel - this.add(label1); - //Create a Label & put a HTML script - JLabel label2 = new JLabel("
  • JAVA??? Notepad
  • Ver# 2.0

  • " - +"
  • Coded by: Salah Al-Thubaiti

  • KFUPM, CS

  • " - +"

    CopyRight??? 2001-2002

  • "); - //adding label2 to the JPanel - this.add(label2); - } - - -} diff --git a/java/spl/notepad/Variant00002java/Actions.java b/java/spl/notepad/Variant00002java/Actions.java deleted file mode 100644 index 50012f2..0000000 --- a/java/spl/notepad/Variant00002java/Actions.java +++ /dev/null @@ -1,481 +0,0 @@ -import java.io.*; -import java.util.*; -import java.awt.event.*; -import javax.swing.*; public class Actions { - - //declaration of the private variables used in the program - private int returnVal; - - //for JFileChooser - private int option; - - //for using it into JOptionPane - private String fileContent = null; - - //to get the text from the text area - private String fileName = null; - - //for using the name of the file - private JFileChooser jfc = new JFileChooser("."); - - //for using a open & save dialog - private ExampleFileFilter filter = new ExampleFileFilter(); - - //for filtering the file - Notepad n; - - //for using the object in the Notepad.java - public Fonts font = new Fonts(); - - - - public Actions(Notepad n){ - this.n = n; - } - - - /** - *If we want to write a new text, first we want to know if the text area is empty or not, - *second we want to know if the text was saved or not. - *If the text area isn't empty & the text wasn't saved before this time, then the program display -> - *for the user an option for saving the text in a new file or in the same file - */ - public void neW(){ - /** - *if the text area isn't empty & if the text area hasn't - *a text not saved before (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - /** - *here, we have two things, first if the text wasn't be opened or saved before - *second if the text was be opened or saved - */ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - //if the user click on YES button, - //then the program will save the text & make a new text area - if(option == 0){ - //to save the text into a new file - saveAs(); - //to create new getTextArea() after saving the old getTextArea() - n.getTextArea().setText(""); - } - //if the user click on NO button - if(option == 1){ - //to create new getTextArea() without saving the old getTextArea() - n.getTextArea().setText(""); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will save the text into the old file & - *make a new text area,,, - */ - if(option == 0){ - save(); - //to create new getTextArea() after saving the old getTextArea() - n.getTextArea().setText(""); - } - //if the user click on NO button - if(option == 1){ - //to create new getTextArea() without saving the old getTextArea() - n.getTextArea().setText(""); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to write a new text,,, this option will be actived - */ - else{ - n.getTextArea().setText(""); - } - n.setTitle("Untitled - JAVA??? Notepad"); - } - - - /** - *If we want to open a new text, first we want to know if the text area - * is empty or not, second we want to kwnow if the text was saved or not. - *If the text area isn't empty & the text wasn't saved befor this time, - *then the program display for the user an option for saving the text - *in a new file or in the same file - */ - public void opeN(){ - /** - *if the text area isn't empty & if the text area hasn't a text which - *not saved befor (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - /** - *here, we have 2 thing, first if the text wasn't be opened or saved befor - *second if the text was be opened or saved - */ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - //if the user click on YES button, - //then the program will be saved the text & opened a new documents - if(option == 0){ - //for saving the text in a new file - saveAs(); - //for opening the new documents - open(); - } - /** - *if the user click on NO button, - *the program will be opened the new documents - */ - if(option == 1){ - //for opening the new documents - open(); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will save the text into the same file & - *open the new documents - */ - if(option == 0){ - //for saving the text into the same file - save(); - //for opening the new documents - open(); - } - /** - *if the user click on NO button, - *the program will be opened the new documents - */ - if(option == 1){ - //for opening the new documents - open(); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to open a new document,,, this option will be actived - */ - else{ - //for opening the new documents - open(); - } - } - - - /** - *THIS IS FOR SAVE ACTION, SaveAs ACTION has saveAs() method - *If we want to save a new text, then we want to know - *if the text was saved befor or not. - *If the text wasn't be saved befor, then we will use saveAs() - *If the text was be save befor, then we will use save() - */ - public void savE(){ - /** - *if String fileName is null, then using saveAs(). - *Because there was no file was be saved - */ - if(fileName == null){ - saveAs(); - } - /** - *if String fileName has a String (file name), then using save(). - *Because we want to save the new text in the same file. - *if the user want to save the all text (old & new text) in a new file, -> - *he can presses SaveAs button (@saveAs()) - */ - else{ - save(); - } - } - - - /** - *THIS FROM SUN??? WEBSITE (@Print.java) - *if we want to print the text, we can do this by print method - */ - public void prinT(){ - //import printer class - Print.printComponent(n.getTextArea()); - } - - - /** - *If we want to exit from the program, - *first we want to know if the text area is empty or not, - *second we want to kwnow if the text was saved or not. - *If the text area isn't empty & the text wasn't saved befor this time, - *then the program display -> - *for the user an option for saving the text in a new file or in the same file - */ - public void exiT(){ - /** - *if the text area isn't empty & if the text area hasn't a text which - *not saved befor (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will be saved the text & close the program - */ - if(option == 0){ - //for saving the text into new file - saveAs(); - //for closing the program - System.exit(0); - } - /** - *if the user click on NO button, - *then the program will be closed without save the text - */ - if(option == 1){ - //for closing the program - System.exit(0); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will be saved the text & close the program - */ - if(option == 0){ - //for saving the text into the same file - save(); - //for closing the program - System.exit(0); - } - /** - *if the user click on NO button, - *then the program will be closed without save the text - */ - if(option == 1){ - //for closing the program - System.exit(0); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to close the program. This option will be actived - */ - else{ - //for closing the program - System.exit(0); - } - } - - - //to select all the text - public void selectALL(){ - n.getTextArea().selectAll(); - } - - - //for wraping the line & wraping the style word - public void lineWraP(){ - if(n.getLineWrap().isSelected()){ - /** - *make the line wrap & wrap style word is true - *when the line wrap is selected - */ - n.getTextArea().setLineWrap(true); - n.getTextArea().setWrapStyleWord(true); - } - else{ - /** - *make the line wrap & wrap style word is false - *when the line wrap isn't selected - */ - n.getTextArea().setLineWrap(false); - n.getTextArea().setWrapStyleWord(false); - } - } - - - /** - *@see FONTS.JAVA - *this is a font class which is for changing the font, style & size - */ - public void fonT(){ - font.setVisible(true); //setting the visible is true - font.pack(); //pack the panel - //making an action for ok button, so we can change the font - font.getOkjb().addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - n.getTextArea().setFont(font.font()); - //after we chose the font, then the JDialog will be closed - font.setVisible(false); - } - }); - //making an action for cancel button, so we can return to the old font. - font.getCajb().addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - //after we cancel the, then the JDialog will be closed - font.setVisible(false); - } - }); - } - - - /** - *@see ABOUT.JAVA - *it's a Message Dialog to show the information about this program - */ - public void abouT(){ - JOptionPane.showMessageDialog(null, new About(),"About Notepad",JOptionPane.PLAIN_MESSAGE); - } - - - /** - *THIS IS THE WAY FOR OPENING THE TEXT FILE - */ - public void open(){ - //filter the kind of files, we want only TXT file - filter.addExtension("txt"); - //to set a description for the file (TXT) - filter.setDescription("TXT Documents"); - //setting the FileFilter to JFileChooser - jfc.setFileFilter(filter); - returnVal = jfc.showOpenDialog(n); //to show JFileChooser - if(returnVal == JFileChooser.APPROVE_OPTION){ - //to erase any text in the text area before adding new text - n.getTextArea().setText(null); - try{ - //to get the name of the selected file - fileName = jfc.getSelectedFile().getPath(); - //to read the selected file - Reader in = new FileReader(jfc.getSelectedFile()); - //100000 is the max. char can be written in the text area - char[] buff = new char[100000]; - int nch; - while((nch = in.read(buff, 0, buff.length)) != -1) - n.getTextArea().append(new String(buff, 0, nch)); - //to get more text from the file if the array wasn't full - fileContent = n.getTextArea().getText(); - } - catch(FileNotFoundException x){} - catch(IOException ioe){ - System.err.println("I/O Error on Open"); - } - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - /** - *THIS IS THE WAY FOR SAVING THE TEXT IN THE SAME FILE - */ - public void save(){ - //initializing 'fout' to write all text in the selected file - try{ - PrintWriter fout = new PrintWriter(new FileWriter(jfc.getSelectedFile())); - //for getting the text from the text area - fileContent = n.getTextArea().getText(); - //using StringTokenizer for the 'fileContent' String - StringTokenizer st=new StringTokenizer(fileContent,System.getProperty("line.separator")); - while(st.hasMoreTokens()){ - //write the string (text) in the selected file - fout.println(st.nextToken()); - } - //closing fout - fout.close(); - } - catch(IOException ioe){ - System.err.println("I/O Error on Save"); - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - /** - *THIS IS THE WAY FOR SAVING THE TEXT IN A NEW FILE - */ - public void saveAs(){ - //filter the kind of files, we want only TXT file - filter.addExtension("txt"); - //to set a description for the file (TXT) - filter.setDescription("TXT Documents"); - //setting the FileFilter to JFileChooser - jfc.setFileFilter(filter); - returnVal = jfc.showSaveDialog(n); - if(returnVal == JFileChooser.APPROVE_OPTION){ - //initializing the PrintWriter, to save the text in a new file - PrintWriter fout = null; - try{ - fout = new PrintWriter(new FileWriter(jfc.getSelectedFile() + ".txt")); - //getting the text from the text area - fileContent = n.getTextArea().getText(); - //getting the name of the selected file - fileName = jfc.getSelectedFile().getPath(); - //using StringTokenizer for the 'fileContent' String - StringTokenizer st=new StringTokenizer(fileContent,System.getProperty("line.separator")); - while(st.hasMoreTokens()){ - //write the string (text) in the selected file - fout.println(st.nextToken()); - } - //closing 'fout' - fout.close(); - } - catch(IOException ioe){ - System.err.println ("I/O Error on Save"); - } - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - //to cut the selected text - public void cuT(){ - n.getTextArea().cut(); - } - - - //to copy the selected text - public void copY(){ - n.getTextArea().copy(); - } - - - //to paste the selected text - public void pastE(){ - n.getTextArea().paste(); - } - - -} diff --git a/java/spl/notepad/Variant00002java/Center.java b/java/spl/notepad/Variant00002java/Center.java deleted file mode 100644 index 1715525..0000000 --- a/java/spl/notepad/Variant00002java/Center.java +++ /dev/null @@ -1,37 +0,0 @@ -import java.awt.*; -/** - *A PUBLIC CLASS FOR CENTER.JAVA - */ -public class Center { - - Notepad n; - - //for using the object in the Notepad.java - Fonts f; - - //for using the object in the Fonts.java - public Center(Notepad n){ - this.n = n; - } - - - public Center(Fonts f){ - this.f = f; - } - - - public void nCenter(){ - //Centering the window - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - n.setLocation((screenSize.width-n.getWidth())/2,(screenSize.height-n.getHeight())/2); - } - - - public void fCenter(){ - //Centering the window - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - f.setLocation((screenSize.width-f.getWidth())/2,(screenSize.height-f.getHeight())/2); - } - - -} diff --git a/java/spl/notepad/Variant00002java/ExampleFileFilter.java b/java/spl/notepad/Variant00002java/ExampleFileFilter.java deleted file mode 100644 index 47b0dd6..0000000 --- a/java/spl/notepad/Variant00002java/ExampleFileFilter.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (c) 2002 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * -Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * -Redistribution in binary form must reproduct the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING - * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT - * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT - * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS - * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST - * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, - * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY - * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN - * IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that Software is not designed, licensed or intended for - * use in the design, construction, operation or maintenance of any nuclear - * facility. - */ - -/* - * @(#)ExampleFileFilter.java 1.13 02/06/13 - */ - - - -//import the packages for using the classes in them into the program -import java.io.File; -import java.util.Hashtable; -import java.util.Enumeration; -import javax.swing.filechooser.*; - -/** - * A convenience implementation of FileFilter that filters out - * all files except for those type extensions that it knows about. - * - * Extensions are of the type ".foo", which is typically found on - * Windows and Unix boxes, but not on Macinthosh. Case is ignored. - * - * Example - create a new filter that filerts out all files - * but gif and jpg image files: - * - * JFileChooser chooser = new JFileChooser(); - * ExampleFileFilter filter = new ExampleFileFilter( - * new String{"gif", "jpg"}, "JPEG & GIF Images") - * chooser.addChoosableFileFilter(filter); - * chooser.showOpenDialog(this); - * - * @version 1.13 06/13/02 - * @author Jeff Dinkins - */ -public class ExampleFileFilter extends FileFilter { - - -// private static String TYPE_UNKNOWN = "Type Unknown"; -// private static String HIDDEN_FILE = "Hidden File"; - - private Hashtable filters = null; - - - private String description = null; - - - private String fullDescription = null; - - - private boolean useExtensionsInDescription = true; - - - - /** - * Creates a file filter. If no filters are added, then all - * files are accepted. - * - * @see #addExtension - */ - public ExampleFileFilter(){ - this.filters = new Hashtable(); - } - - - - /** - * Creates a file filter that accepts files with the given extension. - * Example: new ExampleFileFilter("jpg"); - * - * @see #addExtension - */ - public ExampleFileFilter(String extension){ - this(extension,null); - } - - - - /** - * Creates a file filter that accepts the given file type. - * Example: new ExampleFileFilter("jpg", "JPEG Image Images"); - * - * Note that the "." before the extension is not needed. If - * provided, it will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String extension, String description){ - this(); - if(extension!=null) addExtension(extension); - if(description!=null) setDescription(description); - } - - - - /** - * Creates a file filter from the given string array. - * Example: new ExampleFileFilter(String {"gif", "jpg"}); - * - * Note that the "." before the extension is not needed adn - * will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String[] filters){ - this(filters, null); - } - - - - /** - * Creates a file filter from the given string array and description. - * Example: new ExampleFileFilter(String {"gif", "jpg"}, "Gif and JPG Images"); - * - * Note that the "." before the extension is not needed and will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String[] filters, String description){ - this(); - for (int i = 0; i < filters.length; i++){ - // add filters one by one - addExtension(filters[i]); - } - if(description!=null) setDescription(description); - } - - - - /** - * Return true if this file should be shown in the directory pane, - * false if it shouldn't. - * - * Files that begin with "." are ignored. - * - * @see #getExtension - * @see FileFilter#accepts - */ - public boolean accept(File f){ - if(f != null){ - if(f.isDirectory()){ - return true; - } - String extension = getExtension(f); - if(extension != null && filters.get(getExtension(f)) != null){ - return true; - }; - } - return false; - } - - - - /** - * Return the extension portion of the file's name . - * - * @see #getExtension - * @see FileFilter#accept - */ - public String getExtension(File f){ - if(f != null){ - String filename = f.getName(); - int i = filename.lastIndexOf('.'); - if(i>0 && i(5); - } - filters.put(extension.toLowerCase(), this); - fullDescription = null; - } - - - - /** - * Returns the human readable description of this filter. For - * example: "JPEG and GIF Image Files (*.jpg, *.gif)" - * - * @see setDescription - * @see setExtensionListInDescription - * @see isExtensionListInDescription - * @see FileFilter#getDescription - */ - @SuppressWarnings("rawtypes") - public String getDescription(){ - if(fullDescription == null) { - if(description == null || isExtensionListInDescription()){ - fullDescription = description==null ? "(" : description + " ("; - // build the description from the extension list - Enumeration extensions = filters.keys(); - if(extensions != null){ - fullDescription += "." + (String) extensions.nextElement(); - while (extensions.hasMoreElements()) { - fullDescription += ", ." + (String) extensions.nextElement(); - } - } - fullDescription += ")"; - } else { - fullDescription = description; - } - } - return fullDescription; - } - - - - /** - * Sets the human readable description of this filter. For - * example: filter.setDescription("Gif and JPG Images"); - * - * @see setDescription - * @see setExtensionListInDescription - * @see isExtensionListInDescription - */ - public void setDescription(String description){ - this.description = description; - fullDescription = null; - } - - - - /** - * Determines whether the extension list (.jpg, .gif, etc) should - * show up in the human readable description. - * - * Only relevent if a description was provided in the constructor - * or using setDescription(); - * - * @see getDescription - * @see setDescription - * @see isExtensionListInDescription - */ - public void setExtensionListInDescription(boolean b){ - useExtensionsInDescription = b; - fullDescription = null; - } - - - - /** - * Returns whether the extension list (.jpg, .gif, etc) should - * show up in the human readable description. - * - * Only relevent if a description was provided in the constructor - * or using setDescription(); - * - * @see getDescription - * @see setDescription - * @see setExtensionListInDescription - */ - public boolean isExtensionListInDescription(){ - return useExtensionsInDescription; - } - - -} diff --git a/java/spl/notepad/Variant00002java/Fonts.java b/java/spl/notepad/Variant00002java/Fonts.java deleted file mode 100644 index e63be0b..0000000 --- a/java/spl/notepad/Variant00002java/Fonts.java +++ /dev/null @@ -1,136 +0,0 @@ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - -/** - *A class for creating JFontDialog - */ -public class Fonts extends JDialog { - - private static final long serialVersionUID = 1L; - - - /** - *@see Center.java - *this class to make the JDialog in the center - */ - public Center center = new Center(this); - - - - //declaration of the private variables used in the program - private JPanel jp = new JPanel(); - - - private JLabel fjl = new JLabel("Fonts: "); - - - private JComboBox fjcb = new JComboBox(); - - - /** - *-> GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames() <- - * WE USING THIS METHOD TO GET ALL FONT IN THE SYSTEM (OS) - */ - private String fonts[]=GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); - - - private JLabel sjl = new JLabel("Sizes: "); - - - private JComboBox sjcb = new JComboBox(); - - - private String sizes[] = {"8","10","12","14","16","18","20","24","28","32","48","72"}; - - - private JLabel tjl = new JLabel("Types: "); - - - private JComboBox tjcb = new JComboBox(); - - - private String types[] = {"Regular", "Bold", "Italic", "Bold Italic"}; - - - private JLabel jjl = new JLabel("Preview:"); - - - private JLabel jl = new JLabel("AaBaCcDdeEfFgGhHjJ"); - - - private JButton okjb = new JButton("OK"); - - - private JButton cajb = new JButton("Cancel"); - - - //for using ok & cancel button @Actions.java - public JButton getOkjb(){ - return okjb; - } - - - public JButton getCajb(){ - return cajb; - } - - - //Constructor of Fonts - public Fonts(){ - //for setting the title - setTitle("Font Dialog"); - setResizable(false); - /** - *setting the layout (GridLayout: 5 rows & 2 columns) - *add font JLabel, add font JComboBox - *add type JLabel, add type JComboBox - *add size JLabel, add size JComboBox - *add preview JLabel,add test JLabel - *add ok button, add cancel button - */ - jp.setLayout(new GridLayout(5,2,1,1)); - jp.add(fjl); - jp.add(fjcb = new JComboBox(fonts)); - jp.add(sjl); - jp.add(sjcb = new JComboBox(sizes)); - jp.add(tjl); - jp.add(tjcb = new JComboBox(types)); - jp.add(jjl); - jl.setBorder(BorderFactory.createEtchedBorder()); - jp.add(jl); - jp.add(okjb); - jp.add(cajb); - //add JPanel to the Container - this.getContentPane().add(jp); - /** - *for making JDialog at the center, - *@Center.java - */ - center.fCenter(); - //add action listener to Font JComboBox to get the selected item for setting the preview - fjcb.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - jl.setFont(new Font(String.valueOf(fjcb.getSelectedItem()),tjcb.getSelectedIndex(),14)); - } - }); - //add action listener to Type JComboBox to get the selected index for setting the preview - tjcb.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - jl.setFont(new Font(String.valueOf(fjcb.getSelectedItem()),tjcb.getSelectedIndex(),14)); - } - }); - } - - - /* - *@return font value: (Font,Type,Size) - */ - public Font font(){ - Font font = new Font(String.valueOf(fjcb.getSelectedItem()), tjcb.getSelectedIndex(), - Integer.parseInt(String.valueOf(sjcb.getSelectedItem()))); - return font; - } - - -} diff --git a/java/spl/notepad/Variant00002java/Notepad.java b/java/spl/notepad/Variant00002java/Notepad.java deleted file mode 100644 index 6ba5837..0000000 --- a/java/spl/notepad/Variant00002java/Notepad.java +++ /dev/null @@ -1,356 +0,0 @@ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - -public - -class Notepad extends JFrame { - - private static final long serialVersionUID = 1; - - - //for using the methods in these classes - public Actions actions = new Actions(this); - - - public Center center = new Center(this); - - - - //declaration of the private variables used in the program - //create the text area - private JTextArea textArea; - - - //create the Menu Bar that contains the JMenu "filE, ediT, vieW, formaT, helP" - private JMenuBar Menubar; - - - //Create the menu that contains the items - private JMenu filE, ediT, vieW, formaT, helP; - - - //Create the menu items - private JMenuItem neW, opeN, savE, saveAS, prinT, exiT, fonT, abouT, - cuT, copY, pastE, selectALL; - - - private JCheckBoxMenuItem lineWraP; - - - //Create the Tool Bar that contains the JButton - private JToolBar toolBar; - - - //Create the buttons - private JButton newButton, openButton, saveButton, saveAsButton, printButton, - fontButton, aboutButton; - - - - //for using lineWrap & textArea @Actions.java - public JCheckBoxMenuItem getLineWrap(){ - return lineWraP; - } - - - public JTextArea getTextArea(){ - return textArea; - } - - - - public Notepad (){ - //set the title for Notepad and set the size for it. - setTitle("Untitled - JAVA??? Notepad"); - setSize(800,600); - - //get the graphical user interface components display area - Container cp = getContentPane(); - /** - *adding the text area, - *adding the tool bar & - *adding the scroll pane to the container - */ - cp.add(textArea = new JTextArea()); - cp.add("North", toolBar = new JToolBar("Tool Bar")); - cp.add(new JScrollPane(textArea)); - - //for setting the menu bar - setJMenuBar(Menubar= new JMenuBar()); - //adding file, edit, view, format, help to the menu bar - Menubar.add(filE = new JMenu("File")); - Menubar.add(ediT = new JMenu("Edit")); - Menubar.add(vieW = new JMenu("View")); - Menubar.add(formaT = new JMenu("Format")); - Menubar.add(helP = new JMenu("Help")); - - /** - *adding neW, opeN, savE, saveAS, prinT & exiT to the filE Menu, - *adding a small image icon to the menu item & - *adding separator between the menu item - */ - filE.add(neW = new JMenuItem("New", new ImageIcon(this.getClass().getResource("images/new.gif")))); - filE.add(opeN = new JMenuItem("Open", new ImageIcon(this.getClass().getResource("images/open.gif")))); - filE.add(savE = new JMenuItem("Save", new ImageIcon(this.getClass().getResource("images/save.gif")))); - filE.add(saveAS = new JMenuItem("Save As", new ImageIcon(this.getClass().getResource("images/saveAs.gif")))); - filE.add(prinT = new JMenuItem("Print", new ImageIcon(this.getClass().getResource("images/print.gif")))); - filE.add(exiT = new JMenuItem("Exit")); //, new ImageIcon(this.getClass().getResource("images/exit.gif")))); -- exit.gif missing - filE.insertSeparator(4); - filE.insertSeparator(6); - - /** - *adding undO, redO, cuT, copY, pastE, finD, findNexT & selectALL to the ediT Menu, - *adding a small image icon to the menu item & - *adding separator between the menu item - */ - ediT.add(selectALL= new JMenuItem("Select All")); - //ediT.insertSeparator(2); - //ediT.insertSeparator(6); - - /** - *adding lineWraP & fonT to the formaT Menu, - *adding abouT to the helP Menu & - *adding a small image icon to the menu item - */ - formaT.add(lineWraP = new JCheckBoxMenuItem("Line Wrap")); - formaT.add(fonT = new JMenuItem("Font", new ImageIcon(this.getClass().getResource("images/font.gif")))); - helP.add(abouT = new JMenuItem("About Notepad", new ImageIcon(this.getClass().getResource("images/about.gif")))); - - /** - *allowing the file menu to be selected by pressing ALT + F - *allowing the edit menu to be selected by pressing ALT + E - *allowing the view menu to be selected by pressing ALT + V - *allowing the format menu to be selected by pressing ALT + O - *allowing the help menu to be selected by pressing ALT + H - */ - filE.setMnemonic('f'); - ediT.setMnemonic('e'); - vieW.setMnemonic('v'); - formaT.setMnemonic('o'); - helP.setMnemonic('h'); - - /** - *allowing the neW menu item to be selected by pressing ALT + N - *allowing the opeN menu item to be selected by pressing ALT + O - *allowing the savE menu item to be selected by pressing ALT + S - *allowing the prinT menu item to be selected by pressing ALT + P - *allowing the exiT menu item to be selected by pressing ALT + F4 - *allowing the cuT menu item to be selected by pressing ALT + X - *allowing the copY menu item to be selected by pressing ALT + C - *allowing the pastE menu item to be selected by pressing ALT + V - *allowing the selectAll menu item to be selected by pressing ALT + A - */ - neW.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK)); - opeN.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK)); - savE.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK)); - prinT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.CTRL_MASK)); - exiT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, ActionEvent.CTRL_MASK)); - selectALL.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.CTRL_MASK)); - - /** - *adding newButton, openButton, saveButton, saveAsButton, printButton, undoButton, - *redoButton, cutButton, copyButton, pasteButton, fontButton & aboutButton to the tool bar, - *adding a small image icon to the menu item & - *adding separator between the button - */ - toolBar.add(newButton = new JButton(new ImageIcon(this.getClass().getResource("images/new.gif")))); - toolBar.add(openButton = new JButton(new ImageIcon(this.getClass().getResource("images/open.gif")))); - toolBar.add(saveButton = new JButton(new ImageIcon(this.getClass().getResource("images/save.gif")))); - toolBar.add(saveAsButton= new JButton(new ImageIcon(this.getClass().getResource("images/saveAs.gif")))); - toolBar.add(printButton = new JButton(new ImageIcon(this.getClass().getResource("images/print.gif")))); - toolBar.addSeparator(); - toolBar.add(fontButton = new JButton(new ImageIcon(this.getClass().getResource("images/font.gif")))); - toolBar.add(aboutButton = new JButton(new ImageIcon(this.getClass().getResource("images/about.gif")))); - - //adding a tool tip text to the button for descriping the image icon. - newButton.setToolTipText("New"); - openButton.setToolTipText("Open"); - saveButton.setToolTipText("Save"); - saveAsButton.setToolTipText("Save As"); - printButton.setToolTipText("Print"); - fontButton.setToolTipText("Font"); - aboutButton.setToolTipText("About Notepad"); - - /** - *setting the default close operation to false & - *using own action (exiT action @Actions.java) - */ - setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); - addWindowListener(new WindowAdapter(){ - public void windowClosing(WindowEvent e){ - actions.exiT(); - } - }); - /** - *adding action listener for menu item: neW, opeN, savE, saveAS, prinT, exiT, - *redO, undO, copY, cuT, pastE, finD, findNexT, selectALL, lineWraP, fonT & abouT - *the actions was written @Actions.java - */ - neW.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.neW(); - } - }); - opeN.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.opeN(); - } - }); - savE.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.savE(); - } - }); - saveAS.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.saveAs(); - } - }); - prinT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.prinT(); - } - }); - exiT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.exiT(); - } - }); - selectALL.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.selectALL(); - } - }); - lineWraP.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.lineWraP(); - } - }); - fonT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.fonT(); - } - }); - abouT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.abouT(); - } - }); - - /** - *adding action listener for the button in the tool bar: newButton, openButton, - *saveButton, saveAsButton, printButton, redoButton, undoButton, copyButton, - *cutButton, pasteButton, findButton, selectALL, lineWraP, fontButton & aboutButton - *the actions was written @Actions.java - */ - newButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.neW(); - } - }); - openButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.opeN(); - } - }); - saveButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.savE(); - } - }); - saveAsButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.saveAs(); - } - }); - printButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.prinT(); - } - }); - fontButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.fonT(); - } - }); - aboutButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.abouT(); - } - }); - - /** - *Setting the Line Wrap & Wrap Style Word features are true - */ - textArea.setLineWrap(true); - textArea.setWrapStyleWord(true); - /** - *for making the program at the center, - *@see Center.java - */ - center.nCenter(); - show(); - - ediT.add(cuT = new JMenuItem("Cut", new ImageIcon(this.getClass().getResource("images/cut.gif")))); - ediT.add(copY = new JMenuItem("Copy", new ImageIcon(this.getClass().getResource("images/copy.gif")))); - ediT.add(pastE= new JMenuItem("Paste",new ImageIcon(this.getClass().getResource("images/paste.gif")))); - - cuT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.CTRL_MASK)); - copY.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK)); - pastE.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.CTRL_MASK)); - - toolBar.add(cutButton = new JButton(new ImageIcon(this.getClass().getResource("images/cut.gif")))); - toolBar.add(copyButton = new JButton(new ImageIcon(this.getClass().getResource("images/copy.gif")))); - toolBar.add(pasteButton = new JButton(new ImageIcon(this.getClass().getResource("images/paste.gif")))); - - cutButton.setToolTipText("Cut"); - copyButton.setToolTipText("Copy"); - pasteButton.setToolTipText("Paste"); - - cuT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.cuT(); - } - }); - copY.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.copY(); - } - }); - pastE.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.pastE(); - } - }); - - cutButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.cuT(); - } - }); - copyButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.copY(); - } - }); - pasteButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.pastE(); - } - }); - - } - - - //Main Method - public static void main(String[] args){ - new Notepad(); - - } - - - private JButton cutButton, copyButton, pasteButton; - - -} diff --git a/java/spl/notepad/Variant00002java/Print.java b/java/spl/notepad/Variant00002java/Print.java deleted file mode 100644 index 132daed..0000000 --- a/java/spl/notepad/Variant00002java/Print.java +++ /dev/null @@ -1,64 +0,0 @@ -import java.awt.*; -import java.awt.print.*; -import javax.swing.*; - -/** - *A class for creating a printer option. - */ -public class Print implements Printable { - - private Component componentToBePrinted; - - - - public static void printComponent(Component c){ - new Print(c).print(); - } - - - public Print(Component componentToBePrinted){ - this.componentToBePrinted = componentToBePrinted; - } - - - public void print(){ - PrinterJob printJob = PrinterJob.getPrinterJob(); - printJob.setPrintable(this); - if(printJob.printDialog()) - try{ - printJob.print(); - } - catch(PrinterException pe){ - System.out.println("Error printing: " + pe); - } - } - - - public int print(Graphics g, PageFormat pageFormat, int pageIndex){ - if(pageIndex > 0){ - return(NO_SUCH_PAGE); - } - else{ - Graphics2D g2d = (Graphics2D)g; - g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); - disableDoubleBuffering(componentToBePrinted); - componentToBePrinted.paint(g2d); - enableDoubleBuffering(componentToBePrinted); - return(PAGE_EXISTS); - } - } - - - public static void disableDoubleBuffering(Component c){ - RepaintManager currentManager = RepaintManager.currentManager(c); - currentManager.setDoubleBufferingEnabled(false); - } - - - public static void enableDoubleBuffering(Component c){ - RepaintManager currentManager = RepaintManager.currentManager(c); - currentManager.setDoubleBufferingEnabled(true); - } - - -} diff --git a/java/spl/notepad/Variant00003java/About.java b/java/spl/notepad/Variant00003java/About.java deleted file mode 100644 index fb751fd..0000000 --- a/java/spl/notepad/Variant00003java/About.java +++ /dev/null @@ -1,25 +0,0 @@ -import javax.swing.*; - -/** - *A CLASS FOR CREATING ABOUT PANEL - */ -public class About extends JPanel { - - private static final long serialVersionUID = 1; - - - public About(){ - //Create a Label & an image icon in it - JLabel label1 = new JLabel(new ImageIcon(this.getClass().getResource("images/java.gif"))); - //adding label1 to the JPanel - this.add(label1); - //Create a Label & put a HTML script - JLabel label2 = new JLabel("
  • JAVA??? Notepad
  • Ver# 2.0

  • " - +"
  • Coded by: Salah Al-Thubaiti

  • KFUPM, CS

  • " - +"

    CopyRight??? 2001-2002

  • "); - //adding label2 to the JPanel - this.add(label2); - } - - -} diff --git a/java/spl/notepad/Variant00003java/Actions.java b/java/spl/notepad/Variant00003java/Actions.java deleted file mode 100644 index aacba1d..0000000 --- a/java/spl/notepad/Variant00003java/Actions.java +++ /dev/null @@ -1,497 +0,0 @@ -import java.io.*; -import java.util.*; -import java.awt.event.*; -import javax.swing.*; public class Actions { - - //declaration of the private variables used in the program - private int returnVal; - - //for JFileChooser - private int option; - - //for using it into JOptionPane - private String fileContent = null; - - //to get the text from the text area - private String fileName = null; - - //for using the name of the file - private JFileChooser jfc = new JFileChooser("."); - - //for using a open & save dialog - private ExampleFileFilter filter = new ExampleFileFilter(); - - //for filtering the file - Notepad n; - - //for using the object in the Notepad.java - public Fonts font = new Fonts(); - - - - public Actions(Notepad n){ - this.n = n; - } - - - /** - *If we want to write a new text, first we want to know if the text area is empty or not, - *second we want to know if the text was saved or not. - *If the text area isn't empty & the text wasn't saved before this time, then the program display -> - *for the user an option for saving the text in a new file or in the same file - */ - public void neW(){ - /** - *if the text area isn't empty & if the text area hasn't - *a text not saved before (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - /** - *here, we have two things, first if the text wasn't be opened or saved before - *second if the text was be opened or saved - */ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - //if the user click on YES button, - //then the program will save the text & make a new text area - if(option == 0){ - //to save the text into a new file - saveAs(); - //to create new getTextArea() after saving the old getTextArea() - n.getTextArea().setText(""); - } - //if the user click on NO button - if(option == 1){ - //to create new getTextArea() without saving the old getTextArea() - n.getTextArea().setText(""); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will save the text into the old file & - *make a new text area,,, - */ - if(option == 0){ - save(); - //to create new getTextArea() after saving the old getTextArea() - n.getTextArea().setText(""); - } - //if the user click on NO button - if(option == 1){ - //to create new getTextArea() without saving the old getTextArea() - n.getTextArea().setText(""); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to write a new text,,, this option will be actived - */ - else{ - n.getTextArea().setText(""); - } - n.setTitle("Untitled - JAVA??? Notepad"); - } - - - /** - *If we want to open a new text, first we want to know if the text area - * is empty or not, second we want to kwnow if the text was saved or not. - *If the text area isn't empty & the text wasn't saved befor this time, - *then the program display for the user an option for saving the text - *in a new file or in the same file - */ - public void opeN(){ - /** - *if the text area isn't empty & if the text area hasn't a text which - *not saved befor (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - /** - *here, we have 2 thing, first if the text wasn't be opened or saved befor - *second if the text was be opened or saved - */ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - //if the user click on YES button, - //then the program will be saved the text & opened a new documents - if(option == 0){ - //for saving the text in a new file - saveAs(); - //for opening the new documents - open(); - } - /** - *if the user click on NO button, - *the program will be opened the new documents - */ - if(option == 1){ - //for opening the new documents - open(); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will save the text into the same file & - *open the new documents - */ - if(option == 0){ - //for saving the text into the same file - save(); - //for opening the new documents - open(); - } - /** - *if the user click on NO button, - *the program will be opened the new documents - */ - if(option == 1){ - //for opening the new documents - open(); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to open a new document,,, this option will be actived - */ - else{ - //for opening the new documents - open(); - } - } - - - /** - *THIS IS FOR SAVE ACTION, SaveAs ACTION has saveAs() method - *If we want to save a new text, then we want to know - *if the text was saved befor or not. - *If the text wasn't be saved befor, then we will use saveAs() - *If the text was be save befor, then we will use save() - */ - public void savE(){ - /** - *if String fileName is null, then using saveAs(). - *Because there was no file was be saved - */ - if(fileName == null){ - saveAs(); - } - /** - *if String fileName has a String (file name), then using save(). - *Because we want to save the new text in the same file. - *if the user want to save the all text (old & new text) in a new file, -> - *he can presses SaveAs button (@saveAs()) - */ - else{ - save(); - } - } - - - /** - *THIS FROM SUN??? WEBSITE (@Print.java) - *if we want to print the text, we can do this by print method - */ - public void prinT(){ - //import printer class - Print.printComponent(n.getTextArea()); - } - - - /** - *If we want to exit from the program, - *first we want to know if the text area is empty or not, - *second we want to kwnow if the text was saved or not. - *If the text area isn't empty & the text wasn't saved befor this time, - *then the program display -> - *for the user an option for saving the text in a new file or in the same file - */ - public void exiT(){ - /** - *if the text area isn't empty & if the text area hasn't a text which - *not saved befor (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will be saved the text & close the program - */ - if(option == 0){ - //for saving the text into new file - saveAs(); - //for closing the program - System.exit(0); - } - /** - *if the user click on NO button, - *then the program will be closed without save the text - */ - if(option == 1){ - //for closing the program - System.exit(0); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will be saved the text & close the program - */ - if(option == 0){ - //for saving the text into the same file - save(); - //for closing the program - System.exit(0); - } - /** - *if the user click on NO button, - *then the program will be closed without save the text - */ - if(option == 1){ - //for closing the program - System.exit(0); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to close the program. This option will be actived - */ - else{ - //for closing the program - System.exit(0); - } - } - - - //to select all the text - public void selectALL(){ - n.getTextArea().selectAll(); - } - - - //for wraping the line & wraping the style word - public void lineWraP(){ - if(n.getLineWrap().isSelected()){ - /** - *make the line wrap & wrap style word is true - *when the line wrap is selected - */ - n.getTextArea().setLineWrap(true); - n.getTextArea().setWrapStyleWord(true); - } - else{ - /** - *make the line wrap & wrap style word is false - *when the line wrap isn't selected - */ - n.getTextArea().setLineWrap(false); - n.getTextArea().setWrapStyleWord(false); - } - } - - - /** - *@see FONTS.JAVA - *this is a font class which is for changing the font, style & size - */ - public void fonT(){ - font.setVisible(true); //setting the visible is true - font.pack(); //pack the panel - //making an action for ok button, so we can change the font - font.getOkjb().addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - n.getTextArea().setFont(font.font()); - //after we chose the font, then the JDialog will be closed - font.setVisible(false); - } - }); - //making an action for cancel button, so we can return to the old font. - font.getCajb().addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - //after we cancel the, then the JDialog will be closed - font.setVisible(false); - } - }); - } - - - /** - *@see ABOUT.JAVA - *it's a Message Dialog to show the information about this program - */ - public void abouT(){ - JOptionPane.showMessageDialog(null, new About(),"About Notepad",JOptionPane.PLAIN_MESSAGE); - } - - - /** - *THIS IS THE WAY FOR OPENING THE TEXT FILE - */ - public void open(){ - //filter the kind of files, we want only TXT file - filter.addExtension("txt"); - //to set a description for the file (TXT) - filter.setDescription("TXT Documents"); - //setting the FileFilter to JFileChooser - jfc.setFileFilter(filter); - returnVal = jfc.showOpenDialog(n); //to show JFileChooser - if(returnVal == JFileChooser.APPROVE_OPTION){ - //to erase any text in the text area before adding new text - n.getTextArea().setText(null); - try{ - //to get the name of the selected file - fileName = jfc.getSelectedFile().getPath(); - //to read the selected file - Reader in = new FileReader(jfc.getSelectedFile()); - //100000 is the max. char can be written in the text area - char[] buff = new char[100000]; - int nch; - while((nch = in.read(buff, 0, buff.length)) != -1) - n.getTextArea().append(new String(buff, 0, nch)); - //to get more text from the file if the array wasn't full - fileContent = n.getTextArea().getText(); - } - catch(FileNotFoundException x){} - catch(IOException ioe){ - System.err.println("I/O Error on Open"); - } - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - /** - *THIS IS THE WAY FOR SAVING THE TEXT IN THE SAME FILE - */ - public void save(){ - //initializing 'fout' to write all text in the selected file - try{ - PrintWriter fout = new PrintWriter(new FileWriter(jfc.getSelectedFile())); - //for getting the text from the text area - fileContent = n.getTextArea().getText(); - //using StringTokenizer for the 'fileContent' String - StringTokenizer st=new StringTokenizer(fileContent,System.getProperty("line.separator")); - while(st.hasMoreTokens()){ - //write the string (text) in the selected file - fout.println(st.nextToken()); - } - //closing fout - fout.close(); - } - catch(IOException ioe){ - System.err.println("I/O Error on Save"); - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - /** - *THIS IS THE WAY FOR SAVING THE TEXT IN A NEW FILE - */ - public void saveAs(){ - //filter the kind of files, we want only TXT file - filter.addExtension("txt"); - //to set a description for the file (TXT) - filter.setDescription("TXT Documents"); - //setting the FileFilter to JFileChooser - jfc.setFileFilter(filter); - returnVal = jfc.showSaveDialog(n); - if(returnVal == JFileChooser.APPROVE_OPTION){ - //initializing the PrintWriter, to save the text in a new file - PrintWriter fout = null; - try{ - fout = new PrintWriter(new FileWriter(jfc.getSelectedFile() + ".txt")); - //getting the text from the text area - fileContent = n.getTextArea().getText(); - //getting the name of the selected file - fileName = jfc.getSelectedFile().getPath(); - //using StringTokenizer for the 'fileContent' String - StringTokenizer st=new StringTokenizer(fileContent,System.getProperty("line.separator")); - while(st.hasMoreTokens()){ - //write the string (text) in the selected file - fout.println(st.nextToken()); - } - //closing 'fout' - fout.close(); - } - catch(IOException ioe){ - System.err.println ("I/O Error on Save"); - } - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - private String findword; - - //for searching & finding the word - //this is a method for searching the input text from the text area - - public void finD(){ - try{ - //this is an input dialog which return a string (findword) - findword = JOptionPane.showInputDialog("Type the word to find"); - //if the JTextField in the input dialog is empty (null), then return a message dialog - while(n.getTextArea().getText().indexOf(findword) == -1){ - /** - *this is a message dialog which is warning the user, - *because he didn't or forgot to enter the word - */ - JOptionPane.showMessageDialog(null,"Word not found!","No match",JOptionPane.WARNING_MESSAGE); - findword = JOptionPane.showInputDialog("Type the word to find"); - } - //for selecting the word which the user search for it - n.getTextArea().select(n.getTextArea().getText().indexOf(findword), - n.getTextArea().getText().indexOf(findword) + findword.length()); - } - catch(Exception ex){ - JOptionPane.showMessageDialog(null,"Search canceled","Abourted",JOptionPane.WARNING_MESSAGE); - } - } - - - public void findNexT(){ - n.getTextArea().select(n.getTextArea().getText().indexOf(findword,(int)n.getTextArea().getText().indexOf(findword)+1), - n.getTextArea().getText().indexOf(findword,(int)n.getTextArea().getText().indexOf(findword)+1)); - } - - -} diff --git a/java/spl/notepad/Variant00003java/Center.java b/java/spl/notepad/Variant00003java/Center.java deleted file mode 100644 index 1715525..0000000 --- a/java/spl/notepad/Variant00003java/Center.java +++ /dev/null @@ -1,37 +0,0 @@ -import java.awt.*; -/** - *A PUBLIC CLASS FOR CENTER.JAVA - */ -public class Center { - - Notepad n; - - //for using the object in the Notepad.java - Fonts f; - - //for using the object in the Fonts.java - public Center(Notepad n){ - this.n = n; - } - - - public Center(Fonts f){ - this.f = f; - } - - - public void nCenter(){ - //Centering the window - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - n.setLocation((screenSize.width-n.getWidth())/2,(screenSize.height-n.getHeight())/2); - } - - - public void fCenter(){ - //Centering the window - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - f.setLocation((screenSize.width-f.getWidth())/2,(screenSize.height-f.getHeight())/2); - } - - -} diff --git a/java/spl/notepad/Variant00003java/ExampleFileFilter.java b/java/spl/notepad/Variant00003java/ExampleFileFilter.java deleted file mode 100644 index 47b0dd6..0000000 --- a/java/spl/notepad/Variant00003java/ExampleFileFilter.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (c) 2002 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * -Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * -Redistribution in binary form must reproduct the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING - * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT - * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT - * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS - * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST - * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, - * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY - * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN - * IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that Software is not designed, licensed or intended for - * use in the design, construction, operation or maintenance of any nuclear - * facility. - */ - -/* - * @(#)ExampleFileFilter.java 1.13 02/06/13 - */ - - - -//import the packages for using the classes in them into the program -import java.io.File; -import java.util.Hashtable; -import java.util.Enumeration; -import javax.swing.filechooser.*; - -/** - * A convenience implementation of FileFilter that filters out - * all files except for those type extensions that it knows about. - * - * Extensions are of the type ".foo", which is typically found on - * Windows and Unix boxes, but not on Macinthosh. Case is ignored. - * - * Example - create a new filter that filerts out all files - * but gif and jpg image files: - * - * JFileChooser chooser = new JFileChooser(); - * ExampleFileFilter filter = new ExampleFileFilter( - * new String{"gif", "jpg"}, "JPEG & GIF Images") - * chooser.addChoosableFileFilter(filter); - * chooser.showOpenDialog(this); - * - * @version 1.13 06/13/02 - * @author Jeff Dinkins - */ -public class ExampleFileFilter extends FileFilter { - - -// private static String TYPE_UNKNOWN = "Type Unknown"; -// private static String HIDDEN_FILE = "Hidden File"; - - private Hashtable filters = null; - - - private String description = null; - - - private String fullDescription = null; - - - private boolean useExtensionsInDescription = true; - - - - /** - * Creates a file filter. If no filters are added, then all - * files are accepted. - * - * @see #addExtension - */ - public ExampleFileFilter(){ - this.filters = new Hashtable(); - } - - - - /** - * Creates a file filter that accepts files with the given extension. - * Example: new ExampleFileFilter("jpg"); - * - * @see #addExtension - */ - public ExampleFileFilter(String extension){ - this(extension,null); - } - - - - /** - * Creates a file filter that accepts the given file type. - * Example: new ExampleFileFilter("jpg", "JPEG Image Images"); - * - * Note that the "." before the extension is not needed. If - * provided, it will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String extension, String description){ - this(); - if(extension!=null) addExtension(extension); - if(description!=null) setDescription(description); - } - - - - /** - * Creates a file filter from the given string array. - * Example: new ExampleFileFilter(String {"gif", "jpg"}); - * - * Note that the "." before the extension is not needed adn - * will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String[] filters){ - this(filters, null); - } - - - - /** - * Creates a file filter from the given string array and description. - * Example: new ExampleFileFilter(String {"gif", "jpg"}, "Gif and JPG Images"); - * - * Note that the "." before the extension is not needed and will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String[] filters, String description){ - this(); - for (int i = 0; i < filters.length; i++){ - // add filters one by one - addExtension(filters[i]); - } - if(description!=null) setDescription(description); - } - - - - /** - * Return true if this file should be shown in the directory pane, - * false if it shouldn't. - * - * Files that begin with "." are ignored. - * - * @see #getExtension - * @see FileFilter#accepts - */ - public boolean accept(File f){ - if(f != null){ - if(f.isDirectory()){ - return true; - } - String extension = getExtension(f); - if(extension != null && filters.get(getExtension(f)) != null){ - return true; - }; - } - return false; - } - - - - /** - * Return the extension portion of the file's name . - * - * @see #getExtension - * @see FileFilter#accept - */ - public String getExtension(File f){ - if(f != null){ - String filename = f.getName(); - int i = filename.lastIndexOf('.'); - if(i>0 && i(5); - } - filters.put(extension.toLowerCase(), this); - fullDescription = null; - } - - - - /** - * Returns the human readable description of this filter. For - * example: "JPEG and GIF Image Files (*.jpg, *.gif)" - * - * @see setDescription - * @see setExtensionListInDescription - * @see isExtensionListInDescription - * @see FileFilter#getDescription - */ - @SuppressWarnings("rawtypes") - public String getDescription(){ - if(fullDescription == null) { - if(description == null || isExtensionListInDescription()){ - fullDescription = description==null ? "(" : description + " ("; - // build the description from the extension list - Enumeration extensions = filters.keys(); - if(extensions != null){ - fullDescription += "." + (String) extensions.nextElement(); - while (extensions.hasMoreElements()) { - fullDescription += ", ." + (String) extensions.nextElement(); - } - } - fullDescription += ")"; - } else { - fullDescription = description; - } - } - return fullDescription; - } - - - - /** - * Sets the human readable description of this filter. For - * example: filter.setDescription("Gif and JPG Images"); - * - * @see setDescription - * @see setExtensionListInDescription - * @see isExtensionListInDescription - */ - public void setDescription(String description){ - this.description = description; - fullDescription = null; - } - - - - /** - * Determines whether the extension list (.jpg, .gif, etc) should - * show up in the human readable description. - * - * Only relevent if a description was provided in the constructor - * or using setDescription(); - * - * @see getDescription - * @see setDescription - * @see isExtensionListInDescription - */ - public void setExtensionListInDescription(boolean b){ - useExtensionsInDescription = b; - fullDescription = null; - } - - - - /** - * Returns whether the extension list (.jpg, .gif, etc) should - * show up in the human readable description. - * - * Only relevent if a description was provided in the constructor - * or using setDescription(); - * - * @see getDescription - * @see setDescription - * @see setExtensionListInDescription - */ - public boolean isExtensionListInDescription(){ - return useExtensionsInDescription; - } - - -} diff --git a/java/spl/notepad/Variant00003java/Fonts.java b/java/spl/notepad/Variant00003java/Fonts.java deleted file mode 100644 index e63be0b..0000000 --- a/java/spl/notepad/Variant00003java/Fonts.java +++ /dev/null @@ -1,136 +0,0 @@ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - -/** - *A class for creating JFontDialog - */ -public class Fonts extends JDialog { - - private static final long serialVersionUID = 1L; - - - /** - *@see Center.java - *this class to make the JDialog in the center - */ - public Center center = new Center(this); - - - - //declaration of the private variables used in the program - private JPanel jp = new JPanel(); - - - private JLabel fjl = new JLabel("Fonts: "); - - - private JComboBox fjcb = new JComboBox(); - - - /** - *-> GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames() <- - * WE USING THIS METHOD TO GET ALL FONT IN THE SYSTEM (OS) - */ - private String fonts[]=GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); - - - private JLabel sjl = new JLabel("Sizes: "); - - - private JComboBox sjcb = new JComboBox(); - - - private String sizes[] = {"8","10","12","14","16","18","20","24","28","32","48","72"}; - - - private JLabel tjl = new JLabel("Types: "); - - - private JComboBox tjcb = new JComboBox(); - - - private String types[] = {"Regular", "Bold", "Italic", "Bold Italic"}; - - - private JLabel jjl = new JLabel("Preview:"); - - - private JLabel jl = new JLabel("AaBaCcDdeEfFgGhHjJ"); - - - private JButton okjb = new JButton("OK"); - - - private JButton cajb = new JButton("Cancel"); - - - //for using ok & cancel button @Actions.java - public JButton getOkjb(){ - return okjb; - } - - - public JButton getCajb(){ - return cajb; - } - - - //Constructor of Fonts - public Fonts(){ - //for setting the title - setTitle("Font Dialog"); - setResizable(false); - /** - *setting the layout (GridLayout: 5 rows & 2 columns) - *add font JLabel, add font JComboBox - *add type JLabel, add type JComboBox - *add size JLabel, add size JComboBox - *add preview JLabel,add test JLabel - *add ok button, add cancel button - */ - jp.setLayout(new GridLayout(5,2,1,1)); - jp.add(fjl); - jp.add(fjcb = new JComboBox(fonts)); - jp.add(sjl); - jp.add(sjcb = new JComboBox(sizes)); - jp.add(tjl); - jp.add(tjcb = new JComboBox(types)); - jp.add(jjl); - jl.setBorder(BorderFactory.createEtchedBorder()); - jp.add(jl); - jp.add(okjb); - jp.add(cajb); - //add JPanel to the Container - this.getContentPane().add(jp); - /** - *for making JDialog at the center, - *@Center.java - */ - center.fCenter(); - //add action listener to Font JComboBox to get the selected item for setting the preview - fjcb.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - jl.setFont(new Font(String.valueOf(fjcb.getSelectedItem()),tjcb.getSelectedIndex(),14)); - } - }); - //add action listener to Type JComboBox to get the selected index for setting the preview - tjcb.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - jl.setFont(new Font(String.valueOf(fjcb.getSelectedItem()),tjcb.getSelectedIndex(),14)); - } - }); - } - - - /* - *@return font value: (Font,Type,Size) - */ - public Font font(){ - Font font = new Font(String.valueOf(fjcb.getSelectedItem()), tjcb.getSelectedIndex(), - Integer.parseInt(String.valueOf(sjcb.getSelectedItem()))); - return font; - } - - -} diff --git a/java/spl/notepad/Variant00003java/Notepad.java b/java/spl/notepad/Variant00003java/Notepad.java deleted file mode 100644 index 497930c..0000000 --- a/java/spl/notepad/Variant00003java/Notepad.java +++ /dev/null @@ -1,342 +0,0 @@ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import javax.swing.event.*; - -public - -class Notepad extends JFrame { - - private static final long serialVersionUID = 1; - - - //for using the methods in these classes - public Actions actions = new Actions(this); - - - public Center center = new Center(this); - - - - //declaration of the private variables used in the program - //create the text area - private JTextArea textArea; - - - //create the Menu Bar that contains the JMenu "filE, ediT, vieW, formaT, helP" - private JMenuBar Menubar; - - - //Create the menu that contains the items - private JMenu filE, ediT, vieW, formaT, helP; - - - //Create the menu items - private JMenuItem neW, opeN, savE, saveAS, prinT, exiT, fonT, abouT, - cuT, copY, pastE, selectALL; - - - private JCheckBoxMenuItem lineWraP; - - - //Create the Tool Bar that contains the JButton - private JToolBar toolBar; - - - //Create the buttons - private JButton newButton, openButton, saveButton, saveAsButton, printButton, - fontButton, aboutButton; - - - - //for using lineWrap & textArea @Actions.java - public JCheckBoxMenuItem getLineWrap(){ - return lineWraP; - } - - - public JTextArea getTextArea(){ - return textArea; - } - - - - public Notepad (){ - //set the title for Notepad and set the size for it. - setTitle("Untitled - JAVA??? Notepad"); - setSize(800,600); - - //get the graphical user interface components display area - Container cp = getContentPane(); - /** - *adding the text area, - *adding the tool bar & - *adding the scroll pane to the container - */ - cp.add(textArea = new JTextArea()); - cp.add("North", toolBar = new JToolBar("Tool Bar")); - cp.add(new JScrollPane(textArea)); - - //for setting the menu bar - setJMenuBar(Menubar= new JMenuBar()); - //adding file, edit, view, format, help to the menu bar - Menubar.add(filE = new JMenu("File")); - Menubar.add(ediT = new JMenu("Edit")); - Menubar.add(vieW = new JMenu("View")); - Menubar.add(formaT = new JMenu("Format")); - Menubar.add(helP = new JMenu("Help")); - - /** - *adding neW, opeN, savE, saveAS, prinT & exiT to the filE Menu, - *adding a small image icon to the menu item & - *adding separator between the menu item - */ - filE.add(neW = new JMenuItem("New", new ImageIcon(this.getClass().getResource("images/new.gif")))); - filE.add(opeN = new JMenuItem("Open", new ImageIcon(this.getClass().getResource("images/open.gif")))); - filE.add(savE = new JMenuItem("Save", new ImageIcon(this.getClass().getResource("images/save.gif")))); - filE.add(saveAS = new JMenuItem("Save As", new ImageIcon(this.getClass().getResource("images/saveAs.gif")))); - filE.add(prinT = new JMenuItem("Print", new ImageIcon(this.getClass().getResource("images/print.gif")))); - filE.add(exiT = new JMenuItem("Exit")); //, new ImageIcon(this.getClass().getResource("images/exit.gif")))); -- exit.gif missing - filE.insertSeparator(4); - filE.insertSeparator(6); - - /** - *adding undO, redO, cuT, copY, pastE, finD, findNexT & selectALL to the ediT Menu, - *adding a small image icon to the menu item & - *adding separator between the menu item - */ - ediT.add(selectALL= new JMenuItem("Select All")); - //ediT.insertSeparator(2); - //ediT.insertSeparator(6); - - /** - *adding lineWraP & fonT to the formaT Menu, - *adding abouT to the helP Menu & - *adding a small image icon to the menu item - */ - formaT.add(lineWraP = new JCheckBoxMenuItem("Line Wrap")); - formaT.add(fonT = new JMenuItem("Font", new ImageIcon(this.getClass().getResource("images/font.gif")))); - helP.add(abouT = new JMenuItem("About Notepad", new ImageIcon(this.getClass().getResource("images/about.gif")))); - - /** - *allowing the file menu to be selected by pressing ALT + F - *allowing the edit menu to be selected by pressing ALT + E - *allowing the view menu to be selected by pressing ALT + V - *allowing the format menu to be selected by pressing ALT + O - *allowing the help menu to be selected by pressing ALT + H - */ - filE.setMnemonic('f'); - ediT.setMnemonic('e'); - vieW.setMnemonic('v'); - formaT.setMnemonic('o'); - helP.setMnemonic('h'); - - /** - *allowing the neW menu item to be selected by pressing ALT + N - *allowing the opeN menu item to be selected by pressing ALT + O - *allowing the savE menu item to be selected by pressing ALT + S - *allowing the prinT menu item to be selected by pressing ALT + P - *allowing the exiT menu item to be selected by pressing ALT + F4 - *allowing the cuT menu item to be selected by pressing ALT + X - *allowing the copY menu item to be selected by pressing ALT + C - *allowing the pastE menu item to be selected by pressing ALT + V - *allowing the selectAll menu item to be selected by pressing ALT + A - */ - neW.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK)); - opeN.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK)); - savE.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK)); - prinT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.CTRL_MASK)); - exiT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, ActionEvent.CTRL_MASK)); - selectALL.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.CTRL_MASK)); - - /** - *adding newButton, openButton, saveButton, saveAsButton, printButton, undoButton, - *redoButton, cutButton, copyButton, pasteButton, fontButton & aboutButton to the tool bar, - *adding a small image icon to the menu item & - *adding separator between the button - */ - toolBar.add(newButton = new JButton(new ImageIcon(this.getClass().getResource("images/new.gif")))); - toolBar.add(openButton = new JButton(new ImageIcon(this.getClass().getResource("images/open.gif")))); - toolBar.add(saveButton = new JButton(new ImageIcon(this.getClass().getResource("images/save.gif")))); - toolBar.add(saveAsButton= new JButton(new ImageIcon(this.getClass().getResource("images/saveAs.gif")))); - toolBar.add(printButton = new JButton(new ImageIcon(this.getClass().getResource("images/print.gif")))); - toolBar.addSeparator(); - toolBar.add(fontButton = new JButton(new ImageIcon(this.getClass().getResource("images/font.gif")))); - toolBar.add(aboutButton = new JButton(new ImageIcon(this.getClass().getResource("images/about.gif")))); - - //adding a tool tip text to the button for descriping the image icon. - newButton.setToolTipText("New"); - openButton.setToolTipText("Open"); - saveButton.setToolTipText("Save"); - saveAsButton.setToolTipText("Save As"); - printButton.setToolTipText("Print"); - fontButton.setToolTipText("Font"); - aboutButton.setToolTipText("About Notepad"); - - /** - *setting the default close operation to false & - *using own action (exiT action @Actions.java) - */ - setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); - addWindowListener(new WindowAdapter(){ - public void windowClosing(WindowEvent e){ - actions.exiT(); - } - }); - /** - *adding action listener for menu item: neW, opeN, savE, saveAS, prinT, exiT, - *redO, undO, copY, cuT, pastE, finD, findNexT, selectALL, lineWraP, fonT & abouT - *the actions was written @Actions.java - */ - neW.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.neW(); - } - }); - opeN.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.opeN(); - } - }); - savE.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.savE(); - } - }); - saveAS.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.saveAs(); - } - }); - prinT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.prinT(); - } - }); - exiT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.exiT(); - } - }); - selectALL.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.selectALL(); - } - }); - lineWraP.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.lineWraP(); - } - }); - fonT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.fonT(); - } - }); - abouT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.abouT(); - } - }); - - /** - *adding action listener for the button in the tool bar: newButton, openButton, - *saveButton, saveAsButton, printButton, redoButton, undoButton, copyButton, - *cutButton, pasteButton, findButton, selectALL, lineWraP, fontButton & aboutButton - *the actions was written @Actions.java - */ - newButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.neW(); - } - }); - openButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.opeN(); - } - }); - saveButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.savE(); - } - }); - saveAsButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.saveAs(); - } - }); - printButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.prinT(); - } - }); - fontButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.fonT(); - } - }); - aboutButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.abouT(); - } - }); - - /** - *Setting the Line Wrap & Wrap Style Word features are true - */ - textArea.setLineWrap(true); - textArea.setWrapStyleWord(true); - /** - *for making the program at the center, - *@see Center.java - */ - center.nCenter(); - show(); - - ediT.add(finD = new JMenuItem("Find", new ImageIcon(this.getClass().getResource("images/find.gif")))); - ediT.add(findNexT = new JMenuItem("Find Next")); - //ediT.insertSeparator(8); - - /** - *allowing the finD menu item to be selected by pressing ALT + F - *allowing the findNexT menu item to be selected by pressing ALT + F3 - */ - finD.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F, ActionEvent.CTRL_MASK)); - findNexT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F3, ActionEvent.CTRL_MASK)); - toolBar.add(findButton = new JButton(new ImageIcon(this.getClass().getResource("images/find.gif")))); - findButton.setToolTipText("Find"); - - finD.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.finD(); - } - }); - findNexT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.findNexT(); - } - }); - - findButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.finD(); - } - }); - } - - - //Main Method - public static void main(String[] args){ - new Notepad(); - - } - - - - private JButton findButton; - - - private JMenuItem finD, findNexT; - - -} diff --git a/java/spl/notepad/Variant00003java/Print.java b/java/spl/notepad/Variant00003java/Print.java deleted file mode 100644 index 132daed..0000000 --- a/java/spl/notepad/Variant00003java/Print.java +++ /dev/null @@ -1,64 +0,0 @@ -import java.awt.*; -import java.awt.print.*; -import javax.swing.*; - -/** - *A class for creating a printer option. - */ -public class Print implements Printable { - - private Component componentToBePrinted; - - - - public static void printComponent(Component c){ - new Print(c).print(); - } - - - public Print(Component componentToBePrinted){ - this.componentToBePrinted = componentToBePrinted; - } - - - public void print(){ - PrinterJob printJob = PrinterJob.getPrinterJob(); - printJob.setPrintable(this); - if(printJob.printDialog()) - try{ - printJob.print(); - } - catch(PrinterException pe){ - System.out.println("Error printing: " + pe); - } - } - - - public int print(Graphics g, PageFormat pageFormat, int pageIndex){ - if(pageIndex > 0){ - return(NO_SUCH_PAGE); - } - else{ - Graphics2D g2d = (Graphics2D)g; - g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); - disableDoubleBuffering(componentToBePrinted); - componentToBePrinted.paint(g2d); - enableDoubleBuffering(componentToBePrinted); - return(PAGE_EXISTS); - } - } - - - public static void disableDoubleBuffering(Component c){ - RepaintManager currentManager = RepaintManager.currentManager(c); - currentManager.setDoubleBufferingEnabled(false); - } - - - public static void enableDoubleBuffering(Component c){ - RepaintManager currentManager = RepaintManager.currentManager(c); - currentManager.setDoubleBufferingEnabled(true); - } - - -} diff --git a/java/spl/notepad/Variant00004java/About.java b/java/spl/notepad/Variant00004java/About.java deleted file mode 100644 index fb751fd..0000000 --- a/java/spl/notepad/Variant00004java/About.java +++ /dev/null @@ -1,25 +0,0 @@ -import javax.swing.*; - -/** - *A CLASS FOR CREATING ABOUT PANEL - */ -public class About extends JPanel { - - private static final long serialVersionUID = 1; - - - public About(){ - //Create a Label & an image icon in it - JLabel label1 = new JLabel(new ImageIcon(this.getClass().getResource("images/java.gif"))); - //adding label1 to the JPanel - this.add(label1); - //Create a Label & put a HTML script - JLabel label2 = new JLabel("
  • JAVA??? Notepad
  • Ver# 2.0

  • " - +"
  • Coded by: Salah Al-Thubaiti

  • KFUPM, CS

  • " - +"

    CopyRight??? 2001-2002

  • "); - //adding label2 to the JPanel - this.add(label2); - } - - -} diff --git a/java/spl/notepad/Variant00004java/Actions.java b/java/spl/notepad/Variant00004java/Actions.java deleted file mode 100644 index b97e1f5..0000000 --- a/java/spl/notepad/Variant00004java/Actions.java +++ /dev/null @@ -1,515 +0,0 @@ -import java.io.*; -import java.util.*; -import java.awt.event.*; -import javax.swing.*; public class Actions { - - //declaration of the private variables used in the program - private int returnVal; - - //for JFileChooser - private int option; - - //for using it into JOptionPane - private String fileContent = null; - - //to get the text from the text area - private String fileName = null; - - //for using the name of the file - private JFileChooser jfc = new JFileChooser("."); - - //for using a open & save dialog - private ExampleFileFilter filter = new ExampleFileFilter(); - - //for filtering the file - Notepad n; - - //for using the object in the Notepad.java - public Fonts font = new Fonts(); - - - - public Actions(Notepad n){ - this.n = n; - } - - - /** - *If we want to write a new text, first we want to know if the text area is empty or not, - *second we want to know if the text was saved or not. - *If the text area isn't empty & the text wasn't saved before this time, then the program display -> - *for the user an option for saving the text in a new file or in the same file - */ - public void neW(){ - /** - *if the text area isn't empty & if the text area hasn't - *a text not saved before (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - /** - *here, we have two things, first if the text wasn't be opened or saved before - *second if the text was be opened or saved - */ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - //if the user click on YES button, - //then the program will save the text & make a new text area - if(option == 0){ - //to save the text into a new file - saveAs(); - //to create new getTextArea() after saving the old getTextArea() - n.getTextArea().setText(""); - } - //if the user click on NO button - if(option == 1){ - //to create new getTextArea() without saving the old getTextArea() - n.getTextArea().setText(""); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will save the text into the old file & - *make a new text area,,, - */ - if(option == 0){ - save(); - //to create new getTextArea() after saving the old getTextArea() - n.getTextArea().setText(""); - } - //if the user click on NO button - if(option == 1){ - //to create new getTextArea() without saving the old getTextArea() - n.getTextArea().setText(""); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to write a new text,,, this option will be actived - */ - else{ - n.getTextArea().setText(""); - } - n.setTitle("Untitled - JAVA??? Notepad"); - } - - - /** - *If we want to open a new text, first we want to know if the text area - * is empty or not, second we want to kwnow if the text was saved or not. - *If the text area isn't empty & the text wasn't saved befor this time, - *then the program display for the user an option for saving the text - *in a new file or in the same file - */ - public void opeN(){ - /** - *if the text area isn't empty & if the text area hasn't a text which - *not saved befor (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - /** - *here, we have 2 thing, first if the text wasn't be opened or saved befor - *second if the text was be opened or saved - */ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - //if the user click on YES button, - //then the program will be saved the text & opened a new documents - if(option == 0){ - //for saving the text in a new file - saveAs(); - //for opening the new documents - open(); - } - /** - *if the user click on NO button, - *the program will be opened the new documents - */ - if(option == 1){ - //for opening the new documents - open(); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will save the text into the same file & - *open the new documents - */ - if(option == 0){ - //for saving the text into the same file - save(); - //for opening the new documents - open(); - } - /** - *if the user click on NO button, - *the program will be opened the new documents - */ - if(option == 1){ - //for opening the new documents - open(); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to open a new document,,, this option will be actived - */ - else{ - //for opening the new documents - open(); - } - } - - - /** - *THIS IS FOR SAVE ACTION, SaveAs ACTION has saveAs() method - *If we want to save a new text, then we want to know - *if the text was saved befor or not. - *If the text wasn't be saved befor, then we will use saveAs() - *If the text was be save befor, then we will use save() - */ - public void savE(){ - /** - *if String fileName is null, then using saveAs(). - *Because there was no file was be saved - */ - if(fileName == null){ - saveAs(); - } - /** - *if String fileName has a String (file name), then using save(). - *Because we want to save the new text in the same file. - *if the user want to save the all text (old & new text) in a new file, -> - *he can presses SaveAs button (@saveAs()) - */ - else{ - save(); - } - } - - - /** - *THIS FROM SUN??? WEBSITE (@Print.java) - *if we want to print the text, we can do this by print method - */ - public void prinT(){ - //import printer class - Print.printComponent(n.getTextArea()); - } - - - /** - *If we want to exit from the program, - *first we want to know if the text area is empty or not, - *second we want to kwnow if the text was saved or not. - *If the text area isn't empty & the text wasn't saved befor this time, - *then the program display -> - *for the user an option for saving the text in a new file or in the same file - */ - public void exiT(){ - /** - *if the text area isn't empty & if the text area hasn't a text which - *not saved befor (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will be saved the text & close the program - */ - if(option == 0){ - //for saving the text into new file - saveAs(); - //for closing the program - System.exit(0); - } - /** - *if the user click on NO button, - *then the program will be closed without save the text - */ - if(option == 1){ - //for closing the program - System.exit(0); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will be saved the text & close the program - */ - if(option == 0){ - //for saving the text into the same file - save(); - //for closing the program - System.exit(0); - } - /** - *if the user click on NO button, - *then the program will be closed without save the text - */ - if(option == 1){ - //for closing the program - System.exit(0); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to close the program. This option will be actived - */ - else{ - //for closing the program - System.exit(0); - } - } - - - //to select all the text - public void selectALL(){ - n.getTextArea().selectAll(); - } - - - //for wraping the line & wraping the style word - public void lineWraP(){ - if(n.getLineWrap().isSelected()){ - /** - *make the line wrap & wrap style word is true - *when the line wrap is selected - */ - n.getTextArea().setLineWrap(true); - n.getTextArea().setWrapStyleWord(true); - } - else{ - /** - *make the line wrap & wrap style word is false - *when the line wrap isn't selected - */ - n.getTextArea().setLineWrap(false); - n.getTextArea().setWrapStyleWord(false); - } - } - - - /** - *@see FONTS.JAVA - *this is a font class which is for changing the font, style & size - */ - public void fonT(){ - font.setVisible(true); //setting the visible is true - font.pack(); //pack the panel - //making an action for ok button, so we can change the font - font.getOkjb().addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - n.getTextArea().setFont(font.font()); - //after we chose the font, then the JDialog will be closed - font.setVisible(false); - } - }); - //making an action for cancel button, so we can return to the old font. - font.getCajb().addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - //after we cancel the, then the JDialog will be closed - font.setVisible(false); - } - }); - } - - - /** - *@see ABOUT.JAVA - *it's a Message Dialog to show the information about this program - */ - public void abouT(){ - JOptionPane.showMessageDialog(null, new About(),"About Notepad",JOptionPane.PLAIN_MESSAGE); - } - - - /** - *THIS IS THE WAY FOR OPENING THE TEXT FILE - */ - public void open(){ - //filter the kind of files, we want only TXT file - filter.addExtension("txt"); - //to set a description for the file (TXT) - filter.setDescription("TXT Documents"); - //setting the FileFilter to JFileChooser - jfc.setFileFilter(filter); - returnVal = jfc.showOpenDialog(n); //to show JFileChooser - if(returnVal == JFileChooser.APPROVE_OPTION){ - //to erase any text in the text area before adding new text - n.getTextArea().setText(null); - try{ - //to get the name of the selected file - fileName = jfc.getSelectedFile().getPath(); - //to read the selected file - Reader in = new FileReader(jfc.getSelectedFile()); - //100000 is the max. char can be written in the text area - char[] buff = new char[100000]; - int nch; - while((nch = in.read(buff, 0, buff.length)) != -1) - n.getTextArea().append(new String(buff, 0, nch)); - //to get more text from the file if the array wasn't full - fileContent = n.getTextArea().getText(); - } - catch(FileNotFoundException x){} - catch(IOException ioe){ - System.err.println("I/O Error on Open"); - } - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - /** - *THIS IS THE WAY FOR SAVING THE TEXT IN THE SAME FILE - */ - public void save(){ - //initializing 'fout' to write all text in the selected file - try{ - PrintWriter fout = new PrintWriter(new FileWriter(jfc.getSelectedFile())); - //for getting the text from the text area - fileContent = n.getTextArea().getText(); - //using StringTokenizer for the 'fileContent' String - StringTokenizer st=new StringTokenizer(fileContent,System.getProperty("line.separator")); - while(st.hasMoreTokens()){ - //write the string (text) in the selected file - fout.println(st.nextToken()); - } - //closing fout - fout.close(); - } - catch(IOException ioe){ - System.err.println("I/O Error on Save"); - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - /** - *THIS IS THE WAY FOR SAVING THE TEXT IN A NEW FILE - */ - public void saveAs(){ - //filter the kind of files, we want only TXT file - filter.addExtension("txt"); - //to set a description for the file (TXT) - filter.setDescription("TXT Documents"); - //setting the FileFilter to JFileChooser - jfc.setFileFilter(filter); - returnVal = jfc.showSaveDialog(n); - if(returnVal == JFileChooser.APPROVE_OPTION){ - //initializing the PrintWriter, to save the text in a new file - PrintWriter fout = null; - try{ - fout = new PrintWriter(new FileWriter(jfc.getSelectedFile() + ".txt")); - //getting the text from the text area - fileContent = n.getTextArea().getText(); - //getting the name of the selected file - fileName = jfc.getSelectedFile().getPath(); - //using StringTokenizer for the 'fileContent' String - StringTokenizer st=new StringTokenizer(fileContent,System.getProperty("line.separator")); - while(st.hasMoreTokens()){ - //write the string (text) in the selected file - fout.println(st.nextToken()); - } - //closing 'fout' - fout.close(); - } - catch(IOException ioe){ - System.err.println ("I/O Error on Save"); - } - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - //to cut the selected text - public void cuT(){ - n.getTextArea().cut(); - } - - - //to copy the selected text - public void copY(){ - n.getTextArea().copy(); - } - - - //to paste the selected text - public void pastE(){ - n.getTextArea().paste(); - } - - - private String findword; - - //for searching & finding the word - //this is a method for searching the input text from the text area - - public void finD(){ - try{ - //this is an input dialog which return a string (findword) - findword = JOptionPane.showInputDialog("Type the word to find"); - //if the JTextField in the input dialog is empty (null), then return a message dialog - while(n.getTextArea().getText().indexOf(findword) == -1){ - /** - *this is a message dialog which is warning the user, - *because he didn't or forgot to enter the word - */ - JOptionPane.showMessageDialog(null,"Word not found!","No match",JOptionPane.WARNING_MESSAGE); - findword = JOptionPane.showInputDialog("Type the word to find"); - } - //for selecting the word which the user search for it - n.getTextArea().select(n.getTextArea().getText().indexOf(findword), - n.getTextArea().getText().indexOf(findword) + findword.length()); - } - catch(Exception ex){ - JOptionPane.showMessageDialog(null,"Search canceled","Abourted",JOptionPane.WARNING_MESSAGE); - } - } - - - public void findNexT(){ - n.getTextArea().select(n.getTextArea().getText().indexOf(findword,(int)n.getTextArea().getText().indexOf(findword)+1), - n.getTextArea().getText().indexOf(findword,(int)n.getTextArea().getText().indexOf(findword)+1)); - } - - -} diff --git a/java/spl/notepad/Variant00004java/Center.java b/java/spl/notepad/Variant00004java/Center.java deleted file mode 100644 index 1715525..0000000 --- a/java/spl/notepad/Variant00004java/Center.java +++ /dev/null @@ -1,37 +0,0 @@ -import java.awt.*; -/** - *A PUBLIC CLASS FOR CENTER.JAVA - */ -public class Center { - - Notepad n; - - //for using the object in the Notepad.java - Fonts f; - - //for using the object in the Fonts.java - public Center(Notepad n){ - this.n = n; - } - - - public Center(Fonts f){ - this.f = f; - } - - - public void nCenter(){ - //Centering the window - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - n.setLocation((screenSize.width-n.getWidth())/2,(screenSize.height-n.getHeight())/2); - } - - - public void fCenter(){ - //Centering the window - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - f.setLocation((screenSize.width-f.getWidth())/2,(screenSize.height-f.getHeight())/2); - } - - -} diff --git a/java/spl/notepad/Variant00004java/ExampleFileFilter.java b/java/spl/notepad/Variant00004java/ExampleFileFilter.java deleted file mode 100644 index 47b0dd6..0000000 --- a/java/spl/notepad/Variant00004java/ExampleFileFilter.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (c) 2002 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * -Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * -Redistribution in binary form must reproduct the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING - * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT - * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT - * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS - * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST - * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, - * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY - * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN - * IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that Software is not designed, licensed or intended for - * use in the design, construction, operation or maintenance of any nuclear - * facility. - */ - -/* - * @(#)ExampleFileFilter.java 1.13 02/06/13 - */ - - - -//import the packages for using the classes in them into the program -import java.io.File; -import java.util.Hashtable; -import java.util.Enumeration; -import javax.swing.filechooser.*; - -/** - * A convenience implementation of FileFilter that filters out - * all files except for those type extensions that it knows about. - * - * Extensions are of the type ".foo", which is typically found on - * Windows and Unix boxes, but not on Macinthosh. Case is ignored. - * - * Example - create a new filter that filerts out all files - * but gif and jpg image files: - * - * JFileChooser chooser = new JFileChooser(); - * ExampleFileFilter filter = new ExampleFileFilter( - * new String{"gif", "jpg"}, "JPEG & GIF Images") - * chooser.addChoosableFileFilter(filter); - * chooser.showOpenDialog(this); - * - * @version 1.13 06/13/02 - * @author Jeff Dinkins - */ -public class ExampleFileFilter extends FileFilter { - - -// private static String TYPE_UNKNOWN = "Type Unknown"; -// private static String HIDDEN_FILE = "Hidden File"; - - private Hashtable filters = null; - - - private String description = null; - - - private String fullDescription = null; - - - private boolean useExtensionsInDescription = true; - - - - /** - * Creates a file filter. If no filters are added, then all - * files are accepted. - * - * @see #addExtension - */ - public ExampleFileFilter(){ - this.filters = new Hashtable(); - } - - - - /** - * Creates a file filter that accepts files with the given extension. - * Example: new ExampleFileFilter("jpg"); - * - * @see #addExtension - */ - public ExampleFileFilter(String extension){ - this(extension,null); - } - - - - /** - * Creates a file filter that accepts the given file type. - * Example: new ExampleFileFilter("jpg", "JPEG Image Images"); - * - * Note that the "." before the extension is not needed. If - * provided, it will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String extension, String description){ - this(); - if(extension!=null) addExtension(extension); - if(description!=null) setDescription(description); - } - - - - /** - * Creates a file filter from the given string array. - * Example: new ExampleFileFilter(String {"gif", "jpg"}); - * - * Note that the "." before the extension is not needed adn - * will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String[] filters){ - this(filters, null); - } - - - - /** - * Creates a file filter from the given string array and description. - * Example: new ExampleFileFilter(String {"gif", "jpg"}, "Gif and JPG Images"); - * - * Note that the "." before the extension is not needed and will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String[] filters, String description){ - this(); - for (int i = 0; i < filters.length; i++){ - // add filters one by one - addExtension(filters[i]); - } - if(description!=null) setDescription(description); - } - - - - /** - * Return true if this file should be shown in the directory pane, - * false if it shouldn't. - * - * Files that begin with "." are ignored. - * - * @see #getExtension - * @see FileFilter#accepts - */ - public boolean accept(File f){ - if(f != null){ - if(f.isDirectory()){ - return true; - } - String extension = getExtension(f); - if(extension != null && filters.get(getExtension(f)) != null){ - return true; - }; - } - return false; - } - - - - /** - * Return the extension portion of the file's name . - * - * @see #getExtension - * @see FileFilter#accept - */ - public String getExtension(File f){ - if(f != null){ - String filename = f.getName(); - int i = filename.lastIndexOf('.'); - if(i>0 && i(5); - } - filters.put(extension.toLowerCase(), this); - fullDescription = null; - } - - - - /** - * Returns the human readable description of this filter. For - * example: "JPEG and GIF Image Files (*.jpg, *.gif)" - * - * @see setDescription - * @see setExtensionListInDescription - * @see isExtensionListInDescription - * @see FileFilter#getDescription - */ - @SuppressWarnings("rawtypes") - public String getDescription(){ - if(fullDescription == null) { - if(description == null || isExtensionListInDescription()){ - fullDescription = description==null ? "(" : description + " ("; - // build the description from the extension list - Enumeration extensions = filters.keys(); - if(extensions != null){ - fullDescription += "." + (String) extensions.nextElement(); - while (extensions.hasMoreElements()) { - fullDescription += ", ." + (String) extensions.nextElement(); - } - } - fullDescription += ")"; - } else { - fullDescription = description; - } - } - return fullDescription; - } - - - - /** - * Sets the human readable description of this filter. For - * example: filter.setDescription("Gif and JPG Images"); - * - * @see setDescription - * @see setExtensionListInDescription - * @see isExtensionListInDescription - */ - public void setDescription(String description){ - this.description = description; - fullDescription = null; - } - - - - /** - * Determines whether the extension list (.jpg, .gif, etc) should - * show up in the human readable description. - * - * Only relevent if a description was provided in the constructor - * or using setDescription(); - * - * @see getDescription - * @see setDescription - * @see isExtensionListInDescription - */ - public void setExtensionListInDescription(boolean b){ - useExtensionsInDescription = b; - fullDescription = null; - } - - - - /** - * Returns whether the extension list (.jpg, .gif, etc) should - * show up in the human readable description. - * - * Only relevent if a description was provided in the constructor - * or using setDescription(); - * - * @see getDescription - * @see setDescription - * @see setExtensionListInDescription - */ - public boolean isExtensionListInDescription(){ - return useExtensionsInDescription; - } - - -} diff --git a/java/spl/notepad/Variant00004java/Fonts.java b/java/spl/notepad/Variant00004java/Fonts.java deleted file mode 100644 index e63be0b..0000000 --- a/java/spl/notepad/Variant00004java/Fonts.java +++ /dev/null @@ -1,136 +0,0 @@ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - -/** - *A class for creating JFontDialog - */ -public class Fonts extends JDialog { - - private static final long serialVersionUID = 1L; - - - /** - *@see Center.java - *this class to make the JDialog in the center - */ - public Center center = new Center(this); - - - - //declaration of the private variables used in the program - private JPanel jp = new JPanel(); - - - private JLabel fjl = new JLabel("Fonts: "); - - - private JComboBox fjcb = new JComboBox(); - - - /** - *-> GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames() <- - * WE USING THIS METHOD TO GET ALL FONT IN THE SYSTEM (OS) - */ - private String fonts[]=GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); - - - private JLabel sjl = new JLabel("Sizes: "); - - - private JComboBox sjcb = new JComboBox(); - - - private String sizes[] = {"8","10","12","14","16","18","20","24","28","32","48","72"}; - - - private JLabel tjl = new JLabel("Types: "); - - - private JComboBox tjcb = new JComboBox(); - - - private String types[] = {"Regular", "Bold", "Italic", "Bold Italic"}; - - - private JLabel jjl = new JLabel("Preview:"); - - - private JLabel jl = new JLabel("AaBaCcDdeEfFgGhHjJ"); - - - private JButton okjb = new JButton("OK"); - - - private JButton cajb = new JButton("Cancel"); - - - //for using ok & cancel button @Actions.java - public JButton getOkjb(){ - return okjb; - } - - - public JButton getCajb(){ - return cajb; - } - - - //Constructor of Fonts - public Fonts(){ - //for setting the title - setTitle("Font Dialog"); - setResizable(false); - /** - *setting the layout (GridLayout: 5 rows & 2 columns) - *add font JLabel, add font JComboBox - *add type JLabel, add type JComboBox - *add size JLabel, add size JComboBox - *add preview JLabel,add test JLabel - *add ok button, add cancel button - */ - jp.setLayout(new GridLayout(5,2,1,1)); - jp.add(fjl); - jp.add(fjcb = new JComboBox(fonts)); - jp.add(sjl); - jp.add(sjcb = new JComboBox(sizes)); - jp.add(tjl); - jp.add(tjcb = new JComboBox(types)); - jp.add(jjl); - jl.setBorder(BorderFactory.createEtchedBorder()); - jp.add(jl); - jp.add(okjb); - jp.add(cajb); - //add JPanel to the Container - this.getContentPane().add(jp); - /** - *for making JDialog at the center, - *@Center.java - */ - center.fCenter(); - //add action listener to Font JComboBox to get the selected item for setting the preview - fjcb.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - jl.setFont(new Font(String.valueOf(fjcb.getSelectedItem()),tjcb.getSelectedIndex(),14)); - } - }); - //add action listener to Type JComboBox to get the selected index for setting the preview - tjcb.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - jl.setFont(new Font(String.valueOf(fjcb.getSelectedItem()),tjcb.getSelectedIndex(),14)); - } - }); - } - - - /* - *@return font value: (Font,Type,Size) - */ - public Font font(){ - Font font = new Font(String.valueOf(fjcb.getSelectedItem()), tjcb.getSelectedIndex(), - Integer.parseInt(String.valueOf(sjcb.getSelectedItem()))); - return font; - } - - -} diff --git a/java/spl/notepad/Variant00004java/Notepad.java b/java/spl/notepad/Variant00004java/Notepad.java deleted file mode 100644 index 8e26dfe..0000000 --- a/java/spl/notepad/Variant00004java/Notepad.java +++ /dev/null @@ -1,394 +0,0 @@ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import javax.swing.event.*; - -public - -class Notepad extends JFrame { - - private static final long serialVersionUID = 1; - - - //for using the methods in these classes - public Actions actions = new Actions(this); - - - public Center center = new Center(this); - - - - //declaration of the private variables used in the program - //create the text area - private JTextArea textArea; - - - //create the Menu Bar that contains the JMenu "filE, ediT, vieW, formaT, helP" - private JMenuBar Menubar; - - - //Create the menu that contains the items - private JMenu filE, ediT, vieW, formaT, helP; - - - //Create the menu items - private JMenuItem neW, opeN, savE, saveAS, prinT, exiT, fonT, abouT, - cuT, copY, pastE, selectALL; - - - private JCheckBoxMenuItem lineWraP; - - - //Create the Tool Bar that contains the JButton - private JToolBar toolBar; - - - //Create the buttons - private JButton newButton, openButton, saveButton, saveAsButton, printButton, - fontButton, aboutButton; - - - - //for using lineWrap & textArea @Actions.java - public JCheckBoxMenuItem getLineWrap(){ - return lineWraP; - } - - - public JTextArea getTextArea(){ - return textArea; - } - - - - public Notepad (){ - //set the title for Notepad and set the size for it. - setTitle("Untitled - JAVA??? Notepad"); - setSize(800,600); - - //get the graphical user interface components display area - Container cp = getContentPane(); - /** - *adding the text area, - *adding the tool bar & - *adding the scroll pane to the container - */ - cp.add(textArea = new JTextArea()); - cp.add("North", toolBar = new JToolBar("Tool Bar")); - cp.add(new JScrollPane(textArea)); - - //for setting the menu bar - setJMenuBar(Menubar= new JMenuBar()); - //adding file, edit, view, format, help to the menu bar - Menubar.add(filE = new JMenu("File")); - Menubar.add(ediT = new JMenu("Edit")); - Menubar.add(vieW = new JMenu("View")); - Menubar.add(formaT = new JMenu("Format")); - Menubar.add(helP = new JMenu("Help")); - - /** - *adding neW, opeN, savE, saveAS, prinT & exiT to the filE Menu, - *adding a small image icon to the menu item & - *adding separator between the menu item - */ - filE.add(neW = new JMenuItem("New", new ImageIcon(this.getClass().getResource("images/new.gif")))); - filE.add(opeN = new JMenuItem("Open", new ImageIcon(this.getClass().getResource("images/open.gif")))); - filE.add(savE = new JMenuItem("Save", new ImageIcon(this.getClass().getResource("images/save.gif")))); - filE.add(saveAS = new JMenuItem("Save As", new ImageIcon(this.getClass().getResource("images/saveAs.gif")))); - filE.add(prinT = new JMenuItem("Print", new ImageIcon(this.getClass().getResource("images/print.gif")))); - filE.add(exiT = new JMenuItem("Exit")); //, new ImageIcon(this.getClass().getResource("images/exit.gif")))); -- exit.gif missing - filE.insertSeparator(4); - filE.insertSeparator(6); - - /** - *adding undO, redO, cuT, copY, pastE, finD, findNexT & selectALL to the ediT Menu, - *adding a small image icon to the menu item & - *adding separator between the menu item - */ - ediT.add(selectALL= new JMenuItem("Select All")); - //ediT.insertSeparator(2); - //ediT.insertSeparator(6); - - /** - *adding lineWraP & fonT to the formaT Menu, - *adding abouT to the helP Menu & - *adding a small image icon to the menu item - */ - formaT.add(lineWraP = new JCheckBoxMenuItem("Line Wrap")); - formaT.add(fonT = new JMenuItem("Font", new ImageIcon(this.getClass().getResource("images/font.gif")))); - helP.add(abouT = new JMenuItem("About Notepad", new ImageIcon(this.getClass().getResource("images/about.gif")))); - - /** - *allowing the file menu to be selected by pressing ALT + F - *allowing the edit menu to be selected by pressing ALT + E - *allowing the view menu to be selected by pressing ALT + V - *allowing the format menu to be selected by pressing ALT + O - *allowing the help menu to be selected by pressing ALT + H - */ - filE.setMnemonic('f'); - ediT.setMnemonic('e'); - vieW.setMnemonic('v'); - formaT.setMnemonic('o'); - helP.setMnemonic('h'); - - /** - *allowing the neW menu item to be selected by pressing ALT + N - *allowing the opeN menu item to be selected by pressing ALT + O - *allowing the savE menu item to be selected by pressing ALT + S - *allowing the prinT menu item to be selected by pressing ALT + P - *allowing the exiT menu item to be selected by pressing ALT + F4 - *allowing the cuT menu item to be selected by pressing ALT + X - *allowing the copY menu item to be selected by pressing ALT + C - *allowing the pastE menu item to be selected by pressing ALT + V - *allowing the selectAll menu item to be selected by pressing ALT + A - */ - neW.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK)); - opeN.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK)); - savE.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK)); - prinT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.CTRL_MASK)); - exiT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, ActionEvent.CTRL_MASK)); - selectALL.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.CTRL_MASK)); - - /** - *adding newButton, openButton, saveButton, saveAsButton, printButton, undoButton, - *redoButton, cutButton, copyButton, pasteButton, fontButton & aboutButton to the tool bar, - *adding a small image icon to the menu item & - *adding separator between the button - */ - toolBar.add(newButton = new JButton(new ImageIcon(this.getClass().getResource("images/new.gif")))); - toolBar.add(openButton = new JButton(new ImageIcon(this.getClass().getResource("images/open.gif")))); - toolBar.add(saveButton = new JButton(new ImageIcon(this.getClass().getResource("images/save.gif")))); - toolBar.add(saveAsButton= new JButton(new ImageIcon(this.getClass().getResource("images/saveAs.gif")))); - toolBar.add(printButton = new JButton(new ImageIcon(this.getClass().getResource("images/print.gif")))); - toolBar.addSeparator(); - toolBar.add(fontButton = new JButton(new ImageIcon(this.getClass().getResource("images/font.gif")))); - toolBar.add(aboutButton = new JButton(new ImageIcon(this.getClass().getResource("images/about.gif")))); - - //adding a tool tip text to the button for descriping the image icon. - newButton.setToolTipText("New"); - openButton.setToolTipText("Open"); - saveButton.setToolTipText("Save"); - saveAsButton.setToolTipText("Save As"); - printButton.setToolTipText("Print"); - fontButton.setToolTipText("Font"); - aboutButton.setToolTipText("About Notepad"); - - /** - *setting the default close operation to false & - *using own action (exiT action @Actions.java) - */ - setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); - addWindowListener(new WindowAdapter(){ - public void windowClosing(WindowEvent e){ - actions.exiT(); - } - }); - /** - *adding action listener for menu item: neW, opeN, savE, saveAS, prinT, exiT, - *redO, undO, copY, cuT, pastE, finD, findNexT, selectALL, lineWraP, fonT & abouT - *the actions was written @Actions.java - */ - neW.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.neW(); - } - }); - opeN.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.opeN(); - } - }); - savE.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.savE(); - } - }); - saveAS.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.saveAs(); - } - }); - prinT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.prinT(); - } - }); - exiT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.exiT(); - } - }); - selectALL.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.selectALL(); - } - }); - lineWraP.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.lineWraP(); - } - }); - fonT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.fonT(); - } - }); - abouT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.abouT(); - } - }); - - /** - *adding action listener for the button in the tool bar: newButton, openButton, - *saveButton, saveAsButton, printButton, redoButton, undoButton, copyButton, - *cutButton, pasteButton, findButton, selectALL, lineWraP, fontButton & aboutButton - *the actions was written @Actions.java - */ - newButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.neW(); - } - }); - openButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.opeN(); - } - }); - saveButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.savE(); - } - }); - saveAsButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.saveAs(); - } - }); - printButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.prinT(); - } - }); - fontButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.fonT(); - } - }); - aboutButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.abouT(); - } - }); - - /** - *Setting the Line Wrap & Wrap Style Word features are true - */ - textArea.setLineWrap(true); - textArea.setWrapStyleWord(true); - /** - *for making the program at the center, - *@see Center.java - */ - center.nCenter(); - show(); - - ediT.add(cuT = new JMenuItem("Cut", new ImageIcon(this.getClass().getResource("images/cut.gif")))); - ediT.add(copY = new JMenuItem("Copy", new ImageIcon(this.getClass().getResource("images/copy.gif")))); - ediT.add(pastE= new JMenuItem("Paste",new ImageIcon(this.getClass().getResource("images/paste.gif")))); - - cuT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.CTRL_MASK)); - copY.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK)); - pastE.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.CTRL_MASK)); - - toolBar.add(cutButton = new JButton(new ImageIcon(this.getClass().getResource("images/cut.gif")))); - toolBar.add(copyButton = new JButton(new ImageIcon(this.getClass().getResource("images/copy.gif")))); - toolBar.add(pasteButton = new JButton(new ImageIcon(this.getClass().getResource("images/paste.gif")))); - - cutButton.setToolTipText("Cut"); - copyButton.setToolTipText("Copy"); - pasteButton.setToolTipText("Paste"); - - cuT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.cuT(); - } - }); - copY.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.copY(); - } - }); - pastE.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.pastE(); - } - }); - - cutButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.cuT(); - } - }); - copyButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.copY(); - } - }); - pasteButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.pastE(); - } - }); - - - ediT.add(finD = new JMenuItem("Find", new ImageIcon(this.getClass().getResource("images/find.gif")))); - ediT.add(findNexT = new JMenuItem("Find Next")); - //ediT.insertSeparator(8); - - /** - *allowing the finD menu item to be selected by pressing ALT + F - *allowing the findNexT menu item to be selected by pressing ALT + F3 - */ - finD.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F, ActionEvent.CTRL_MASK)); - findNexT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F3, ActionEvent.CTRL_MASK)); - toolBar.add(findButton = new JButton(new ImageIcon(this.getClass().getResource("images/find.gif")))); - findButton.setToolTipText("Find"); - - finD.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.finD(); - } - }); - findNexT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.findNexT(); - } - }); - - findButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.finD(); - } - }); - } - - - //Main Method - public static void main(String[] args){ - new Notepad(); - - } - - - private JButton cutButton, copyButton, pasteButton; - - - - private JButton findButton; - - - private JMenuItem finD, findNexT; - - -} diff --git a/java/spl/notepad/Variant00004java/Print.java b/java/spl/notepad/Variant00004java/Print.java deleted file mode 100644 index 132daed..0000000 --- a/java/spl/notepad/Variant00004java/Print.java +++ /dev/null @@ -1,64 +0,0 @@ -import java.awt.*; -import java.awt.print.*; -import javax.swing.*; - -/** - *A class for creating a printer option. - */ -public class Print implements Printable { - - private Component componentToBePrinted; - - - - public static void printComponent(Component c){ - new Print(c).print(); - } - - - public Print(Component componentToBePrinted){ - this.componentToBePrinted = componentToBePrinted; - } - - - public void print(){ - PrinterJob printJob = PrinterJob.getPrinterJob(); - printJob.setPrintable(this); - if(printJob.printDialog()) - try{ - printJob.print(); - } - catch(PrinterException pe){ - System.out.println("Error printing: " + pe); - } - } - - - public int print(Graphics g, PageFormat pageFormat, int pageIndex){ - if(pageIndex > 0){ - return(NO_SUCH_PAGE); - } - else{ - Graphics2D g2d = (Graphics2D)g; - g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); - disableDoubleBuffering(componentToBePrinted); - componentToBePrinted.paint(g2d); - enableDoubleBuffering(componentToBePrinted); - return(PAGE_EXISTS); - } - } - - - public static void disableDoubleBuffering(Component c){ - RepaintManager currentManager = RepaintManager.currentManager(c); - currentManager.setDoubleBufferingEnabled(false); - } - - - public static void enableDoubleBuffering(Component c){ - RepaintManager currentManager = RepaintManager.currentManager(c); - currentManager.setDoubleBufferingEnabled(true); - } - - -} diff --git a/java/spl/notepad/Variant00005java/About.java b/java/spl/notepad/Variant00005java/About.java deleted file mode 100644 index fb751fd..0000000 --- a/java/spl/notepad/Variant00005java/About.java +++ /dev/null @@ -1,25 +0,0 @@ -import javax.swing.*; - -/** - *A CLASS FOR CREATING ABOUT PANEL - */ -public class About extends JPanel { - - private static final long serialVersionUID = 1; - - - public About(){ - //Create a Label & an image icon in it - JLabel label1 = new JLabel(new ImageIcon(this.getClass().getResource("images/java.gif"))); - //adding label1 to the JPanel - this.add(label1); - //Create a Label & put a HTML script - JLabel label2 = new JLabel("
  • JAVA??? Notepad
  • Ver# 2.0

  • " - +"
  • Coded by: Salah Al-Thubaiti

  • KFUPM, CS

  • " - +"

    CopyRight??? 2001-2002

  • "); - //adding label2 to the JPanel - this.add(label2); - } - - -} diff --git a/java/spl/notepad/Variant00005java/Actions.java b/java/spl/notepad/Variant00005java/Actions.java deleted file mode 100644 index 7d7fc2a..0000000 --- a/java/spl/notepad/Variant00005java/Actions.java +++ /dev/null @@ -1,468 +0,0 @@ -import java.io.*; -import java.util.*; -import java.awt.event.*; -import javax.swing.*; - -/** - *A PUBLIC CLASS FOR ACTIONS.JAVA - */ -public class Actions { - - //declaration of the private variables used in the program - private int returnVal; - - //for JFileChooser - private int option; - - //for using it into JOptionPane - private String fileContent = null; - - //to get the text from the text area - private String fileName = null; - - //for using the name of the file - private JFileChooser jfc = new JFileChooser("."); - - //for using a open & save dialog - private ExampleFileFilter filter = new ExampleFileFilter(); - - //for filtering the file - Notepad n; - - //for using the object in the Notepad.java - public Fonts font = new Fonts(); - - - - public Actions(Notepad n){ - this.n = n; - } - - - /** - *If we want to write a new text, first we want to know if the text area is empty or not, - *second we want to know if the text was saved or not. - *If the text area isn't empty & the text wasn't saved before this time, then the program display -> - *for the user an option for saving the text in a new file or in the same file - */ - public void neW(){ - /** - *if the text area isn't empty & if the text area hasn't - *a text not saved before (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - /** - *here, we have two things, first if the text wasn't be opened or saved before - *second if the text was be opened or saved - */ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - //if the user click on YES button, - //then the program will save the text & make a new text area - if(option == 0){ - //to save the text into a new file - saveAs(); - //to create new getTextArea() after saving the old getTextArea() - n.getTextArea().setText(""); - } - //if the user click on NO button - if(option == 1){ - //to create new getTextArea() without saving the old getTextArea() - n.getTextArea().setText(""); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will save the text into the old file & - *make a new text area,,, - */ - if(option == 0){ - save(); - //to create new getTextArea() after saving the old getTextArea() - n.getTextArea().setText(""); - } - //if the user click on NO button - if(option == 1){ - //to create new getTextArea() without saving the old getTextArea() - n.getTextArea().setText(""); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to write a new text,,, this option will be actived - */ - else{ - n.getTextArea().setText(""); - } - n.setTitle("Untitled - JAVA??? Notepad"); - } - - - /** - *If we want to open a new text, first we want to know if the text area - * is empty or not, second we want to kwnow if the text was saved or not. - *If the text area isn't empty & the text wasn't saved befor this time, - *then the program display for the user an option for saving the text - *in a new file or in the same file - */ - public void opeN(){ - /** - *if the text area isn't empty & if the text area hasn't a text which - *not saved befor (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - /** - *here, we have 2 thing, first if the text wasn't be opened or saved befor - *second if the text was be opened or saved - */ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - //if the user click on YES button, - //then the program will be saved the text & opened a new documents - if(option == 0){ - //for saving the text in a new file - saveAs(); - //for opening the new documents - open(); - } - /** - *if the user click on NO button, - *the program will be opened the new documents - */ - if(option == 1){ - //for opening the new documents - open(); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will save the text into the same file & - *open the new documents - */ - if(option == 0){ - //for saving the text into the same file - save(); - //for opening the new documents - open(); - } - /** - *if the user click on NO button, - *the program will be opened the new documents - */ - if(option == 1){ - //for opening the new documents - open(); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to open a new document,,, this option will be actived - */ - else{ - //for opening the new documents - open(); - } - } - - - /** - *THIS IS FOR SAVE ACTION, SaveAs ACTION has saveAs() method - *If we want to save a new text, then we want to know - *if the text was saved befor or not. - *If the text wasn't be saved befor, then we will use saveAs() - *If the text was be save befor, then we will use save() - */ - public void savE(){ - /** - *if String fileName is null, then using saveAs(). - *Because there was no file was be saved - */ - if(fileName == null){ - saveAs(); - } - /** - *if String fileName has a String (file name), then using save(). - *Because we want to save the new text in the same file. - *if the user want to save the all text (old & new text) in a new file, -> - *he can presses SaveAs button (@saveAs()) - */ - else{ - save(); - } - } - - - /** - *THIS FROM SUN??? WEBSITE (@Print.java) - *if we want to print the text, we can do this by print method - */ - public void prinT(){ - //import printer class - Print.printComponent(n.getTextArea()); - } - - - /** - *If we want to exit from the program, - *first we want to know if the text area is empty or not, - *second we want to kwnow if the text was saved or not. - *If the text area isn't empty & the text wasn't saved befor this time, - *then the program display -> - *for the user an option for saving the text in a new file or in the same file - */ - public void exiT(){ - /** - *if the text area isn't empty & if the text area hasn't a text which - *not saved befor (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will be saved the text & close the program - */ - if(option == 0){ - //for saving the text into new file - saveAs(); - //for closing the program - System.exit(0); - } - /** - *if the user click on NO button, - *then the program will be closed without save the text - */ - if(option == 1){ - //for closing the program - System.exit(0); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will be saved the text & close the program - */ - if(option == 0){ - //for saving the text into the same file - save(); - //for closing the program - System.exit(0); - } - /** - *if the user click on NO button, - *then the program will be closed without save the text - */ - if(option == 1){ - //for closing the program - System.exit(0); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to close the program. This option will be actived - */ - else{ - //for closing the program - System.exit(0); - } - } - - - //to select all the text - public void selectALL(){ - n.getTextArea().selectAll(); - } - - - //for wraping the line & wraping the style word - public void lineWraP(){ - if(n.getLineWrap().isSelected()){ - /** - *make the line wrap & wrap style word is true - *when the line wrap is selected - */ - n.getTextArea().setLineWrap(true); - n.getTextArea().setWrapStyleWord(true); - } - else{ - /** - *make the line wrap & wrap style word is false - *when the line wrap isn't selected - */ - n.getTextArea().setLineWrap(false); - n.getTextArea().setWrapStyleWord(false); - } - } - - - /** - *@see FONTS.JAVA - *this is a font class which is for changing the font, style & size - */ - public void fonT(){ - font.setVisible(true); //setting the visible is true - font.pack(); //pack the panel - //making an action for ok button, so we can change the font - font.getOkjb().addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - n.getTextArea().setFont(font.font()); - //after we chose the font, then the JDialog will be closed - font.setVisible(false); - } - }); - //making an action for cancel button, so we can return to the old font. - font.getCajb().addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - //after we cancel the, then the JDialog will be closed - font.setVisible(false); - } - }); - } - - - /** - *@see ABOUT.JAVA - *it's a Message Dialog to show the information about this program - */ - public void abouT(){ - JOptionPane.showMessageDialog(null, new About(),"About Notepad",JOptionPane.PLAIN_MESSAGE); - } - - - /** - *THIS IS THE WAY FOR OPENING THE TEXT FILE - */ - public void open(){ - //filter the kind of files, we want only TXT file - filter.addExtension("txt"); - //to set a description for the file (TXT) - filter.setDescription("TXT Documents"); - //setting the FileFilter to JFileChooser - jfc.setFileFilter(filter); - returnVal = jfc.showOpenDialog(n); //to show JFileChooser - if(returnVal == JFileChooser.APPROVE_OPTION){ - //to erase any text in the text area before adding new text - n.getTextArea().setText(null); - try{ - //to get the name of the selected file - fileName = jfc.getSelectedFile().getPath(); - //to read the selected file - Reader in = new FileReader(jfc.getSelectedFile()); - //100000 is the max. char can be written in the text area - char[] buff = new char[100000]; - int nch; - while((nch = in.read(buff, 0, buff.length)) != -1) - n.getTextArea().append(new String(buff, 0, nch)); - //to get more text from the file if the array wasn't full - fileContent = n.getTextArea().getText(); - } - catch(FileNotFoundException x){} - catch(IOException ioe){ - System.err.println("I/O Error on Open"); - } - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - /** - *THIS IS THE WAY FOR SAVING THE TEXT IN THE SAME FILE - */ - public void save(){ - //initializing 'fout' to write all text in the selected file - try{ - PrintWriter fout = new PrintWriter(new FileWriter(jfc.getSelectedFile())); - //for getting the text from the text area - fileContent = n.getTextArea().getText(); - //using StringTokenizer for the 'fileContent' String - StringTokenizer st=new StringTokenizer(fileContent,System.getProperty("line.separator")); - while(st.hasMoreTokens()){ - //write the string (text) in the selected file - fout.println(st.nextToken()); - } - //closing fout - fout.close(); - } - catch(IOException ioe){ - System.err.println("I/O Error on Save"); - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - /** - *THIS IS THE WAY FOR SAVING THE TEXT IN A NEW FILE - */ - public void saveAs(){ - //filter the kind of files, we want only TXT file - filter.addExtension("txt"); - //to set a description for the file (TXT) - filter.setDescription("TXT Documents"); - //setting the FileFilter to JFileChooser - jfc.setFileFilter(filter); - returnVal = jfc.showSaveDialog(n); - if(returnVal == JFileChooser.APPROVE_OPTION){ - //initializing the PrintWriter, to save the text in a new file - PrintWriter fout = null; - try{ - fout = new PrintWriter(new FileWriter(jfc.getSelectedFile() + ".txt")); - //getting the text from the text area - fileContent = n.getTextArea().getText(); - //getting the name of the selected file - fileName = jfc.getSelectedFile().getPath(); - //using StringTokenizer for the 'fileContent' String - StringTokenizer st=new StringTokenizer(fileContent,System.getProperty("line.separator")); - while(st.hasMoreTokens()){ - //write the string (text) in the selected file - fout.println(st.nextToken()); - } - //closing 'fout' - fout.close(); - } - catch(IOException ioe){ - System.err.println ("I/O Error on Save"); - } - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - -} diff --git a/java/spl/notepad/Variant00005java/Center.java b/java/spl/notepad/Variant00005java/Center.java deleted file mode 100644 index 1715525..0000000 --- a/java/spl/notepad/Variant00005java/Center.java +++ /dev/null @@ -1,37 +0,0 @@ -import java.awt.*; -/** - *A PUBLIC CLASS FOR CENTER.JAVA - */ -public class Center { - - Notepad n; - - //for using the object in the Notepad.java - Fonts f; - - //for using the object in the Fonts.java - public Center(Notepad n){ - this.n = n; - } - - - public Center(Fonts f){ - this.f = f; - } - - - public void nCenter(){ - //Centering the window - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - n.setLocation((screenSize.width-n.getWidth())/2,(screenSize.height-n.getHeight())/2); - } - - - public void fCenter(){ - //Centering the window - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - f.setLocation((screenSize.width-f.getWidth())/2,(screenSize.height-f.getHeight())/2); - } - - -} diff --git a/java/spl/notepad/Variant00005java/ExampleFileFilter.java b/java/spl/notepad/Variant00005java/ExampleFileFilter.java deleted file mode 100644 index 47b0dd6..0000000 --- a/java/spl/notepad/Variant00005java/ExampleFileFilter.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (c) 2002 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * -Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * -Redistribution in binary form must reproduct the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING - * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT - * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT - * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS - * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST - * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, - * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY - * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN - * IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that Software is not designed, licensed or intended for - * use in the design, construction, operation or maintenance of any nuclear - * facility. - */ - -/* - * @(#)ExampleFileFilter.java 1.13 02/06/13 - */ - - - -//import the packages for using the classes in them into the program -import java.io.File; -import java.util.Hashtable; -import java.util.Enumeration; -import javax.swing.filechooser.*; - -/** - * A convenience implementation of FileFilter that filters out - * all files except for those type extensions that it knows about. - * - * Extensions are of the type ".foo", which is typically found on - * Windows and Unix boxes, but not on Macinthosh. Case is ignored. - * - * Example - create a new filter that filerts out all files - * but gif and jpg image files: - * - * JFileChooser chooser = new JFileChooser(); - * ExampleFileFilter filter = new ExampleFileFilter( - * new String{"gif", "jpg"}, "JPEG & GIF Images") - * chooser.addChoosableFileFilter(filter); - * chooser.showOpenDialog(this); - * - * @version 1.13 06/13/02 - * @author Jeff Dinkins - */ -public class ExampleFileFilter extends FileFilter { - - -// private static String TYPE_UNKNOWN = "Type Unknown"; -// private static String HIDDEN_FILE = "Hidden File"; - - private Hashtable filters = null; - - - private String description = null; - - - private String fullDescription = null; - - - private boolean useExtensionsInDescription = true; - - - - /** - * Creates a file filter. If no filters are added, then all - * files are accepted. - * - * @see #addExtension - */ - public ExampleFileFilter(){ - this.filters = new Hashtable(); - } - - - - /** - * Creates a file filter that accepts files with the given extension. - * Example: new ExampleFileFilter("jpg"); - * - * @see #addExtension - */ - public ExampleFileFilter(String extension){ - this(extension,null); - } - - - - /** - * Creates a file filter that accepts the given file type. - * Example: new ExampleFileFilter("jpg", "JPEG Image Images"); - * - * Note that the "." before the extension is not needed. If - * provided, it will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String extension, String description){ - this(); - if(extension!=null) addExtension(extension); - if(description!=null) setDescription(description); - } - - - - /** - * Creates a file filter from the given string array. - * Example: new ExampleFileFilter(String {"gif", "jpg"}); - * - * Note that the "." before the extension is not needed adn - * will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String[] filters){ - this(filters, null); - } - - - - /** - * Creates a file filter from the given string array and description. - * Example: new ExampleFileFilter(String {"gif", "jpg"}, "Gif and JPG Images"); - * - * Note that the "." before the extension is not needed and will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String[] filters, String description){ - this(); - for (int i = 0; i < filters.length; i++){ - // add filters one by one - addExtension(filters[i]); - } - if(description!=null) setDescription(description); - } - - - - /** - * Return true if this file should be shown in the directory pane, - * false if it shouldn't. - * - * Files that begin with "." are ignored. - * - * @see #getExtension - * @see FileFilter#accepts - */ - public boolean accept(File f){ - if(f != null){ - if(f.isDirectory()){ - return true; - } - String extension = getExtension(f); - if(extension != null && filters.get(getExtension(f)) != null){ - return true; - }; - } - return false; - } - - - - /** - * Return the extension portion of the file's name . - * - * @see #getExtension - * @see FileFilter#accept - */ - public String getExtension(File f){ - if(f != null){ - String filename = f.getName(); - int i = filename.lastIndexOf('.'); - if(i>0 && i(5); - } - filters.put(extension.toLowerCase(), this); - fullDescription = null; - } - - - - /** - * Returns the human readable description of this filter. For - * example: "JPEG and GIF Image Files (*.jpg, *.gif)" - * - * @see setDescription - * @see setExtensionListInDescription - * @see isExtensionListInDescription - * @see FileFilter#getDescription - */ - @SuppressWarnings("rawtypes") - public String getDescription(){ - if(fullDescription == null) { - if(description == null || isExtensionListInDescription()){ - fullDescription = description==null ? "(" : description + " ("; - // build the description from the extension list - Enumeration extensions = filters.keys(); - if(extensions != null){ - fullDescription += "." + (String) extensions.nextElement(); - while (extensions.hasMoreElements()) { - fullDescription += ", ." + (String) extensions.nextElement(); - } - } - fullDescription += ")"; - } else { - fullDescription = description; - } - } - return fullDescription; - } - - - - /** - * Sets the human readable description of this filter. For - * example: filter.setDescription("Gif and JPG Images"); - * - * @see setDescription - * @see setExtensionListInDescription - * @see isExtensionListInDescription - */ - public void setDescription(String description){ - this.description = description; - fullDescription = null; - } - - - - /** - * Determines whether the extension list (.jpg, .gif, etc) should - * show up in the human readable description. - * - * Only relevent if a description was provided in the constructor - * or using setDescription(); - * - * @see getDescription - * @see setDescription - * @see isExtensionListInDescription - */ - public void setExtensionListInDescription(boolean b){ - useExtensionsInDescription = b; - fullDescription = null; - } - - - - /** - * Returns whether the extension list (.jpg, .gif, etc) should - * show up in the human readable description. - * - * Only relevent if a description was provided in the constructor - * or using setDescription(); - * - * @see getDescription - * @see setDescription - * @see setExtensionListInDescription - */ - public boolean isExtensionListInDescription(){ - return useExtensionsInDescription; - } - - -} diff --git a/java/spl/notepad/Variant00005java/Fonts.java b/java/spl/notepad/Variant00005java/Fonts.java deleted file mode 100644 index e63be0b..0000000 --- a/java/spl/notepad/Variant00005java/Fonts.java +++ /dev/null @@ -1,136 +0,0 @@ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - -/** - *A class for creating JFontDialog - */ -public class Fonts extends JDialog { - - private static final long serialVersionUID = 1L; - - - /** - *@see Center.java - *this class to make the JDialog in the center - */ - public Center center = new Center(this); - - - - //declaration of the private variables used in the program - private JPanel jp = new JPanel(); - - - private JLabel fjl = new JLabel("Fonts: "); - - - private JComboBox fjcb = new JComboBox(); - - - /** - *-> GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames() <- - * WE USING THIS METHOD TO GET ALL FONT IN THE SYSTEM (OS) - */ - private String fonts[]=GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); - - - private JLabel sjl = new JLabel("Sizes: "); - - - private JComboBox sjcb = new JComboBox(); - - - private String sizes[] = {"8","10","12","14","16","18","20","24","28","32","48","72"}; - - - private JLabel tjl = new JLabel("Types: "); - - - private JComboBox tjcb = new JComboBox(); - - - private String types[] = {"Regular", "Bold", "Italic", "Bold Italic"}; - - - private JLabel jjl = new JLabel("Preview:"); - - - private JLabel jl = new JLabel("AaBaCcDdeEfFgGhHjJ"); - - - private JButton okjb = new JButton("OK"); - - - private JButton cajb = new JButton("Cancel"); - - - //for using ok & cancel button @Actions.java - public JButton getOkjb(){ - return okjb; - } - - - public JButton getCajb(){ - return cajb; - } - - - //Constructor of Fonts - public Fonts(){ - //for setting the title - setTitle("Font Dialog"); - setResizable(false); - /** - *setting the layout (GridLayout: 5 rows & 2 columns) - *add font JLabel, add font JComboBox - *add type JLabel, add type JComboBox - *add size JLabel, add size JComboBox - *add preview JLabel,add test JLabel - *add ok button, add cancel button - */ - jp.setLayout(new GridLayout(5,2,1,1)); - jp.add(fjl); - jp.add(fjcb = new JComboBox(fonts)); - jp.add(sjl); - jp.add(sjcb = new JComboBox(sizes)); - jp.add(tjl); - jp.add(tjcb = new JComboBox(types)); - jp.add(jjl); - jl.setBorder(BorderFactory.createEtchedBorder()); - jp.add(jl); - jp.add(okjb); - jp.add(cajb); - //add JPanel to the Container - this.getContentPane().add(jp); - /** - *for making JDialog at the center, - *@Center.java - */ - center.fCenter(); - //add action listener to Font JComboBox to get the selected item for setting the preview - fjcb.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - jl.setFont(new Font(String.valueOf(fjcb.getSelectedItem()),tjcb.getSelectedIndex(),14)); - } - }); - //add action listener to Type JComboBox to get the selected index for setting the preview - tjcb.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - jl.setFont(new Font(String.valueOf(fjcb.getSelectedItem()),tjcb.getSelectedIndex(),14)); - } - }); - } - - - /* - *@return font value: (Font,Type,Size) - */ - public Font font(){ - Font font = new Font(String.valueOf(fjcb.getSelectedItem()), tjcb.getSelectedIndex(), - Integer.parseInt(String.valueOf(sjcb.getSelectedItem()))); - return font; - } - - -} diff --git a/java/spl/notepad/Variant00005java/Notepad.java b/java/spl/notepad/Variant00005java/Notepad.java deleted file mode 100644 index e4c5e15..0000000 --- a/java/spl/notepad/Variant00005java/Notepad.java +++ /dev/null @@ -1,336 +0,0 @@ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; import javax.swing.undo.*; -import javax.swing.event.*; - -public - -class Notepad extends JFrame { - - private static final long serialVersionUID = 1; - - - //for using the methods in these classes - public Actions actions = new Actions(this); - - - public Center center = new Center(this); - - - - //declaration of the private variables used in the program - //create the text area - private JTextArea textArea; - - - //create the Menu Bar that contains the JMenu "filE, ediT, vieW, formaT, helP" - private JMenuBar Menubar; - - - //Create the menu that contains the items - private JMenu filE, ediT, vieW, formaT, helP; - - - //Create the menu items - private JMenuItem neW, opeN, savE, saveAS, prinT, exiT, fonT, abouT, - cuT, copY, pastE, selectALL; - - - private JCheckBoxMenuItem lineWraP; - - - //Create the Tool Bar that contains the JButton - private JToolBar toolBar; - - - //Create the buttons - private JButton newButton, openButton, saveButton, saveAsButton, printButton, - fontButton, aboutButton; - - - - //for using lineWrap & textArea @Actions.java - public JCheckBoxMenuItem getLineWrap(){ - return lineWraP; - } - - - public JTextArea getTextArea(){ - return textArea; - } - - - - public Notepad (){ - //set the title for Notepad and set the size for it. - setTitle("Untitled - JAVA??? Notepad"); - setSize(800,600); - - //get the graphical user interface components display area - Container cp = getContentPane(); - /** - *adding the text area, - *adding the tool bar & - *adding the scroll pane to the container - */ - cp.add(textArea = new JTextArea()); - cp.add("North", toolBar = new JToolBar("Tool Bar")); - cp.add(new JScrollPane(textArea)); - - //for setting the menu bar - setJMenuBar(Menubar= new JMenuBar()); - //adding file, edit, view, format, help to the menu bar - Menubar.add(filE = new JMenu("File")); - Menubar.add(ediT = new JMenu("Edit")); - Menubar.add(vieW = new JMenu("View")); - Menubar.add(formaT = new JMenu("Format")); - Menubar.add(helP = new JMenu("Help")); - - /** - *adding neW, opeN, savE, saveAS, prinT & exiT to the filE Menu, - *adding a small image icon to the menu item & - *adding separator between the menu item - */ - filE.add(neW = new JMenuItem("New", new ImageIcon(this.getClass().getResource("images/new.gif")))); - filE.add(opeN = new JMenuItem("Open", new ImageIcon(this.getClass().getResource("images/open.gif")))); - filE.add(savE = new JMenuItem("Save", new ImageIcon(this.getClass().getResource("images/save.gif")))); - filE.add(saveAS = new JMenuItem("Save As", new ImageIcon(this.getClass().getResource("images/saveAs.gif")))); - filE.add(prinT = new JMenuItem("Print", new ImageIcon(this.getClass().getResource("images/print.gif")))); - filE.add(exiT = new JMenuItem("Exit")); //, new ImageIcon(this.getClass().getResource("images/exit.gif")))); -- exit.gif missing - filE.insertSeparator(4); - filE.insertSeparator(6); - - /** - *adding undO, redO, cuT, copY, pastE, finD, findNexT & selectALL to the ediT Menu, - *adding a small image icon to the menu item & - *adding separator between the menu item - */ - ediT.add(selectALL= new JMenuItem("Select All")); - //ediT.insertSeparator(2); - //ediT.insertSeparator(6); - - /** - *adding lineWraP & fonT to the formaT Menu, - *adding abouT to the helP Menu & - *adding a small image icon to the menu item - */ - formaT.add(lineWraP = new JCheckBoxMenuItem("Line Wrap")); - formaT.add(fonT = new JMenuItem("Font", new ImageIcon(this.getClass().getResource("images/font.gif")))); - helP.add(abouT = new JMenuItem("About Notepad", new ImageIcon(this.getClass().getResource("images/about.gif")))); - - /** - *allowing the file menu to be selected by pressing ALT + F - *allowing the edit menu to be selected by pressing ALT + E - *allowing the view menu to be selected by pressing ALT + V - *allowing the format menu to be selected by pressing ALT + O - *allowing the help menu to be selected by pressing ALT + H - */ - filE.setMnemonic('f'); - ediT.setMnemonic('e'); - vieW.setMnemonic('v'); - formaT.setMnemonic('o'); - helP.setMnemonic('h'); - - /** - *allowing the neW menu item to be selected by pressing ALT + N - *allowing the opeN menu item to be selected by pressing ALT + O - *allowing the savE menu item to be selected by pressing ALT + S - *allowing the prinT menu item to be selected by pressing ALT + P - *allowing the exiT menu item to be selected by pressing ALT + F4 - *allowing the cuT menu item to be selected by pressing ALT + X - *allowing the copY menu item to be selected by pressing ALT + C - *allowing the pastE menu item to be selected by pressing ALT + V - *allowing the selectAll menu item to be selected by pressing ALT + A - */ - neW.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK)); - opeN.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK)); - savE.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK)); - prinT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.CTRL_MASK)); - exiT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, ActionEvent.CTRL_MASK)); - selectALL.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.CTRL_MASK)); - - /** - *adding newButton, openButton, saveButton, saveAsButton, printButton, undoButton, - *redoButton, cutButton, copyButton, pasteButton, fontButton & aboutButton to the tool bar, - *adding a small image icon to the menu item & - *adding separator between the button - */ - toolBar.add(newButton = new JButton(new ImageIcon(this.getClass().getResource("images/new.gif")))); - toolBar.add(openButton = new JButton(new ImageIcon(this.getClass().getResource("images/open.gif")))); - toolBar.add(saveButton = new JButton(new ImageIcon(this.getClass().getResource("images/save.gif")))); - toolBar.add(saveAsButton= new JButton(new ImageIcon(this.getClass().getResource("images/saveAs.gif")))); - toolBar.add(printButton = new JButton(new ImageIcon(this.getClass().getResource("images/print.gif")))); - toolBar.addSeparator(); - toolBar.add(fontButton = new JButton(new ImageIcon(this.getClass().getResource("images/font.gif")))); - toolBar.add(aboutButton = new JButton(new ImageIcon(this.getClass().getResource("images/about.gif")))); - - //adding a tool tip text to the button for descriping the image icon. - newButton.setToolTipText("New"); - openButton.setToolTipText("Open"); - saveButton.setToolTipText("Save"); - saveAsButton.setToolTipText("Save As"); - printButton.setToolTipText("Print"); - fontButton.setToolTipText("Font"); - aboutButton.setToolTipText("About Notepad"); - - /** - *setting the default close operation to false & - *using own action (exiT action @Actions.java) - */ - setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); - addWindowListener(new WindowAdapter(){ - public void windowClosing(WindowEvent e){ - actions.exiT(); - } - }); - /** - *adding action listener for menu item: neW, opeN, savE, saveAS, prinT, exiT, - *redO, undO, copY, cuT, pastE, finD, findNexT, selectALL, lineWraP, fonT & abouT - *the actions was written @Actions.java - */ - neW.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.neW(); - } - }); - opeN.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.opeN(); - } - }); - savE.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.savE(); - } - }); - saveAS.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.saveAs(); - } - }); - prinT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.prinT(); - } - }); - exiT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.exiT(); - } - }); - selectALL.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.selectALL(); - } - }); - lineWraP.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.lineWraP(); - } - }); - fonT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.fonT(); - } - }); - abouT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.abouT(); - } - }); - - /** - *adding action listener for the button in the tool bar: newButton, openButton, - *saveButton, saveAsButton, printButton, redoButton, undoButton, copyButton, - *cutButton, pasteButton, findButton, selectALL, lineWraP, fontButton & aboutButton - *the actions was written @Actions.java - */ - newButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.neW(); - } - }); - openButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.opeN(); - } - }); - saveButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.savE(); - } - }); - saveAsButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.saveAs(); - } - }); - printButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.prinT(); - } - }); - fontButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.fonT(); - } - }); - aboutButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.abouT(); - } - }); - - /** - *Setting the Line Wrap & Wrap Style Word features are true - */ - textArea.setLineWrap(true); - textArea.setWrapStyleWord(true); - /** - *for making the program at the center, - *@see Center.java - */ - center.nCenter(); - show(); - - ediT.add(undoAction); - ediT.add(redoAction); - - toolBar.addSeparator(); - toolBar.add(undoAction); - toolBar.add(redoAction); - toolBar.addSeparator(); - - textArea.getDocument().addUndoableEditListener(new UndoableEditListener(){ - public void undoableEditHappened(UndoableEditEvent e){ - //Remember the edit and update the menus - undo.addEdit(e.getEdit()); - undoAction.update(); - redoAction.update(); - } - }); - } - - - //Main Method - public static void main(String[] args){ - new Notepad(); - - } - - - //for using undo & redo - UndoManager undo = new UndoManager(); - - - UndoAction undoAction = new UndoAction(this); - - - RedoAction redoAction = new RedoAction(this); - - - - private JButton undoButton, redoButton; - - -} diff --git a/java/spl/notepad/Variant00005java/Print.java b/java/spl/notepad/Variant00005java/Print.java deleted file mode 100644 index 132daed..0000000 --- a/java/spl/notepad/Variant00005java/Print.java +++ /dev/null @@ -1,64 +0,0 @@ -import java.awt.*; -import java.awt.print.*; -import javax.swing.*; - -/** - *A class for creating a printer option. - */ -public class Print implements Printable { - - private Component componentToBePrinted; - - - - public static void printComponent(Component c){ - new Print(c).print(); - } - - - public Print(Component componentToBePrinted){ - this.componentToBePrinted = componentToBePrinted; - } - - - public void print(){ - PrinterJob printJob = PrinterJob.getPrinterJob(); - printJob.setPrintable(this); - if(printJob.printDialog()) - try{ - printJob.print(); - } - catch(PrinterException pe){ - System.out.println("Error printing: " + pe); - } - } - - - public int print(Graphics g, PageFormat pageFormat, int pageIndex){ - if(pageIndex > 0){ - return(NO_SUCH_PAGE); - } - else{ - Graphics2D g2d = (Graphics2D)g; - g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); - disableDoubleBuffering(componentToBePrinted); - componentToBePrinted.paint(g2d); - enableDoubleBuffering(componentToBePrinted); - return(PAGE_EXISTS); - } - } - - - public static void disableDoubleBuffering(Component c){ - RepaintManager currentManager = RepaintManager.currentManager(c); - currentManager.setDoubleBufferingEnabled(false); - } - - - public static void enableDoubleBuffering(Component c){ - RepaintManager currentManager = RepaintManager.currentManager(c); - currentManager.setDoubleBufferingEnabled(true); - } - - -} diff --git a/java/spl/notepad/Variant00005java/RedoAction.java b/java/spl/notepad/Variant00005java/RedoAction.java deleted file mode 100644 index ccd8eaf..0000000 --- a/java/spl/notepad/Variant00005java/RedoAction.java +++ /dev/null @@ -1,50 +0,0 @@ -import java.awt.event.*; -import javax.swing.*; -import javax.swing.undo.*; - - - -class RedoAction extends AbstractAction { - - private static final long serialVersionUID = 1; - - - Notepad notepad; - - - - public RedoAction(Notepad notepad){ - super("Redo"); - putValue( Action.SMALL_ICON, - new ImageIcon(this.getClass().getResource("images/redo.gif"))); - setEnabled(false); - this.notepad = notepad; - } - - - public void actionPerformed(ActionEvent e){ - try{ - notepad.undo.redo(); - } - catch (CannotRedoException ex){ - System.out.println("Unable to redo: " + ex); - ex.printStackTrace(); - } - update(); - notepad.undoAction.update(); - } - - - protected void update(){ - if(notepad.undo.canRedo()){ - setEnabled(true); - putValue("Redo", notepad.undo.getRedoPresentationName()); - } - else{ - setEnabled(false); - putValue(Action.NAME, "Redo"); - } - } - - -} diff --git a/java/spl/notepad/Variant00005java/UndoAction.java b/java/spl/notepad/Variant00005java/UndoAction.java deleted file mode 100644 index 3298a36..0000000 --- a/java/spl/notepad/Variant00005java/UndoAction.java +++ /dev/null @@ -1,50 +0,0 @@ -import java.awt.event.*; -import javax.swing.*; -import javax.swing.undo.*; - - - -class UndoAction extends AbstractAction { - - private static final long serialVersionUID = 1; - - - Notepad notepad; - - - - public UndoAction(Notepad notepad){ - super( "Undo" ); - putValue( Action.SMALL_ICON, - new ImageIcon( this.getClass().getResource( "images/undo.gif" ) ) ); - setEnabled( false ); - this.notepad = notepad; - } - - - public void actionPerformed( ActionEvent e ) { - try { - notepad.undo.undo(); - } - catch ( CannotUndoException ex ) { - System.out.println( "Unable to undo: " + ex ); - ex.printStackTrace(); - } - update(); - notepad.redoAction.update(); - } - - - protected void update() { - if( notepad.undo.canUndo() ) { - setEnabled( true ); - putValue( "Undo", notepad.undo.getUndoPresentationName() ); - } - else { - setEnabled( false ); - putValue( Action.NAME, "Undo" ); - } - } - - -} diff --git a/java/spl/notepad/Variant00006java/About.java b/java/spl/notepad/Variant00006java/About.java deleted file mode 100644 index fb751fd..0000000 --- a/java/spl/notepad/Variant00006java/About.java +++ /dev/null @@ -1,25 +0,0 @@ -import javax.swing.*; - -/** - *A CLASS FOR CREATING ABOUT PANEL - */ -public class About extends JPanel { - - private static final long serialVersionUID = 1; - - - public About(){ - //Create a Label & an image icon in it - JLabel label1 = new JLabel(new ImageIcon(this.getClass().getResource("images/java.gif"))); - //adding label1 to the JPanel - this.add(label1); - //Create a Label & put a HTML script - JLabel label2 = new JLabel("
  • JAVA??? Notepad
  • Ver# 2.0

  • " - +"
  • Coded by: Salah Al-Thubaiti

  • KFUPM, CS

  • " - +"

    CopyRight??? 2001-2002

  • "); - //adding label2 to the JPanel - this.add(label2); - } - - -} diff --git a/java/spl/notepad/Variant00006java/Actions.java b/java/spl/notepad/Variant00006java/Actions.java deleted file mode 100644 index 50012f2..0000000 --- a/java/spl/notepad/Variant00006java/Actions.java +++ /dev/null @@ -1,481 +0,0 @@ -import java.io.*; -import java.util.*; -import java.awt.event.*; -import javax.swing.*; public class Actions { - - //declaration of the private variables used in the program - private int returnVal; - - //for JFileChooser - private int option; - - //for using it into JOptionPane - private String fileContent = null; - - //to get the text from the text area - private String fileName = null; - - //for using the name of the file - private JFileChooser jfc = new JFileChooser("."); - - //for using a open & save dialog - private ExampleFileFilter filter = new ExampleFileFilter(); - - //for filtering the file - Notepad n; - - //for using the object in the Notepad.java - public Fonts font = new Fonts(); - - - - public Actions(Notepad n){ - this.n = n; - } - - - /** - *If we want to write a new text, first we want to know if the text area is empty or not, - *second we want to know if the text was saved or not. - *If the text area isn't empty & the text wasn't saved before this time, then the program display -> - *for the user an option for saving the text in a new file or in the same file - */ - public void neW(){ - /** - *if the text area isn't empty & if the text area hasn't - *a text not saved before (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - /** - *here, we have two things, first if the text wasn't be opened or saved before - *second if the text was be opened or saved - */ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - //if the user click on YES button, - //then the program will save the text & make a new text area - if(option == 0){ - //to save the text into a new file - saveAs(); - //to create new getTextArea() after saving the old getTextArea() - n.getTextArea().setText(""); - } - //if the user click on NO button - if(option == 1){ - //to create new getTextArea() without saving the old getTextArea() - n.getTextArea().setText(""); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will save the text into the old file & - *make a new text area,,, - */ - if(option == 0){ - save(); - //to create new getTextArea() after saving the old getTextArea() - n.getTextArea().setText(""); - } - //if the user click on NO button - if(option == 1){ - //to create new getTextArea() without saving the old getTextArea() - n.getTextArea().setText(""); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to write a new text,,, this option will be actived - */ - else{ - n.getTextArea().setText(""); - } - n.setTitle("Untitled - JAVA??? Notepad"); - } - - - /** - *If we want to open a new text, first we want to know if the text area - * is empty or not, second we want to kwnow if the text was saved or not. - *If the text area isn't empty & the text wasn't saved befor this time, - *then the program display for the user an option for saving the text - *in a new file or in the same file - */ - public void opeN(){ - /** - *if the text area isn't empty & if the text area hasn't a text which - *not saved befor (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - /** - *here, we have 2 thing, first if the text wasn't be opened or saved befor - *second if the text was be opened or saved - */ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - //if the user click on YES button, - //then the program will be saved the text & opened a new documents - if(option == 0){ - //for saving the text in a new file - saveAs(); - //for opening the new documents - open(); - } - /** - *if the user click on NO button, - *the program will be opened the new documents - */ - if(option == 1){ - //for opening the new documents - open(); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will save the text into the same file & - *open the new documents - */ - if(option == 0){ - //for saving the text into the same file - save(); - //for opening the new documents - open(); - } - /** - *if the user click on NO button, - *the program will be opened the new documents - */ - if(option == 1){ - //for opening the new documents - open(); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to open a new document,,, this option will be actived - */ - else{ - //for opening the new documents - open(); - } - } - - - /** - *THIS IS FOR SAVE ACTION, SaveAs ACTION has saveAs() method - *If we want to save a new text, then we want to know - *if the text was saved befor or not. - *If the text wasn't be saved befor, then we will use saveAs() - *If the text was be save befor, then we will use save() - */ - public void savE(){ - /** - *if String fileName is null, then using saveAs(). - *Because there was no file was be saved - */ - if(fileName == null){ - saveAs(); - } - /** - *if String fileName has a String (file name), then using save(). - *Because we want to save the new text in the same file. - *if the user want to save the all text (old & new text) in a new file, -> - *he can presses SaveAs button (@saveAs()) - */ - else{ - save(); - } - } - - - /** - *THIS FROM SUN??? WEBSITE (@Print.java) - *if we want to print the text, we can do this by print method - */ - public void prinT(){ - //import printer class - Print.printComponent(n.getTextArea()); - } - - - /** - *If we want to exit from the program, - *first we want to know if the text area is empty or not, - *second we want to kwnow if the text was saved or not. - *If the text area isn't empty & the text wasn't saved befor this time, - *then the program display -> - *for the user an option for saving the text in a new file or in the same file - */ - public void exiT(){ - /** - *if the text area isn't empty & if the text area hasn't a text which - *not saved befor (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will be saved the text & close the program - */ - if(option == 0){ - //for saving the text into new file - saveAs(); - //for closing the program - System.exit(0); - } - /** - *if the user click on NO button, - *then the program will be closed without save the text - */ - if(option == 1){ - //for closing the program - System.exit(0); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will be saved the text & close the program - */ - if(option == 0){ - //for saving the text into the same file - save(); - //for closing the program - System.exit(0); - } - /** - *if the user click on NO button, - *then the program will be closed without save the text - */ - if(option == 1){ - //for closing the program - System.exit(0); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to close the program. This option will be actived - */ - else{ - //for closing the program - System.exit(0); - } - } - - - //to select all the text - public void selectALL(){ - n.getTextArea().selectAll(); - } - - - //for wraping the line & wraping the style word - public void lineWraP(){ - if(n.getLineWrap().isSelected()){ - /** - *make the line wrap & wrap style word is true - *when the line wrap is selected - */ - n.getTextArea().setLineWrap(true); - n.getTextArea().setWrapStyleWord(true); - } - else{ - /** - *make the line wrap & wrap style word is false - *when the line wrap isn't selected - */ - n.getTextArea().setLineWrap(false); - n.getTextArea().setWrapStyleWord(false); - } - } - - - /** - *@see FONTS.JAVA - *this is a font class which is for changing the font, style & size - */ - public void fonT(){ - font.setVisible(true); //setting the visible is true - font.pack(); //pack the panel - //making an action for ok button, so we can change the font - font.getOkjb().addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - n.getTextArea().setFont(font.font()); - //after we chose the font, then the JDialog will be closed - font.setVisible(false); - } - }); - //making an action for cancel button, so we can return to the old font. - font.getCajb().addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - //after we cancel the, then the JDialog will be closed - font.setVisible(false); - } - }); - } - - - /** - *@see ABOUT.JAVA - *it's a Message Dialog to show the information about this program - */ - public void abouT(){ - JOptionPane.showMessageDialog(null, new About(),"About Notepad",JOptionPane.PLAIN_MESSAGE); - } - - - /** - *THIS IS THE WAY FOR OPENING THE TEXT FILE - */ - public void open(){ - //filter the kind of files, we want only TXT file - filter.addExtension("txt"); - //to set a description for the file (TXT) - filter.setDescription("TXT Documents"); - //setting the FileFilter to JFileChooser - jfc.setFileFilter(filter); - returnVal = jfc.showOpenDialog(n); //to show JFileChooser - if(returnVal == JFileChooser.APPROVE_OPTION){ - //to erase any text in the text area before adding new text - n.getTextArea().setText(null); - try{ - //to get the name of the selected file - fileName = jfc.getSelectedFile().getPath(); - //to read the selected file - Reader in = new FileReader(jfc.getSelectedFile()); - //100000 is the max. char can be written in the text area - char[] buff = new char[100000]; - int nch; - while((nch = in.read(buff, 0, buff.length)) != -1) - n.getTextArea().append(new String(buff, 0, nch)); - //to get more text from the file if the array wasn't full - fileContent = n.getTextArea().getText(); - } - catch(FileNotFoundException x){} - catch(IOException ioe){ - System.err.println("I/O Error on Open"); - } - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - /** - *THIS IS THE WAY FOR SAVING THE TEXT IN THE SAME FILE - */ - public void save(){ - //initializing 'fout' to write all text in the selected file - try{ - PrintWriter fout = new PrintWriter(new FileWriter(jfc.getSelectedFile())); - //for getting the text from the text area - fileContent = n.getTextArea().getText(); - //using StringTokenizer for the 'fileContent' String - StringTokenizer st=new StringTokenizer(fileContent,System.getProperty("line.separator")); - while(st.hasMoreTokens()){ - //write the string (text) in the selected file - fout.println(st.nextToken()); - } - //closing fout - fout.close(); - } - catch(IOException ioe){ - System.err.println("I/O Error on Save"); - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - /** - *THIS IS THE WAY FOR SAVING THE TEXT IN A NEW FILE - */ - public void saveAs(){ - //filter the kind of files, we want only TXT file - filter.addExtension("txt"); - //to set a description for the file (TXT) - filter.setDescription("TXT Documents"); - //setting the FileFilter to JFileChooser - jfc.setFileFilter(filter); - returnVal = jfc.showSaveDialog(n); - if(returnVal == JFileChooser.APPROVE_OPTION){ - //initializing the PrintWriter, to save the text in a new file - PrintWriter fout = null; - try{ - fout = new PrintWriter(new FileWriter(jfc.getSelectedFile() + ".txt")); - //getting the text from the text area - fileContent = n.getTextArea().getText(); - //getting the name of the selected file - fileName = jfc.getSelectedFile().getPath(); - //using StringTokenizer for the 'fileContent' String - StringTokenizer st=new StringTokenizer(fileContent,System.getProperty("line.separator")); - while(st.hasMoreTokens()){ - //write the string (text) in the selected file - fout.println(st.nextToken()); - } - //closing 'fout' - fout.close(); - } - catch(IOException ioe){ - System.err.println ("I/O Error on Save"); - } - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - //to cut the selected text - public void cuT(){ - n.getTextArea().cut(); - } - - - //to copy the selected text - public void copY(){ - n.getTextArea().copy(); - } - - - //to paste the selected text - public void pastE(){ - n.getTextArea().paste(); - } - - -} diff --git a/java/spl/notepad/Variant00006java/Center.java b/java/spl/notepad/Variant00006java/Center.java deleted file mode 100644 index 1715525..0000000 --- a/java/spl/notepad/Variant00006java/Center.java +++ /dev/null @@ -1,37 +0,0 @@ -import java.awt.*; -/** - *A PUBLIC CLASS FOR CENTER.JAVA - */ -public class Center { - - Notepad n; - - //for using the object in the Notepad.java - Fonts f; - - //for using the object in the Fonts.java - public Center(Notepad n){ - this.n = n; - } - - - public Center(Fonts f){ - this.f = f; - } - - - public void nCenter(){ - //Centering the window - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - n.setLocation((screenSize.width-n.getWidth())/2,(screenSize.height-n.getHeight())/2); - } - - - public void fCenter(){ - //Centering the window - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - f.setLocation((screenSize.width-f.getWidth())/2,(screenSize.height-f.getHeight())/2); - } - - -} diff --git a/java/spl/notepad/Variant00006java/ExampleFileFilter.java b/java/spl/notepad/Variant00006java/ExampleFileFilter.java deleted file mode 100644 index 47b0dd6..0000000 --- a/java/spl/notepad/Variant00006java/ExampleFileFilter.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (c) 2002 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * -Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * -Redistribution in binary form must reproduct the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING - * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT - * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT - * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS - * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST - * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, - * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY - * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN - * IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that Software is not designed, licensed or intended for - * use in the design, construction, operation or maintenance of any nuclear - * facility. - */ - -/* - * @(#)ExampleFileFilter.java 1.13 02/06/13 - */ - - - -//import the packages for using the classes in them into the program -import java.io.File; -import java.util.Hashtable; -import java.util.Enumeration; -import javax.swing.filechooser.*; - -/** - * A convenience implementation of FileFilter that filters out - * all files except for those type extensions that it knows about. - * - * Extensions are of the type ".foo", which is typically found on - * Windows and Unix boxes, but not on Macinthosh. Case is ignored. - * - * Example - create a new filter that filerts out all files - * but gif and jpg image files: - * - * JFileChooser chooser = new JFileChooser(); - * ExampleFileFilter filter = new ExampleFileFilter( - * new String{"gif", "jpg"}, "JPEG & GIF Images") - * chooser.addChoosableFileFilter(filter); - * chooser.showOpenDialog(this); - * - * @version 1.13 06/13/02 - * @author Jeff Dinkins - */ -public class ExampleFileFilter extends FileFilter { - - -// private static String TYPE_UNKNOWN = "Type Unknown"; -// private static String HIDDEN_FILE = "Hidden File"; - - private Hashtable filters = null; - - - private String description = null; - - - private String fullDescription = null; - - - private boolean useExtensionsInDescription = true; - - - - /** - * Creates a file filter. If no filters are added, then all - * files are accepted. - * - * @see #addExtension - */ - public ExampleFileFilter(){ - this.filters = new Hashtable(); - } - - - - /** - * Creates a file filter that accepts files with the given extension. - * Example: new ExampleFileFilter("jpg"); - * - * @see #addExtension - */ - public ExampleFileFilter(String extension){ - this(extension,null); - } - - - - /** - * Creates a file filter that accepts the given file type. - * Example: new ExampleFileFilter("jpg", "JPEG Image Images"); - * - * Note that the "." before the extension is not needed. If - * provided, it will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String extension, String description){ - this(); - if(extension!=null) addExtension(extension); - if(description!=null) setDescription(description); - } - - - - /** - * Creates a file filter from the given string array. - * Example: new ExampleFileFilter(String {"gif", "jpg"}); - * - * Note that the "." before the extension is not needed adn - * will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String[] filters){ - this(filters, null); - } - - - - /** - * Creates a file filter from the given string array and description. - * Example: new ExampleFileFilter(String {"gif", "jpg"}, "Gif and JPG Images"); - * - * Note that the "." before the extension is not needed and will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String[] filters, String description){ - this(); - for (int i = 0; i < filters.length; i++){ - // add filters one by one - addExtension(filters[i]); - } - if(description!=null) setDescription(description); - } - - - - /** - * Return true if this file should be shown in the directory pane, - * false if it shouldn't. - * - * Files that begin with "." are ignored. - * - * @see #getExtension - * @see FileFilter#accepts - */ - public boolean accept(File f){ - if(f != null){ - if(f.isDirectory()){ - return true; - } - String extension = getExtension(f); - if(extension != null && filters.get(getExtension(f)) != null){ - return true; - }; - } - return false; - } - - - - /** - * Return the extension portion of the file's name . - * - * @see #getExtension - * @see FileFilter#accept - */ - public String getExtension(File f){ - if(f != null){ - String filename = f.getName(); - int i = filename.lastIndexOf('.'); - if(i>0 && i(5); - } - filters.put(extension.toLowerCase(), this); - fullDescription = null; - } - - - - /** - * Returns the human readable description of this filter. For - * example: "JPEG and GIF Image Files (*.jpg, *.gif)" - * - * @see setDescription - * @see setExtensionListInDescription - * @see isExtensionListInDescription - * @see FileFilter#getDescription - */ - @SuppressWarnings("rawtypes") - public String getDescription(){ - if(fullDescription == null) { - if(description == null || isExtensionListInDescription()){ - fullDescription = description==null ? "(" : description + " ("; - // build the description from the extension list - Enumeration extensions = filters.keys(); - if(extensions != null){ - fullDescription += "." + (String) extensions.nextElement(); - while (extensions.hasMoreElements()) { - fullDescription += ", ." + (String) extensions.nextElement(); - } - } - fullDescription += ")"; - } else { - fullDescription = description; - } - } - return fullDescription; - } - - - - /** - * Sets the human readable description of this filter. For - * example: filter.setDescription("Gif and JPG Images"); - * - * @see setDescription - * @see setExtensionListInDescription - * @see isExtensionListInDescription - */ - public void setDescription(String description){ - this.description = description; - fullDescription = null; - } - - - - /** - * Determines whether the extension list (.jpg, .gif, etc) should - * show up in the human readable description. - * - * Only relevent if a description was provided in the constructor - * or using setDescription(); - * - * @see getDescription - * @see setDescription - * @see isExtensionListInDescription - */ - public void setExtensionListInDescription(boolean b){ - useExtensionsInDescription = b; - fullDescription = null; - } - - - - /** - * Returns whether the extension list (.jpg, .gif, etc) should - * show up in the human readable description. - * - * Only relevent if a description was provided in the constructor - * or using setDescription(); - * - * @see getDescription - * @see setDescription - * @see setExtensionListInDescription - */ - public boolean isExtensionListInDescription(){ - return useExtensionsInDescription; - } - - -} diff --git a/java/spl/notepad/Variant00006java/Fonts.java b/java/spl/notepad/Variant00006java/Fonts.java deleted file mode 100644 index e63be0b..0000000 --- a/java/spl/notepad/Variant00006java/Fonts.java +++ /dev/null @@ -1,136 +0,0 @@ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - -/** - *A class for creating JFontDialog - */ -public class Fonts extends JDialog { - - private static final long serialVersionUID = 1L; - - - /** - *@see Center.java - *this class to make the JDialog in the center - */ - public Center center = new Center(this); - - - - //declaration of the private variables used in the program - private JPanel jp = new JPanel(); - - - private JLabel fjl = new JLabel("Fonts: "); - - - private JComboBox fjcb = new JComboBox(); - - - /** - *-> GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames() <- - * WE USING THIS METHOD TO GET ALL FONT IN THE SYSTEM (OS) - */ - private String fonts[]=GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); - - - private JLabel sjl = new JLabel("Sizes: "); - - - private JComboBox sjcb = new JComboBox(); - - - private String sizes[] = {"8","10","12","14","16","18","20","24","28","32","48","72"}; - - - private JLabel tjl = new JLabel("Types: "); - - - private JComboBox tjcb = new JComboBox(); - - - private String types[] = {"Regular", "Bold", "Italic", "Bold Italic"}; - - - private JLabel jjl = new JLabel("Preview:"); - - - private JLabel jl = new JLabel("AaBaCcDdeEfFgGhHjJ"); - - - private JButton okjb = new JButton("OK"); - - - private JButton cajb = new JButton("Cancel"); - - - //for using ok & cancel button @Actions.java - public JButton getOkjb(){ - return okjb; - } - - - public JButton getCajb(){ - return cajb; - } - - - //Constructor of Fonts - public Fonts(){ - //for setting the title - setTitle("Font Dialog"); - setResizable(false); - /** - *setting the layout (GridLayout: 5 rows & 2 columns) - *add font JLabel, add font JComboBox - *add type JLabel, add type JComboBox - *add size JLabel, add size JComboBox - *add preview JLabel,add test JLabel - *add ok button, add cancel button - */ - jp.setLayout(new GridLayout(5,2,1,1)); - jp.add(fjl); - jp.add(fjcb = new JComboBox(fonts)); - jp.add(sjl); - jp.add(sjcb = new JComboBox(sizes)); - jp.add(tjl); - jp.add(tjcb = new JComboBox(types)); - jp.add(jjl); - jl.setBorder(BorderFactory.createEtchedBorder()); - jp.add(jl); - jp.add(okjb); - jp.add(cajb); - //add JPanel to the Container - this.getContentPane().add(jp); - /** - *for making JDialog at the center, - *@Center.java - */ - center.fCenter(); - //add action listener to Font JComboBox to get the selected item for setting the preview - fjcb.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - jl.setFont(new Font(String.valueOf(fjcb.getSelectedItem()),tjcb.getSelectedIndex(),14)); - } - }); - //add action listener to Type JComboBox to get the selected index for setting the preview - tjcb.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - jl.setFont(new Font(String.valueOf(fjcb.getSelectedItem()),tjcb.getSelectedIndex(),14)); - } - }); - } - - - /* - *@return font value: (Font,Type,Size) - */ - public Font font(){ - Font font = new Font(String.valueOf(fjcb.getSelectedItem()), tjcb.getSelectedIndex(), - Integer.parseInt(String.valueOf(sjcb.getSelectedItem()))); - return font; - } - - -} diff --git a/java/spl/notepad/Variant00006java/Notepad.java b/java/spl/notepad/Variant00006java/Notepad.java deleted file mode 100644 index d911ce5..0000000 --- a/java/spl/notepad/Variant00006java/Notepad.java +++ /dev/null @@ -1,388 +0,0 @@ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; import javax.swing.undo.*; -import javax.swing.event.*; - -public - -class Notepad extends JFrame { - - private static final long serialVersionUID = 1; - - - //for using the methods in these classes - public Actions actions = new Actions(this); - - - public Center center = new Center(this); - - - - //declaration of the private variables used in the program - //create the text area - private JTextArea textArea; - - - //create the Menu Bar that contains the JMenu "filE, ediT, vieW, formaT, helP" - private JMenuBar Menubar; - - - //Create the menu that contains the items - private JMenu filE, ediT, vieW, formaT, helP; - - - //Create the menu items - private JMenuItem neW, opeN, savE, saveAS, prinT, exiT, fonT, abouT, - cuT, copY, pastE, selectALL; - - - private JCheckBoxMenuItem lineWraP; - - - //Create the Tool Bar that contains the JButton - private JToolBar toolBar; - - - //Create the buttons - private JButton newButton, openButton, saveButton, saveAsButton, printButton, - fontButton, aboutButton; - - - - //for using lineWrap & textArea @Actions.java - public JCheckBoxMenuItem getLineWrap(){ - return lineWraP; - } - - - public JTextArea getTextArea(){ - return textArea; - } - - - - public Notepad (){ - //set the title for Notepad and set the size for it. - setTitle("Untitled - JAVA??? Notepad"); - setSize(800,600); - - //get the graphical user interface components display area - Container cp = getContentPane(); - /** - *adding the text area, - *adding the tool bar & - *adding the scroll pane to the container - */ - cp.add(textArea = new JTextArea()); - cp.add("North", toolBar = new JToolBar("Tool Bar")); - cp.add(new JScrollPane(textArea)); - - //for setting the menu bar - setJMenuBar(Menubar= new JMenuBar()); - //adding file, edit, view, format, help to the menu bar - Menubar.add(filE = new JMenu("File")); - Menubar.add(ediT = new JMenu("Edit")); - Menubar.add(vieW = new JMenu("View")); - Menubar.add(formaT = new JMenu("Format")); - Menubar.add(helP = new JMenu("Help")); - - /** - *adding neW, opeN, savE, saveAS, prinT & exiT to the filE Menu, - *adding a small image icon to the menu item & - *adding separator between the menu item - */ - filE.add(neW = new JMenuItem("New", new ImageIcon(this.getClass().getResource("images/new.gif")))); - filE.add(opeN = new JMenuItem("Open", new ImageIcon(this.getClass().getResource("images/open.gif")))); - filE.add(savE = new JMenuItem("Save", new ImageIcon(this.getClass().getResource("images/save.gif")))); - filE.add(saveAS = new JMenuItem("Save As", new ImageIcon(this.getClass().getResource("images/saveAs.gif")))); - filE.add(prinT = new JMenuItem("Print", new ImageIcon(this.getClass().getResource("images/print.gif")))); - filE.add(exiT = new JMenuItem("Exit")); //, new ImageIcon(this.getClass().getResource("images/exit.gif")))); -- exit.gif missing - filE.insertSeparator(4); - filE.insertSeparator(6); - - /** - *adding undO, redO, cuT, copY, pastE, finD, findNexT & selectALL to the ediT Menu, - *adding a small image icon to the menu item & - *adding separator between the menu item - */ - ediT.add(selectALL= new JMenuItem("Select All")); - //ediT.insertSeparator(2); - //ediT.insertSeparator(6); - - /** - *adding lineWraP & fonT to the formaT Menu, - *adding abouT to the helP Menu & - *adding a small image icon to the menu item - */ - formaT.add(lineWraP = new JCheckBoxMenuItem("Line Wrap")); - formaT.add(fonT = new JMenuItem("Font", new ImageIcon(this.getClass().getResource("images/font.gif")))); - helP.add(abouT = new JMenuItem("About Notepad", new ImageIcon(this.getClass().getResource("images/about.gif")))); - - /** - *allowing the file menu to be selected by pressing ALT + F - *allowing the edit menu to be selected by pressing ALT + E - *allowing the view menu to be selected by pressing ALT + V - *allowing the format menu to be selected by pressing ALT + O - *allowing the help menu to be selected by pressing ALT + H - */ - filE.setMnemonic('f'); - ediT.setMnemonic('e'); - vieW.setMnemonic('v'); - formaT.setMnemonic('o'); - helP.setMnemonic('h'); - - /** - *allowing the neW menu item to be selected by pressing ALT + N - *allowing the opeN menu item to be selected by pressing ALT + O - *allowing the savE menu item to be selected by pressing ALT + S - *allowing the prinT menu item to be selected by pressing ALT + P - *allowing the exiT menu item to be selected by pressing ALT + F4 - *allowing the cuT menu item to be selected by pressing ALT + X - *allowing the copY menu item to be selected by pressing ALT + C - *allowing the pastE menu item to be selected by pressing ALT + V - *allowing the selectAll menu item to be selected by pressing ALT + A - */ - neW.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK)); - opeN.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK)); - savE.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK)); - prinT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.CTRL_MASK)); - exiT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, ActionEvent.CTRL_MASK)); - selectALL.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.CTRL_MASK)); - - /** - *adding newButton, openButton, saveButton, saveAsButton, printButton, undoButton, - *redoButton, cutButton, copyButton, pasteButton, fontButton & aboutButton to the tool bar, - *adding a small image icon to the menu item & - *adding separator between the button - */ - toolBar.add(newButton = new JButton(new ImageIcon(this.getClass().getResource("images/new.gif")))); - toolBar.add(openButton = new JButton(new ImageIcon(this.getClass().getResource("images/open.gif")))); - toolBar.add(saveButton = new JButton(new ImageIcon(this.getClass().getResource("images/save.gif")))); - toolBar.add(saveAsButton= new JButton(new ImageIcon(this.getClass().getResource("images/saveAs.gif")))); - toolBar.add(printButton = new JButton(new ImageIcon(this.getClass().getResource("images/print.gif")))); - toolBar.addSeparator(); - toolBar.add(fontButton = new JButton(new ImageIcon(this.getClass().getResource("images/font.gif")))); - toolBar.add(aboutButton = new JButton(new ImageIcon(this.getClass().getResource("images/about.gif")))); - - //adding a tool tip text to the button for descriping the image icon. - newButton.setToolTipText("New"); - openButton.setToolTipText("Open"); - saveButton.setToolTipText("Save"); - saveAsButton.setToolTipText("Save As"); - printButton.setToolTipText("Print"); - fontButton.setToolTipText("Font"); - aboutButton.setToolTipText("About Notepad"); - - /** - *setting the default close operation to false & - *using own action (exiT action @Actions.java) - */ - setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); - addWindowListener(new WindowAdapter(){ - public void windowClosing(WindowEvent e){ - actions.exiT(); - } - }); - /** - *adding action listener for menu item: neW, opeN, savE, saveAS, prinT, exiT, - *redO, undO, copY, cuT, pastE, finD, findNexT, selectALL, lineWraP, fonT & abouT - *the actions was written @Actions.java - */ - neW.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.neW(); - } - }); - opeN.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.opeN(); - } - }); - savE.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.savE(); - } - }); - saveAS.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.saveAs(); - } - }); - prinT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.prinT(); - } - }); - exiT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.exiT(); - } - }); - selectALL.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.selectALL(); - } - }); - lineWraP.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.lineWraP(); - } - }); - fonT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.fonT(); - } - }); - abouT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.abouT(); - } - }); - - /** - *adding action listener for the button in the tool bar: newButton, openButton, - *saveButton, saveAsButton, printButton, redoButton, undoButton, copyButton, - *cutButton, pasteButton, findButton, selectALL, lineWraP, fontButton & aboutButton - *the actions was written @Actions.java - */ - newButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.neW(); - } - }); - openButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.opeN(); - } - }); - saveButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.savE(); - } - }); - saveAsButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.saveAs(); - } - }); - printButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.prinT(); - } - }); - fontButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.fonT(); - } - }); - aboutButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.abouT(); - } - }); - - /** - *Setting the Line Wrap & Wrap Style Word features are true - */ - textArea.setLineWrap(true); - textArea.setWrapStyleWord(true); - /** - *for making the program at the center, - *@see Center.java - */ - center.nCenter(); - show(); - - ediT.add(cuT = new JMenuItem("Cut", new ImageIcon(this.getClass().getResource("images/cut.gif")))); - ediT.add(copY = new JMenuItem("Copy", new ImageIcon(this.getClass().getResource("images/copy.gif")))); - ediT.add(pastE= new JMenuItem("Paste",new ImageIcon(this.getClass().getResource("images/paste.gif")))); - - cuT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.CTRL_MASK)); - copY.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK)); - pastE.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.CTRL_MASK)); - - toolBar.add(cutButton = new JButton(new ImageIcon(this.getClass().getResource("images/cut.gif")))); - toolBar.add(copyButton = new JButton(new ImageIcon(this.getClass().getResource("images/copy.gif")))); - toolBar.add(pasteButton = new JButton(new ImageIcon(this.getClass().getResource("images/paste.gif")))); - - cutButton.setToolTipText("Cut"); - copyButton.setToolTipText("Copy"); - pasteButton.setToolTipText("Paste"); - - cuT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.cuT(); - } - }); - copY.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.copY(); - } - }); - pastE.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.pastE(); - } - }); - - cutButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.cuT(); - } - }); - copyButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.copY(); - } - }); - pasteButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.pastE(); - } - }); - - - ediT.add(undoAction); - ediT.add(redoAction); - - toolBar.addSeparator(); - toolBar.add(undoAction); - toolBar.add(redoAction); - toolBar.addSeparator(); - - textArea.getDocument().addUndoableEditListener(new UndoableEditListener(){ - public void undoableEditHappened(UndoableEditEvent e){ - //Remember the edit and update the menus - undo.addEdit(e.getEdit()); - undoAction.update(); - redoAction.update(); - } - }); - } - - - //Main Method - public static void main(String[] args){ - new Notepad(); - - } - - - private JButton cutButton, copyButton, pasteButton; - - - //for using undo & redo - UndoManager undo = new UndoManager(); - - - UndoAction undoAction = new UndoAction(this); - - - RedoAction redoAction = new RedoAction(this); - - - - private JButton undoButton, redoButton; - - -} diff --git a/java/spl/notepad/Variant00006java/Print.java b/java/spl/notepad/Variant00006java/Print.java deleted file mode 100644 index 132daed..0000000 --- a/java/spl/notepad/Variant00006java/Print.java +++ /dev/null @@ -1,64 +0,0 @@ -import java.awt.*; -import java.awt.print.*; -import javax.swing.*; - -/** - *A class for creating a printer option. - */ -public class Print implements Printable { - - private Component componentToBePrinted; - - - - public static void printComponent(Component c){ - new Print(c).print(); - } - - - public Print(Component componentToBePrinted){ - this.componentToBePrinted = componentToBePrinted; - } - - - public void print(){ - PrinterJob printJob = PrinterJob.getPrinterJob(); - printJob.setPrintable(this); - if(printJob.printDialog()) - try{ - printJob.print(); - } - catch(PrinterException pe){ - System.out.println("Error printing: " + pe); - } - } - - - public int print(Graphics g, PageFormat pageFormat, int pageIndex){ - if(pageIndex > 0){ - return(NO_SUCH_PAGE); - } - else{ - Graphics2D g2d = (Graphics2D)g; - g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); - disableDoubleBuffering(componentToBePrinted); - componentToBePrinted.paint(g2d); - enableDoubleBuffering(componentToBePrinted); - return(PAGE_EXISTS); - } - } - - - public static void disableDoubleBuffering(Component c){ - RepaintManager currentManager = RepaintManager.currentManager(c); - currentManager.setDoubleBufferingEnabled(false); - } - - - public static void enableDoubleBuffering(Component c){ - RepaintManager currentManager = RepaintManager.currentManager(c); - currentManager.setDoubleBufferingEnabled(true); - } - - -} diff --git a/java/spl/notepad/Variant00006java/RedoAction.java b/java/spl/notepad/Variant00006java/RedoAction.java deleted file mode 100644 index ccd8eaf..0000000 --- a/java/spl/notepad/Variant00006java/RedoAction.java +++ /dev/null @@ -1,50 +0,0 @@ -import java.awt.event.*; -import javax.swing.*; -import javax.swing.undo.*; - - - -class RedoAction extends AbstractAction { - - private static final long serialVersionUID = 1; - - - Notepad notepad; - - - - public RedoAction(Notepad notepad){ - super("Redo"); - putValue( Action.SMALL_ICON, - new ImageIcon(this.getClass().getResource("images/redo.gif"))); - setEnabled(false); - this.notepad = notepad; - } - - - public void actionPerformed(ActionEvent e){ - try{ - notepad.undo.redo(); - } - catch (CannotRedoException ex){ - System.out.println("Unable to redo: " + ex); - ex.printStackTrace(); - } - update(); - notepad.undoAction.update(); - } - - - protected void update(){ - if(notepad.undo.canRedo()){ - setEnabled(true); - putValue("Redo", notepad.undo.getRedoPresentationName()); - } - else{ - setEnabled(false); - putValue(Action.NAME, "Redo"); - } - } - - -} diff --git a/java/spl/notepad/Variant00006java/UndoAction.java b/java/spl/notepad/Variant00006java/UndoAction.java deleted file mode 100644 index 3298a36..0000000 --- a/java/spl/notepad/Variant00006java/UndoAction.java +++ /dev/null @@ -1,50 +0,0 @@ -import java.awt.event.*; -import javax.swing.*; -import javax.swing.undo.*; - - - -class UndoAction extends AbstractAction { - - private static final long serialVersionUID = 1; - - - Notepad notepad; - - - - public UndoAction(Notepad notepad){ - super( "Undo" ); - putValue( Action.SMALL_ICON, - new ImageIcon( this.getClass().getResource( "images/undo.gif" ) ) ); - setEnabled( false ); - this.notepad = notepad; - } - - - public void actionPerformed( ActionEvent e ) { - try { - notepad.undo.undo(); - } - catch ( CannotUndoException ex ) { - System.out.println( "Unable to undo: " + ex ); - ex.printStackTrace(); - } - update(); - notepad.redoAction.update(); - } - - - protected void update() { - if( notepad.undo.canUndo() ) { - setEnabled( true ); - putValue( "Undo", notepad.undo.getUndoPresentationName() ); - } - else { - setEnabled( false ); - putValue( Action.NAME, "Undo" ); - } - } - - -} diff --git a/java/spl/notepad/Variant00007java/About.java b/java/spl/notepad/Variant00007java/About.java deleted file mode 100644 index fb751fd..0000000 --- a/java/spl/notepad/Variant00007java/About.java +++ /dev/null @@ -1,25 +0,0 @@ -import javax.swing.*; - -/** - *A CLASS FOR CREATING ABOUT PANEL - */ -public class About extends JPanel { - - private static final long serialVersionUID = 1; - - - public About(){ - //Create a Label & an image icon in it - JLabel label1 = new JLabel(new ImageIcon(this.getClass().getResource("images/java.gif"))); - //adding label1 to the JPanel - this.add(label1); - //Create a Label & put a HTML script - JLabel label2 = new JLabel("
  • JAVA??? Notepad
  • Ver# 2.0

  • " - +"
  • Coded by: Salah Al-Thubaiti

  • KFUPM, CS

  • " - +"

    CopyRight??? 2001-2002

  • "); - //adding label2 to the JPanel - this.add(label2); - } - - -} diff --git a/java/spl/notepad/Variant00007java/Actions.java b/java/spl/notepad/Variant00007java/Actions.java deleted file mode 100644 index aacba1d..0000000 --- a/java/spl/notepad/Variant00007java/Actions.java +++ /dev/null @@ -1,497 +0,0 @@ -import java.io.*; -import java.util.*; -import java.awt.event.*; -import javax.swing.*; public class Actions { - - //declaration of the private variables used in the program - private int returnVal; - - //for JFileChooser - private int option; - - //for using it into JOptionPane - private String fileContent = null; - - //to get the text from the text area - private String fileName = null; - - //for using the name of the file - private JFileChooser jfc = new JFileChooser("."); - - //for using a open & save dialog - private ExampleFileFilter filter = new ExampleFileFilter(); - - //for filtering the file - Notepad n; - - //for using the object in the Notepad.java - public Fonts font = new Fonts(); - - - - public Actions(Notepad n){ - this.n = n; - } - - - /** - *If we want to write a new text, first we want to know if the text area is empty or not, - *second we want to know if the text was saved or not. - *If the text area isn't empty & the text wasn't saved before this time, then the program display -> - *for the user an option for saving the text in a new file or in the same file - */ - public void neW(){ - /** - *if the text area isn't empty & if the text area hasn't - *a text not saved before (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - /** - *here, we have two things, first if the text wasn't be opened or saved before - *second if the text was be opened or saved - */ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - //if the user click on YES button, - //then the program will save the text & make a new text area - if(option == 0){ - //to save the text into a new file - saveAs(); - //to create new getTextArea() after saving the old getTextArea() - n.getTextArea().setText(""); - } - //if the user click on NO button - if(option == 1){ - //to create new getTextArea() without saving the old getTextArea() - n.getTextArea().setText(""); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will save the text into the old file & - *make a new text area,,, - */ - if(option == 0){ - save(); - //to create new getTextArea() after saving the old getTextArea() - n.getTextArea().setText(""); - } - //if the user click on NO button - if(option == 1){ - //to create new getTextArea() without saving the old getTextArea() - n.getTextArea().setText(""); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to write a new text,,, this option will be actived - */ - else{ - n.getTextArea().setText(""); - } - n.setTitle("Untitled - JAVA??? Notepad"); - } - - - /** - *If we want to open a new text, first we want to know if the text area - * is empty or not, second we want to kwnow if the text was saved or not. - *If the text area isn't empty & the text wasn't saved befor this time, - *then the program display for the user an option for saving the text - *in a new file or in the same file - */ - public void opeN(){ - /** - *if the text area isn't empty & if the text area hasn't a text which - *not saved befor (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - /** - *here, we have 2 thing, first if the text wasn't be opened or saved befor - *second if the text was be opened or saved - */ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - //if the user click on YES button, - //then the program will be saved the text & opened a new documents - if(option == 0){ - //for saving the text in a new file - saveAs(); - //for opening the new documents - open(); - } - /** - *if the user click on NO button, - *the program will be opened the new documents - */ - if(option == 1){ - //for opening the new documents - open(); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will save the text into the same file & - *open the new documents - */ - if(option == 0){ - //for saving the text into the same file - save(); - //for opening the new documents - open(); - } - /** - *if the user click on NO button, - *the program will be opened the new documents - */ - if(option == 1){ - //for opening the new documents - open(); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to open a new document,,, this option will be actived - */ - else{ - //for opening the new documents - open(); - } - } - - - /** - *THIS IS FOR SAVE ACTION, SaveAs ACTION has saveAs() method - *If we want to save a new text, then we want to know - *if the text was saved befor or not. - *If the text wasn't be saved befor, then we will use saveAs() - *If the text was be save befor, then we will use save() - */ - public void savE(){ - /** - *if String fileName is null, then using saveAs(). - *Because there was no file was be saved - */ - if(fileName == null){ - saveAs(); - } - /** - *if String fileName has a String (file name), then using save(). - *Because we want to save the new text in the same file. - *if the user want to save the all text (old & new text) in a new file, -> - *he can presses SaveAs button (@saveAs()) - */ - else{ - save(); - } - } - - - /** - *THIS FROM SUN??? WEBSITE (@Print.java) - *if we want to print the text, we can do this by print method - */ - public void prinT(){ - //import printer class - Print.printComponent(n.getTextArea()); - } - - - /** - *If we want to exit from the program, - *first we want to know if the text area is empty or not, - *second we want to kwnow if the text was saved or not. - *If the text area isn't empty & the text wasn't saved befor this time, - *then the program display -> - *for the user an option for saving the text in a new file or in the same file - */ - public void exiT(){ - /** - *if the text area isn't empty & if the text area hasn't a text which - *not saved befor (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will be saved the text & close the program - */ - if(option == 0){ - //for saving the text into new file - saveAs(); - //for closing the program - System.exit(0); - } - /** - *if the user click on NO button, - *then the program will be closed without save the text - */ - if(option == 1){ - //for closing the program - System.exit(0); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will be saved the text & close the program - */ - if(option == 0){ - //for saving the text into the same file - save(); - //for closing the program - System.exit(0); - } - /** - *if the user click on NO button, - *then the program will be closed without save the text - */ - if(option == 1){ - //for closing the program - System.exit(0); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to close the program. This option will be actived - */ - else{ - //for closing the program - System.exit(0); - } - } - - - //to select all the text - public void selectALL(){ - n.getTextArea().selectAll(); - } - - - //for wraping the line & wraping the style word - public void lineWraP(){ - if(n.getLineWrap().isSelected()){ - /** - *make the line wrap & wrap style word is true - *when the line wrap is selected - */ - n.getTextArea().setLineWrap(true); - n.getTextArea().setWrapStyleWord(true); - } - else{ - /** - *make the line wrap & wrap style word is false - *when the line wrap isn't selected - */ - n.getTextArea().setLineWrap(false); - n.getTextArea().setWrapStyleWord(false); - } - } - - - /** - *@see FONTS.JAVA - *this is a font class which is for changing the font, style & size - */ - public void fonT(){ - font.setVisible(true); //setting the visible is true - font.pack(); //pack the panel - //making an action for ok button, so we can change the font - font.getOkjb().addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - n.getTextArea().setFont(font.font()); - //after we chose the font, then the JDialog will be closed - font.setVisible(false); - } - }); - //making an action for cancel button, so we can return to the old font. - font.getCajb().addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - //after we cancel the, then the JDialog will be closed - font.setVisible(false); - } - }); - } - - - /** - *@see ABOUT.JAVA - *it's a Message Dialog to show the information about this program - */ - public void abouT(){ - JOptionPane.showMessageDialog(null, new About(),"About Notepad",JOptionPane.PLAIN_MESSAGE); - } - - - /** - *THIS IS THE WAY FOR OPENING THE TEXT FILE - */ - public void open(){ - //filter the kind of files, we want only TXT file - filter.addExtension("txt"); - //to set a description for the file (TXT) - filter.setDescription("TXT Documents"); - //setting the FileFilter to JFileChooser - jfc.setFileFilter(filter); - returnVal = jfc.showOpenDialog(n); //to show JFileChooser - if(returnVal == JFileChooser.APPROVE_OPTION){ - //to erase any text in the text area before adding new text - n.getTextArea().setText(null); - try{ - //to get the name of the selected file - fileName = jfc.getSelectedFile().getPath(); - //to read the selected file - Reader in = new FileReader(jfc.getSelectedFile()); - //100000 is the max. char can be written in the text area - char[] buff = new char[100000]; - int nch; - while((nch = in.read(buff, 0, buff.length)) != -1) - n.getTextArea().append(new String(buff, 0, nch)); - //to get more text from the file if the array wasn't full - fileContent = n.getTextArea().getText(); - } - catch(FileNotFoundException x){} - catch(IOException ioe){ - System.err.println("I/O Error on Open"); - } - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - /** - *THIS IS THE WAY FOR SAVING THE TEXT IN THE SAME FILE - */ - public void save(){ - //initializing 'fout' to write all text in the selected file - try{ - PrintWriter fout = new PrintWriter(new FileWriter(jfc.getSelectedFile())); - //for getting the text from the text area - fileContent = n.getTextArea().getText(); - //using StringTokenizer for the 'fileContent' String - StringTokenizer st=new StringTokenizer(fileContent,System.getProperty("line.separator")); - while(st.hasMoreTokens()){ - //write the string (text) in the selected file - fout.println(st.nextToken()); - } - //closing fout - fout.close(); - } - catch(IOException ioe){ - System.err.println("I/O Error on Save"); - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - /** - *THIS IS THE WAY FOR SAVING THE TEXT IN A NEW FILE - */ - public void saveAs(){ - //filter the kind of files, we want only TXT file - filter.addExtension("txt"); - //to set a description for the file (TXT) - filter.setDescription("TXT Documents"); - //setting the FileFilter to JFileChooser - jfc.setFileFilter(filter); - returnVal = jfc.showSaveDialog(n); - if(returnVal == JFileChooser.APPROVE_OPTION){ - //initializing the PrintWriter, to save the text in a new file - PrintWriter fout = null; - try{ - fout = new PrintWriter(new FileWriter(jfc.getSelectedFile() + ".txt")); - //getting the text from the text area - fileContent = n.getTextArea().getText(); - //getting the name of the selected file - fileName = jfc.getSelectedFile().getPath(); - //using StringTokenizer for the 'fileContent' String - StringTokenizer st=new StringTokenizer(fileContent,System.getProperty("line.separator")); - while(st.hasMoreTokens()){ - //write the string (text) in the selected file - fout.println(st.nextToken()); - } - //closing 'fout' - fout.close(); - } - catch(IOException ioe){ - System.err.println ("I/O Error on Save"); - } - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - private String findword; - - //for searching & finding the word - //this is a method for searching the input text from the text area - - public void finD(){ - try{ - //this is an input dialog which return a string (findword) - findword = JOptionPane.showInputDialog("Type the word to find"); - //if the JTextField in the input dialog is empty (null), then return a message dialog - while(n.getTextArea().getText().indexOf(findword) == -1){ - /** - *this is a message dialog which is warning the user, - *because he didn't or forgot to enter the word - */ - JOptionPane.showMessageDialog(null,"Word not found!","No match",JOptionPane.WARNING_MESSAGE); - findword = JOptionPane.showInputDialog("Type the word to find"); - } - //for selecting the word which the user search for it - n.getTextArea().select(n.getTextArea().getText().indexOf(findword), - n.getTextArea().getText().indexOf(findword) + findword.length()); - } - catch(Exception ex){ - JOptionPane.showMessageDialog(null,"Search canceled","Abourted",JOptionPane.WARNING_MESSAGE); - } - } - - - public void findNexT(){ - n.getTextArea().select(n.getTextArea().getText().indexOf(findword,(int)n.getTextArea().getText().indexOf(findword)+1), - n.getTextArea().getText().indexOf(findword,(int)n.getTextArea().getText().indexOf(findword)+1)); - } - - -} diff --git a/java/spl/notepad/Variant00007java/Center.java b/java/spl/notepad/Variant00007java/Center.java deleted file mode 100644 index 1715525..0000000 --- a/java/spl/notepad/Variant00007java/Center.java +++ /dev/null @@ -1,37 +0,0 @@ -import java.awt.*; -/** - *A PUBLIC CLASS FOR CENTER.JAVA - */ -public class Center { - - Notepad n; - - //for using the object in the Notepad.java - Fonts f; - - //for using the object in the Fonts.java - public Center(Notepad n){ - this.n = n; - } - - - public Center(Fonts f){ - this.f = f; - } - - - public void nCenter(){ - //Centering the window - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - n.setLocation((screenSize.width-n.getWidth())/2,(screenSize.height-n.getHeight())/2); - } - - - public void fCenter(){ - //Centering the window - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - f.setLocation((screenSize.width-f.getWidth())/2,(screenSize.height-f.getHeight())/2); - } - - -} diff --git a/java/spl/notepad/Variant00007java/ExampleFileFilter.java b/java/spl/notepad/Variant00007java/ExampleFileFilter.java deleted file mode 100644 index 47b0dd6..0000000 --- a/java/spl/notepad/Variant00007java/ExampleFileFilter.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (c) 2002 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * -Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * -Redistribution in binary form must reproduct the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING - * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT - * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT - * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS - * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST - * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, - * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY - * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN - * IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that Software is not designed, licensed or intended for - * use in the design, construction, operation or maintenance of any nuclear - * facility. - */ - -/* - * @(#)ExampleFileFilter.java 1.13 02/06/13 - */ - - - -//import the packages for using the classes in them into the program -import java.io.File; -import java.util.Hashtable; -import java.util.Enumeration; -import javax.swing.filechooser.*; - -/** - * A convenience implementation of FileFilter that filters out - * all files except for those type extensions that it knows about. - * - * Extensions are of the type ".foo", which is typically found on - * Windows and Unix boxes, but not on Macinthosh. Case is ignored. - * - * Example - create a new filter that filerts out all files - * but gif and jpg image files: - * - * JFileChooser chooser = new JFileChooser(); - * ExampleFileFilter filter = new ExampleFileFilter( - * new String{"gif", "jpg"}, "JPEG & GIF Images") - * chooser.addChoosableFileFilter(filter); - * chooser.showOpenDialog(this); - * - * @version 1.13 06/13/02 - * @author Jeff Dinkins - */ -public class ExampleFileFilter extends FileFilter { - - -// private static String TYPE_UNKNOWN = "Type Unknown"; -// private static String HIDDEN_FILE = "Hidden File"; - - private Hashtable filters = null; - - - private String description = null; - - - private String fullDescription = null; - - - private boolean useExtensionsInDescription = true; - - - - /** - * Creates a file filter. If no filters are added, then all - * files are accepted. - * - * @see #addExtension - */ - public ExampleFileFilter(){ - this.filters = new Hashtable(); - } - - - - /** - * Creates a file filter that accepts files with the given extension. - * Example: new ExampleFileFilter("jpg"); - * - * @see #addExtension - */ - public ExampleFileFilter(String extension){ - this(extension,null); - } - - - - /** - * Creates a file filter that accepts the given file type. - * Example: new ExampleFileFilter("jpg", "JPEG Image Images"); - * - * Note that the "." before the extension is not needed. If - * provided, it will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String extension, String description){ - this(); - if(extension!=null) addExtension(extension); - if(description!=null) setDescription(description); - } - - - - /** - * Creates a file filter from the given string array. - * Example: new ExampleFileFilter(String {"gif", "jpg"}); - * - * Note that the "." before the extension is not needed adn - * will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String[] filters){ - this(filters, null); - } - - - - /** - * Creates a file filter from the given string array and description. - * Example: new ExampleFileFilter(String {"gif", "jpg"}, "Gif and JPG Images"); - * - * Note that the "." before the extension is not needed and will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String[] filters, String description){ - this(); - for (int i = 0; i < filters.length; i++){ - // add filters one by one - addExtension(filters[i]); - } - if(description!=null) setDescription(description); - } - - - - /** - * Return true if this file should be shown in the directory pane, - * false if it shouldn't. - * - * Files that begin with "." are ignored. - * - * @see #getExtension - * @see FileFilter#accepts - */ - public boolean accept(File f){ - if(f != null){ - if(f.isDirectory()){ - return true; - } - String extension = getExtension(f); - if(extension != null && filters.get(getExtension(f)) != null){ - return true; - }; - } - return false; - } - - - - /** - * Return the extension portion of the file's name . - * - * @see #getExtension - * @see FileFilter#accept - */ - public String getExtension(File f){ - if(f != null){ - String filename = f.getName(); - int i = filename.lastIndexOf('.'); - if(i>0 && i(5); - } - filters.put(extension.toLowerCase(), this); - fullDescription = null; - } - - - - /** - * Returns the human readable description of this filter. For - * example: "JPEG and GIF Image Files (*.jpg, *.gif)" - * - * @see setDescription - * @see setExtensionListInDescription - * @see isExtensionListInDescription - * @see FileFilter#getDescription - */ - @SuppressWarnings("rawtypes") - public String getDescription(){ - if(fullDescription == null) { - if(description == null || isExtensionListInDescription()){ - fullDescription = description==null ? "(" : description + " ("; - // build the description from the extension list - Enumeration extensions = filters.keys(); - if(extensions != null){ - fullDescription += "." + (String) extensions.nextElement(); - while (extensions.hasMoreElements()) { - fullDescription += ", ." + (String) extensions.nextElement(); - } - } - fullDescription += ")"; - } else { - fullDescription = description; - } - } - return fullDescription; - } - - - - /** - * Sets the human readable description of this filter. For - * example: filter.setDescription("Gif and JPG Images"); - * - * @see setDescription - * @see setExtensionListInDescription - * @see isExtensionListInDescription - */ - public void setDescription(String description){ - this.description = description; - fullDescription = null; - } - - - - /** - * Determines whether the extension list (.jpg, .gif, etc) should - * show up in the human readable description. - * - * Only relevent if a description was provided in the constructor - * or using setDescription(); - * - * @see getDescription - * @see setDescription - * @see isExtensionListInDescription - */ - public void setExtensionListInDescription(boolean b){ - useExtensionsInDescription = b; - fullDescription = null; - } - - - - /** - * Returns whether the extension list (.jpg, .gif, etc) should - * show up in the human readable description. - * - * Only relevent if a description was provided in the constructor - * or using setDescription(); - * - * @see getDescription - * @see setDescription - * @see setExtensionListInDescription - */ - public boolean isExtensionListInDescription(){ - return useExtensionsInDescription; - } - - -} diff --git a/java/spl/notepad/Variant00007java/Fonts.java b/java/spl/notepad/Variant00007java/Fonts.java deleted file mode 100644 index e63be0b..0000000 --- a/java/spl/notepad/Variant00007java/Fonts.java +++ /dev/null @@ -1,136 +0,0 @@ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - -/** - *A class for creating JFontDialog - */ -public class Fonts extends JDialog { - - private static final long serialVersionUID = 1L; - - - /** - *@see Center.java - *this class to make the JDialog in the center - */ - public Center center = new Center(this); - - - - //declaration of the private variables used in the program - private JPanel jp = new JPanel(); - - - private JLabel fjl = new JLabel("Fonts: "); - - - private JComboBox fjcb = new JComboBox(); - - - /** - *-> GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames() <- - * WE USING THIS METHOD TO GET ALL FONT IN THE SYSTEM (OS) - */ - private String fonts[]=GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); - - - private JLabel sjl = new JLabel("Sizes: "); - - - private JComboBox sjcb = new JComboBox(); - - - private String sizes[] = {"8","10","12","14","16","18","20","24","28","32","48","72"}; - - - private JLabel tjl = new JLabel("Types: "); - - - private JComboBox tjcb = new JComboBox(); - - - private String types[] = {"Regular", "Bold", "Italic", "Bold Italic"}; - - - private JLabel jjl = new JLabel("Preview:"); - - - private JLabel jl = new JLabel("AaBaCcDdeEfFgGhHjJ"); - - - private JButton okjb = new JButton("OK"); - - - private JButton cajb = new JButton("Cancel"); - - - //for using ok & cancel button @Actions.java - public JButton getOkjb(){ - return okjb; - } - - - public JButton getCajb(){ - return cajb; - } - - - //Constructor of Fonts - public Fonts(){ - //for setting the title - setTitle("Font Dialog"); - setResizable(false); - /** - *setting the layout (GridLayout: 5 rows & 2 columns) - *add font JLabel, add font JComboBox - *add type JLabel, add type JComboBox - *add size JLabel, add size JComboBox - *add preview JLabel,add test JLabel - *add ok button, add cancel button - */ - jp.setLayout(new GridLayout(5,2,1,1)); - jp.add(fjl); - jp.add(fjcb = new JComboBox(fonts)); - jp.add(sjl); - jp.add(sjcb = new JComboBox(sizes)); - jp.add(tjl); - jp.add(tjcb = new JComboBox(types)); - jp.add(jjl); - jl.setBorder(BorderFactory.createEtchedBorder()); - jp.add(jl); - jp.add(okjb); - jp.add(cajb); - //add JPanel to the Container - this.getContentPane().add(jp); - /** - *for making JDialog at the center, - *@Center.java - */ - center.fCenter(); - //add action listener to Font JComboBox to get the selected item for setting the preview - fjcb.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - jl.setFont(new Font(String.valueOf(fjcb.getSelectedItem()),tjcb.getSelectedIndex(),14)); - } - }); - //add action listener to Type JComboBox to get the selected index for setting the preview - tjcb.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - jl.setFont(new Font(String.valueOf(fjcb.getSelectedItem()),tjcb.getSelectedIndex(),14)); - } - }); - } - - - /* - *@return font value: (Font,Type,Size) - */ - public Font font(){ - Font font = new Font(String.valueOf(fjcb.getSelectedItem()), tjcb.getSelectedIndex(), - Integer.parseInt(String.valueOf(sjcb.getSelectedItem()))); - return font; - } - - -} diff --git a/java/spl/notepad/Variant00007java/Notepad.java b/java/spl/notepad/Variant00007java/Notepad.java deleted file mode 100644 index 38e64fb..0000000 --- a/java/spl/notepad/Variant00007java/Notepad.java +++ /dev/null @@ -1,373 +0,0 @@ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import javax.swing.event.*; import javax.swing.undo.*; - -public - -class Notepad extends JFrame { - - private static final long serialVersionUID = 1; - - - //for using the methods in these classes - public Actions actions = new Actions(this); - - - public Center center = new Center(this); - - - - //declaration of the private variables used in the program - //create the text area - private JTextArea textArea; - - - //create the Menu Bar that contains the JMenu "filE, ediT, vieW, formaT, helP" - private JMenuBar Menubar; - - - //Create the menu that contains the items - private JMenu filE, ediT, vieW, formaT, helP; - - - //Create the menu items - private JMenuItem neW, opeN, savE, saveAS, prinT, exiT, fonT, abouT, - cuT, copY, pastE, selectALL; - - - private JCheckBoxMenuItem lineWraP; - - - //Create the Tool Bar that contains the JButton - private JToolBar toolBar; - - - //Create the buttons - private JButton newButton, openButton, saveButton, saveAsButton, printButton, - fontButton, aboutButton; - - - - //for using lineWrap & textArea @Actions.java - public JCheckBoxMenuItem getLineWrap(){ - return lineWraP; - } - - - public JTextArea getTextArea(){ - return textArea; - } - - - - public Notepad (){ - //set the title for Notepad and set the size for it. - setTitle("Untitled - JAVA??? Notepad"); - setSize(800,600); - - //get the graphical user interface components display area - Container cp = getContentPane(); - /** - *adding the text area, - *adding the tool bar & - *adding the scroll pane to the container - */ - cp.add(textArea = new JTextArea()); - cp.add("North", toolBar = new JToolBar("Tool Bar")); - cp.add(new JScrollPane(textArea)); - - //for setting the menu bar - setJMenuBar(Menubar= new JMenuBar()); - //adding file, edit, view, format, help to the menu bar - Menubar.add(filE = new JMenu("File")); - Menubar.add(ediT = new JMenu("Edit")); - Menubar.add(vieW = new JMenu("View")); - Menubar.add(formaT = new JMenu("Format")); - Menubar.add(helP = new JMenu("Help")); - - /** - *adding neW, opeN, savE, saveAS, prinT & exiT to the filE Menu, - *adding a small image icon to the menu item & - *adding separator between the menu item - */ - filE.add(neW = new JMenuItem("New", new ImageIcon(this.getClass().getResource("images/new.gif")))); - filE.add(opeN = new JMenuItem("Open", new ImageIcon(this.getClass().getResource("images/open.gif")))); - filE.add(savE = new JMenuItem("Save", new ImageIcon(this.getClass().getResource("images/save.gif")))); - filE.add(saveAS = new JMenuItem("Save As", new ImageIcon(this.getClass().getResource("images/saveAs.gif")))); - filE.add(prinT = new JMenuItem("Print", new ImageIcon(this.getClass().getResource("images/print.gif")))); - filE.add(exiT = new JMenuItem("Exit")); //, new ImageIcon(this.getClass().getResource("images/exit.gif")))); -- exit.gif missing - filE.insertSeparator(4); - filE.insertSeparator(6); - - /** - *adding undO, redO, cuT, copY, pastE, finD, findNexT & selectALL to the ediT Menu, - *adding a small image icon to the menu item & - *adding separator between the menu item - */ - ediT.add(selectALL= new JMenuItem("Select All")); - //ediT.insertSeparator(2); - //ediT.insertSeparator(6); - - /** - *adding lineWraP & fonT to the formaT Menu, - *adding abouT to the helP Menu & - *adding a small image icon to the menu item - */ - formaT.add(lineWraP = new JCheckBoxMenuItem("Line Wrap")); - formaT.add(fonT = new JMenuItem("Font", new ImageIcon(this.getClass().getResource("images/font.gif")))); - helP.add(abouT = new JMenuItem("About Notepad", new ImageIcon(this.getClass().getResource("images/about.gif")))); - - /** - *allowing the file menu to be selected by pressing ALT + F - *allowing the edit menu to be selected by pressing ALT + E - *allowing the view menu to be selected by pressing ALT + V - *allowing the format menu to be selected by pressing ALT + O - *allowing the help menu to be selected by pressing ALT + H - */ - filE.setMnemonic('f'); - ediT.setMnemonic('e'); - vieW.setMnemonic('v'); - formaT.setMnemonic('o'); - helP.setMnemonic('h'); - - /** - *allowing the neW menu item to be selected by pressing ALT + N - *allowing the opeN menu item to be selected by pressing ALT + O - *allowing the savE menu item to be selected by pressing ALT + S - *allowing the prinT menu item to be selected by pressing ALT + P - *allowing the exiT menu item to be selected by pressing ALT + F4 - *allowing the cuT menu item to be selected by pressing ALT + X - *allowing the copY menu item to be selected by pressing ALT + C - *allowing the pastE menu item to be selected by pressing ALT + V - *allowing the selectAll menu item to be selected by pressing ALT + A - */ - neW.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK)); - opeN.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK)); - savE.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK)); - prinT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.CTRL_MASK)); - exiT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, ActionEvent.CTRL_MASK)); - selectALL.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.CTRL_MASK)); - - /** - *adding newButton, openButton, saveButton, saveAsButton, printButton, undoButton, - *redoButton, cutButton, copyButton, pasteButton, fontButton & aboutButton to the tool bar, - *adding a small image icon to the menu item & - *adding separator between the button - */ - toolBar.add(newButton = new JButton(new ImageIcon(this.getClass().getResource("images/new.gif")))); - toolBar.add(openButton = new JButton(new ImageIcon(this.getClass().getResource("images/open.gif")))); - toolBar.add(saveButton = new JButton(new ImageIcon(this.getClass().getResource("images/save.gif")))); - toolBar.add(saveAsButton= new JButton(new ImageIcon(this.getClass().getResource("images/saveAs.gif")))); - toolBar.add(printButton = new JButton(new ImageIcon(this.getClass().getResource("images/print.gif")))); - toolBar.addSeparator(); - toolBar.add(fontButton = new JButton(new ImageIcon(this.getClass().getResource("images/font.gif")))); - toolBar.add(aboutButton = new JButton(new ImageIcon(this.getClass().getResource("images/about.gif")))); - - //adding a tool tip text to the button for descriping the image icon. - newButton.setToolTipText("New"); - openButton.setToolTipText("Open"); - saveButton.setToolTipText("Save"); - saveAsButton.setToolTipText("Save As"); - printButton.setToolTipText("Print"); - fontButton.setToolTipText("Font"); - aboutButton.setToolTipText("About Notepad"); - - /** - *setting the default close operation to false & - *using own action (exiT action @Actions.java) - */ - setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); - addWindowListener(new WindowAdapter(){ - public void windowClosing(WindowEvent e){ - actions.exiT(); - } - }); - /** - *adding action listener for menu item: neW, opeN, savE, saveAS, prinT, exiT, - *redO, undO, copY, cuT, pastE, finD, findNexT, selectALL, lineWraP, fonT & abouT - *the actions was written @Actions.java - */ - neW.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.neW(); - } - }); - opeN.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.opeN(); - } - }); - savE.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.savE(); - } - }); - saveAS.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.saveAs(); - } - }); - prinT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.prinT(); - } - }); - exiT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.exiT(); - } - }); - selectALL.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.selectALL(); - } - }); - lineWraP.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.lineWraP(); - } - }); - fonT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.fonT(); - } - }); - abouT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.abouT(); - } - }); - - /** - *adding action listener for the button in the tool bar: newButton, openButton, - *saveButton, saveAsButton, printButton, redoButton, undoButton, copyButton, - *cutButton, pasteButton, findButton, selectALL, lineWraP, fontButton & aboutButton - *the actions was written @Actions.java - */ - newButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.neW(); - } - }); - openButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.opeN(); - } - }); - saveButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.savE(); - } - }); - saveAsButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.saveAs(); - } - }); - printButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.prinT(); - } - }); - fontButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.fonT(); - } - }); - aboutButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.abouT(); - } - }); - - /** - *Setting the Line Wrap & Wrap Style Word features are true - */ - textArea.setLineWrap(true); - textArea.setWrapStyleWord(true); - /** - *for making the program at the center, - *@see Center.java - */ - center.nCenter(); - show(); - - ediT.add(finD = new JMenuItem("Find", new ImageIcon(this.getClass().getResource("images/find.gif")))); - ediT.add(findNexT = new JMenuItem("Find Next")); - //ediT.insertSeparator(8); - - /** - *allowing the finD menu item to be selected by pressing ALT + F - *allowing the findNexT menu item to be selected by pressing ALT + F3 - */ - finD.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F, ActionEvent.CTRL_MASK)); - findNexT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F3, ActionEvent.CTRL_MASK)); - toolBar.add(findButton = new JButton(new ImageIcon(this.getClass().getResource("images/find.gif")))); - findButton.setToolTipText("Find"); - - finD.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.finD(); - } - }); - findNexT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.findNexT(); - } - }); - - findButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.finD(); - } - }); - - ediT.add(undoAction); - ediT.add(redoAction); - - toolBar.addSeparator(); - toolBar.add(undoAction); - toolBar.add(redoAction); - toolBar.addSeparator(); - - textArea.getDocument().addUndoableEditListener(new UndoableEditListener(){ - public void undoableEditHappened(UndoableEditEvent e){ - //Remember the edit and update the menus - undo.addEdit(e.getEdit()); - undoAction.update(); - redoAction.update(); - } - }); - } - - - //Main Method - public static void main(String[] args){ - new Notepad(); - - } - - - - private JButton findButton; - - - private JMenuItem finD, findNexT; - - - //for using undo & redo - UndoManager undo = new UndoManager(); - - - UndoAction undoAction = new UndoAction(this); - - - RedoAction redoAction = new RedoAction(this); - - - - private JButton undoButton, redoButton; - - -} diff --git a/java/spl/notepad/Variant00007java/Print.java b/java/spl/notepad/Variant00007java/Print.java deleted file mode 100644 index 132daed..0000000 --- a/java/spl/notepad/Variant00007java/Print.java +++ /dev/null @@ -1,64 +0,0 @@ -import java.awt.*; -import java.awt.print.*; -import javax.swing.*; - -/** - *A class for creating a printer option. - */ -public class Print implements Printable { - - private Component componentToBePrinted; - - - - public static void printComponent(Component c){ - new Print(c).print(); - } - - - public Print(Component componentToBePrinted){ - this.componentToBePrinted = componentToBePrinted; - } - - - public void print(){ - PrinterJob printJob = PrinterJob.getPrinterJob(); - printJob.setPrintable(this); - if(printJob.printDialog()) - try{ - printJob.print(); - } - catch(PrinterException pe){ - System.out.println("Error printing: " + pe); - } - } - - - public int print(Graphics g, PageFormat pageFormat, int pageIndex){ - if(pageIndex > 0){ - return(NO_SUCH_PAGE); - } - else{ - Graphics2D g2d = (Graphics2D)g; - g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); - disableDoubleBuffering(componentToBePrinted); - componentToBePrinted.paint(g2d); - enableDoubleBuffering(componentToBePrinted); - return(PAGE_EXISTS); - } - } - - - public static void disableDoubleBuffering(Component c){ - RepaintManager currentManager = RepaintManager.currentManager(c); - currentManager.setDoubleBufferingEnabled(false); - } - - - public static void enableDoubleBuffering(Component c){ - RepaintManager currentManager = RepaintManager.currentManager(c); - currentManager.setDoubleBufferingEnabled(true); - } - - -} diff --git a/java/spl/notepad/Variant00007java/RedoAction.java b/java/spl/notepad/Variant00007java/RedoAction.java deleted file mode 100644 index ccd8eaf..0000000 --- a/java/spl/notepad/Variant00007java/RedoAction.java +++ /dev/null @@ -1,50 +0,0 @@ -import java.awt.event.*; -import javax.swing.*; -import javax.swing.undo.*; - - - -class RedoAction extends AbstractAction { - - private static final long serialVersionUID = 1; - - - Notepad notepad; - - - - public RedoAction(Notepad notepad){ - super("Redo"); - putValue( Action.SMALL_ICON, - new ImageIcon(this.getClass().getResource("images/redo.gif"))); - setEnabled(false); - this.notepad = notepad; - } - - - public void actionPerformed(ActionEvent e){ - try{ - notepad.undo.redo(); - } - catch (CannotRedoException ex){ - System.out.println("Unable to redo: " + ex); - ex.printStackTrace(); - } - update(); - notepad.undoAction.update(); - } - - - protected void update(){ - if(notepad.undo.canRedo()){ - setEnabled(true); - putValue("Redo", notepad.undo.getRedoPresentationName()); - } - else{ - setEnabled(false); - putValue(Action.NAME, "Redo"); - } - } - - -} diff --git a/java/spl/notepad/Variant00007java/UndoAction.java b/java/spl/notepad/Variant00007java/UndoAction.java deleted file mode 100644 index 3298a36..0000000 --- a/java/spl/notepad/Variant00007java/UndoAction.java +++ /dev/null @@ -1,50 +0,0 @@ -import java.awt.event.*; -import javax.swing.*; -import javax.swing.undo.*; - - - -class UndoAction extends AbstractAction { - - private static final long serialVersionUID = 1; - - - Notepad notepad; - - - - public UndoAction(Notepad notepad){ - super( "Undo" ); - putValue( Action.SMALL_ICON, - new ImageIcon( this.getClass().getResource( "images/undo.gif" ) ) ); - setEnabled( false ); - this.notepad = notepad; - } - - - public void actionPerformed( ActionEvent e ) { - try { - notepad.undo.undo(); - } - catch ( CannotUndoException ex ) { - System.out.println( "Unable to undo: " + ex ); - ex.printStackTrace(); - } - update(); - notepad.redoAction.update(); - } - - - protected void update() { - if( notepad.undo.canUndo() ) { - setEnabled( true ); - putValue( "Undo", notepad.undo.getUndoPresentationName() ); - } - else { - setEnabled( false ); - putValue( Action.NAME, "Undo" ); - } - } - - -} diff --git a/java/spl/notepad/Variant00008java/About.java b/java/spl/notepad/Variant00008java/About.java deleted file mode 100644 index fb751fd..0000000 --- a/java/spl/notepad/Variant00008java/About.java +++ /dev/null @@ -1,25 +0,0 @@ -import javax.swing.*; - -/** - *A CLASS FOR CREATING ABOUT PANEL - */ -public class About extends JPanel { - - private static final long serialVersionUID = 1; - - - public About(){ - //Create a Label & an image icon in it - JLabel label1 = new JLabel(new ImageIcon(this.getClass().getResource("images/java.gif"))); - //adding label1 to the JPanel - this.add(label1); - //Create a Label & put a HTML script - JLabel label2 = new JLabel("
  • JAVA??? Notepad
  • Ver# 2.0

  • " - +"
  • Coded by: Salah Al-Thubaiti

  • KFUPM, CS

  • " - +"

    CopyRight??? 2001-2002

  • "); - //adding label2 to the JPanel - this.add(label2); - } - - -} diff --git a/java/spl/notepad/Variant00008java/Actions.java b/java/spl/notepad/Variant00008java/Actions.java deleted file mode 100644 index b97e1f5..0000000 --- a/java/spl/notepad/Variant00008java/Actions.java +++ /dev/null @@ -1,515 +0,0 @@ -import java.io.*; -import java.util.*; -import java.awt.event.*; -import javax.swing.*; public class Actions { - - //declaration of the private variables used in the program - private int returnVal; - - //for JFileChooser - private int option; - - //for using it into JOptionPane - private String fileContent = null; - - //to get the text from the text area - private String fileName = null; - - //for using the name of the file - private JFileChooser jfc = new JFileChooser("."); - - //for using a open & save dialog - private ExampleFileFilter filter = new ExampleFileFilter(); - - //for filtering the file - Notepad n; - - //for using the object in the Notepad.java - public Fonts font = new Fonts(); - - - - public Actions(Notepad n){ - this.n = n; - } - - - /** - *If we want to write a new text, first we want to know if the text area is empty or not, - *second we want to know if the text was saved or not. - *If the text area isn't empty & the text wasn't saved before this time, then the program display -> - *for the user an option for saving the text in a new file or in the same file - */ - public void neW(){ - /** - *if the text area isn't empty & if the text area hasn't - *a text not saved before (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - /** - *here, we have two things, first if the text wasn't be opened or saved before - *second if the text was be opened or saved - */ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - //if the user click on YES button, - //then the program will save the text & make a new text area - if(option == 0){ - //to save the text into a new file - saveAs(); - //to create new getTextArea() after saving the old getTextArea() - n.getTextArea().setText(""); - } - //if the user click on NO button - if(option == 1){ - //to create new getTextArea() without saving the old getTextArea() - n.getTextArea().setText(""); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will save the text into the old file & - *make a new text area,,, - */ - if(option == 0){ - save(); - //to create new getTextArea() after saving the old getTextArea() - n.getTextArea().setText(""); - } - //if the user click on NO button - if(option == 1){ - //to create new getTextArea() without saving the old getTextArea() - n.getTextArea().setText(""); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to write a new text,,, this option will be actived - */ - else{ - n.getTextArea().setText(""); - } - n.setTitle("Untitled - JAVA??? Notepad"); - } - - - /** - *If we want to open a new text, first we want to know if the text area - * is empty or not, second we want to kwnow if the text was saved or not. - *If the text area isn't empty & the text wasn't saved befor this time, - *then the program display for the user an option for saving the text - *in a new file or in the same file - */ - public void opeN(){ - /** - *if the text area isn't empty & if the text area hasn't a text which - *not saved befor (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - /** - *here, we have 2 thing, first if the text wasn't be opened or saved befor - *second if the text was be opened or saved - */ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - //if the user click on YES button, - //then the program will be saved the text & opened a new documents - if(option == 0){ - //for saving the text in a new file - saveAs(); - //for opening the new documents - open(); - } - /** - *if the user click on NO button, - *the program will be opened the new documents - */ - if(option == 1){ - //for opening the new documents - open(); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will save the text into the same file & - *open the new documents - */ - if(option == 0){ - //for saving the text into the same file - save(); - //for opening the new documents - open(); - } - /** - *if the user click on NO button, - *the program will be opened the new documents - */ - if(option == 1){ - //for opening the new documents - open(); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to open a new document,,, this option will be actived - */ - else{ - //for opening the new documents - open(); - } - } - - - /** - *THIS IS FOR SAVE ACTION, SaveAs ACTION has saveAs() method - *If we want to save a new text, then we want to know - *if the text was saved befor or not. - *If the text wasn't be saved befor, then we will use saveAs() - *If the text was be save befor, then we will use save() - */ - public void savE(){ - /** - *if String fileName is null, then using saveAs(). - *Because there was no file was be saved - */ - if(fileName == null){ - saveAs(); - } - /** - *if String fileName has a String (file name), then using save(). - *Because we want to save the new text in the same file. - *if the user want to save the all text (old & new text) in a new file, -> - *he can presses SaveAs button (@saveAs()) - */ - else{ - save(); - } - } - - - /** - *THIS FROM SUN??? WEBSITE (@Print.java) - *if we want to print the text, we can do this by print method - */ - public void prinT(){ - //import printer class - Print.printComponent(n.getTextArea()); - } - - - /** - *If we want to exit from the program, - *first we want to know if the text area is empty or not, - *second we want to kwnow if the text was saved or not. - *If the text area isn't empty & the text wasn't saved befor this time, - *then the program display -> - *for the user an option for saving the text in a new file or in the same file - */ - public void exiT(){ - /** - *if the text area isn't empty & if the text area hasn't a text which - *not saved befor (fileContent != null) - */ - if(!n.getTextArea().getText().equals("") && !n.getTextArea().getText().equals(fileContent)){ - //if there was no file opened or saved - if(fileName == null){ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will be saved the text & close the program - */ - if(option == 0){ - //for saving the text into new file - saveAs(); - //for closing the program - System.exit(0); - } - /** - *if the user click on NO button, - *then the program will be closed without save the text - */ - if(option == 1){ - //for closing the program - System.exit(0); - } - } - //if there was a text which was be opend or saved - else{ - /** - *this method has 3 options (1 = YES, 2 = NO, 3 = Cancel) - *this is an option pop up to the user, for saving the old text or not - */ - option = JOptionPane.showConfirmDialog(null,"Do you want to save the changes ??"); - /** - *if the user click on YES button, - *then the program will be saved the text & close the program - */ - if(option == 0){ - //for saving the text into the same file - save(); - //for closing the program - System.exit(0); - } - /** - *if the user click on NO button, - *then the program will be closed without save the text - */ - if(option == 1){ - //for closing the program - System.exit(0); - } - } - } - /** - *if the text was be opened or saved before but wasn't be changed, - *and we want to close the program. This option will be actived - */ - else{ - //for closing the program - System.exit(0); - } - } - - - //to select all the text - public void selectALL(){ - n.getTextArea().selectAll(); - } - - - //for wraping the line & wraping the style word - public void lineWraP(){ - if(n.getLineWrap().isSelected()){ - /** - *make the line wrap & wrap style word is true - *when the line wrap is selected - */ - n.getTextArea().setLineWrap(true); - n.getTextArea().setWrapStyleWord(true); - } - else{ - /** - *make the line wrap & wrap style word is false - *when the line wrap isn't selected - */ - n.getTextArea().setLineWrap(false); - n.getTextArea().setWrapStyleWord(false); - } - } - - - /** - *@see FONTS.JAVA - *this is a font class which is for changing the font, style & size - */ - public void fonT(){ - font.setVisible(true); //setting the visible is true - font.pack(); //pack the panel - //making an action for ok button, so we can change the font - font.getOkjb().addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - n.getTextArea().setFont(font.font()); - //after we chose the font, then the JDialog will be closed - font.setVisible(false); - } - }); - //making an action for cancel button, so we can return to the old font. - font.getCajb().addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - //after we cancel the, then the JDialog will be closed - font.setVisible(false); - } - }); - } - - - /** - *@see ABOUT.JAVA - *it's a Message Dialog to show the information about this program - */ - public void abouT(){ - JOptionPane.showMessageDialog(null, new About(),"About Notepad",JOptionPane.PLAIN_MESSAGE); - } - - - /** - *THIS IS THE WAY FOR OPENING THE TEXT FILE - */ - public void open(){ - //filter the kind of files, we want only TXT file - filter.addExtension("txt"); - //to set a description for the file (TXT) - filter.setDescription("TXT Documents"); - //setting the FileFilter to JFileChooser - jfc.setFileFilter(filter); - returnVal = jfc.showOpenDialog(n); //to show JFileChooser - if(returnVal == JFileChooser.APPROVE_OPTION){ - //to erase any text in the text area before adding new text - n.getTextArea().setText(null); - try{ - //to get the name of the selected file - fileName = jfc.getSelectedFile().getPath(); - //to read the selected file - Reader in = new FileReader(jfc.getSelectedFile()); - //100000 is the max. char can be written in the text area - char[] buff = new char[100000]; - int nch; - while((nch = in.read(buff, 0, buff.length)) != -1) - n.getTextArea().append(new String(buff, 0, nch)); - //to get more text from the file if the array wasn't full - fileContent = n.getTextArea().getText(); - } - catch(FileNotFoundException x){} - catch(IOException ioe){ - System.err.println("I/O Error on Open"); - } - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - /** - *THIS IS THE WAY FOR SAVING THE TEXT IN THE SAME FILE - */ - public void save(){ - //initializing 'fout' to write all text in the selected file - try{ - PrintWriter fout = new PrintWriter(new FileWriter(jfc.getSelectedFile())); - //for getting the text from the text area - fileContent = n.getTextArea().getText(); - //using StringTokenizer for the 'fileContent' String - StringTokenizer st=new StringTokenizer(fileContent,System.getProperty("line.separator")); - while(st.hasMoreTokens()){ - //write the string (text) in the selected file - fout.println(st.nextToken()); - } - //closing fout - fout.close(); - } - catch(IOException ioe){ - System.err.println("I/O Error on Save"); - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - /** - *THIS IS THE WAY FOR SAVING THE TEXT IN A NEW FILE - */ - public void saveAs(){ - //filter the kind of files, we want only TXT file - filter.addExtension("txt"); - //to set a description for the file (TXT) - filter.setDescription("TXT Documents"); - //setting the FileFilter to JFileChooser - jfc.setFileFilter(filter); - returnVal = jfc.showSaveDialog(n); - if(returnVal == JFileChooser.APPROVE_OPTION){ - //initializing the PrintWriter, to save the text in a new file - PrintWriter fout = null; - try{ - fout = new PrintWriter(new FileWriter(jfc.getSelectedFile() + ".txt")); - //getting the text from the text area - fileContent = n.getTextArea().getText(); - //getting the name of the selected file - fileName = jfc.getSelectedFile().getPath(); - //using StringTokenizer for the 'fileContent' String - StringTokenizer st=new StringTokenizer(fileContent,System.getProperty("line.separator")); - while(st.hasMoreTokens()){ - //write the string (text) in the selected file - fout.println(st.nextToken()); - } - //closing 'fout' - fout.close(); - } - catch(IOException ioe){ - System.err.println ("I/O Error on Save"); - } - } - n.setTitle(jfc.getSelectedFile().getName() + " - JAVA??? Notepad"); - } - - - //to cut the selected text - public void cuT(){ - n.getTextArea().cut(); - } - - - //to copy the selected text - public void copY(){ - n.getTextArea().copy(); - } - - - //to paste the selected text - public void pastE(){ - n.getTextArea().paste(); - } - - - private String findword; - - //for searching & finding the word - //this is a method for searching the input text from the text area - - public void finD(){ - try{ - //this is an input dialog which return a string (findword) - findword = JOptionPane.showInputDialog("Type the word to find"); - //if the JTextField in the input dialog is empty (null), then return a message dialog - while(n.getTextArea().getText().indexOf(findword) == -1){ - /** - *this is a message dialog which is warning the user, - *because he didn't or forgot to enter the word - */ - JOptionPane.showMessageDialog(null,"Word not found!","No match",JOptionPane.WARNING_MESSAGE); - findword = JOptionPane.showInputDialog("Type the word to find"); - } - //for selecting the word which the user search for it - n.getTextArea().select(n.getTextArea().getText().indexOf(findword), - n.getTextArea().getText().indexOf(findword) + findword.length()); - } - catch(Exception ex){ - JOptionPane.showMessageDialog(null,"Search canceled","Abourted",JOptionPane.WARNING_MESSAGE); - } - } - - - public void findNexT(){ - n.getTextArea().select(n.getTextArea().getText().indexOf(findword,(int)n.getTextArea().getText().indexOf(findword)+1), - n.getTextArea().getText().indexOf(findword,(int)n.getTextArea().getText().indexOf(findword)+1)); - } - - -} diff --git a/java/spl/notepad/Variant00008java/Center.java b/java/spl/notepad/Variant00008java/Center.java deleted file mode 100644 index 1715525..0000000 --- a/java/spl/notepad/Variant00008java/Center.java +++ /dev/null @@ -1,37 +0,0 @@ -import java.awt.*; -/** - *A PUBLIC CLASS FOR CENTER.JAVA - */ -public class Center { - - Notepad n; - - //for using the object in the Notepad.java - Fonts f; - - //for using the object in the Fonts.java - public Center(Notepad n){ - this.n = n; - } - - - public Center(Fonts f){ - this.f = f; - } - - - public void nCenter(){ - //Centering the window - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - n.setLocation((screenSize.width-n.getWidth())/2,(screenSize.height-n.getHeight())/2); - } - - - public void fCenter(){ - //Centering the window - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - f.setLocation((screenSize.width-f.getWidth())/2,(screenSize.height-f.getHeight())/2); - } - - -} diff --git a/java/spl/notepad/Variant00008java/ExampleFileFilter.java b/java/spl/notepad/Variant00008java/ExampleFileFilter.java deleted file mode 100644 index 47b0dd6..0000000 --- a/java/spl/notepad/Variant00008java/ExampleFileFilter.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (c) 2002 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * -Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * -Redistribution in binary form must reproduct the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING - * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT - * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT - * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS - * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST - * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, - * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY - * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN - * IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that Software is not designed, licensed or intended for - * use in the design, construction, operation or maintenance of any nuclear - * facility. - */ - -/* - * @(#)ExampleFileFilter.java 1.13 02/06/13 - */ - - - -//import the packages for using the classes in them into the program -import java.io.File; -import java.util.Hashtable; -import java.util.Enumeration; -import javax.swing.filechooser.*; - -/** - * A convenience implementation of FileFilter that filters out - * all files except for those type extensions that it knows about. - * - * Extensions are of the type ".foo", which is typically found on - * Windows and Unix boxes, but not on Macinthosh. Case is ignored. - * - * Example - create a new filter that filerts out all files - * but gif and jpg image files: - * - * JFileChooser chooser = new JFileChooser(); - * ExampleFileFilter filter = new ExampleFileFilter( - * new String{"gif", "jpg"}, "JPEG & GIF Images") - * chooser.addChoosableFileFilter(filter); - * chooser.showOpenDialog(this); - * - * @version 1.13 06/13/02 - * @author Jeff Dinkins - */ -public class ExampleFileFilter extends FileFilter { - - -// private static String TYPE_UNKNOWN = "Type Unknown"; -// private static String HIDDEN_FILE = "Hidden File"; - - private Hashtable filters = null; - - - private String description = null; - - - private String fullDescription = null; - - - private boolean useExtensionsInDescription = true; - - - - /** - * Creates a file filter. If no filters are added, then all - * files are accepted. - * - * @see #addExtension - */ - public ExampleFileFilter(){ - this.filters = new Hashtable(); - } - - - - /** - * Creates a file filter that accepts files with the given extension. - * Example: new ExampleFileFilter("jpg"); - * - * @see #addExtension - */ - public ExampleFileFilter(String extension){ - this(extension,null); - } - - - - /** - * Creates a file filter that accepts the given file type. - * Example: new ExampleFileFilter("jpg", "JPEG Image Images"); - * - * Note that the "." before the extension is not needed. If - * provided, it will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String extension, String description){ - this(); - if(extension!=null) addExtension(extension); - if(description!=null) setDescription(description); - } - - - - /** - * Creates a file filter from the given string array. - * Example: new ExampleFileFilter(String {"gif", "jpg"}); - * - * Note that the "." before the extension is not needed adn - * will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String[] filters){ - this(filters, null); - } - - - - /** - * Creates a file filter from the given string array and description. - * Example: new ExampleFileFilter(String {"gif", "jpg"}, "Gif and JPG Images"); - * - * Note that the "." before the extension is not needed and will be ignored. - * - * @see #addExtension - */ - public ExampleFileFilter(String[] filters, String description){ - this(); - for (int i = 0; i < filters.length; i++){ - // add filters one by one - addExtension(filters[i]); - } - if(description!=null) setDescription(description); - } - - - - /** - * Return true if this file should be shown in the directory pane, - * false if it shouldn't. - * - * Files that begin with "." are ignored. - * - * @see #getExtension - * @see FileFilter#accepts - */ - public boolean accept(File f){ - if(f != null){ - if(f.isDirectory()){ - return true; - } - String extension = getExtension(f); - if(extension != null && filters.get(getExtension(f)) != null){ - return true; - }; - } - return false; - } - - - - /** - * Return the extension portion of the file's name . - * - * @see #getExtension - * @see FileFilter#accept - */ - public String getExtension(File f){ - if(f != null){ - String filename = f.getName(); - int i = filename.lastIndexOf('.'); - if(i>0 && i(5); - } - filters.put(extension.toLowerCase(), this); - fullDescription = null; - } - - - - /** - * Returns the human readable description of this filter. For - * example: "JPEG and GIF Image Files (*.jpg, *.gif)" - * - * @see setDescription - * @see setExtensionListInDescription - * @see isExtensionListInDescription - * @see FileFilter#getDescription - */ - @SuppressWarnings("rawtypes") - public String getDescription(){ - if(fullDescription == null) { - if(description == null || isExtensionListInDescription()){ - fullDescription = description==null ? "(" : description + " ("; - // build the description from the extension list - Enumeration extensions = filters.keys(); - if(extensions != null){ - fullDescription += "." + (String) extensions.nextElement(); - while (extensions.hasMoreElements()) { - fullDescription += ", ." + (String) extensions.nextElement(); - } - } - fullDescription += ")"; - } else { - fullDescription = description; - } - } - return fullDescription; - } - - - - /** - * Sets the human readable description of this filter. For - * example: filter.setDescription("Gif and JPG Images"); - * - * @see setDescription - * @see setExtensionListInDescription - * @see isExtensionListInDescription - */ - public void setDescription(String description){ - this.description = description; - fullDescription = null; - } - - - - /** - * Determines whether the extension list (.jpg, .gif, etc) should - * show up in the human readable description. - * - * Only relevent if a description was provided in the constructor - * or using setDescription(); - * - * @see getDescription - * @see setDescription - * @see isExtensionListInDescription - */ - public void setExtensionListInDescription(boolean b){ - useExtensionsInDescription = b; - fullDescription = null; - } - - - - /** - * Returns whether the extension list (.jpg, .gif, etc) should - * show up in the human readable description. - * - * Only relevent if a description was provided in the constructor - * or using setDescription(); - * - * @see getDescription - * @see setDescription - * @see setExtensionListInDescription - */ - public boolean isExtensionListInDescription(){ - return useExtensionsInDescription; - } - - -} diff --git a/java/spl/notepad/Variant00008java/Fonts.java b/java/spl/notepad/Variant00008java/Fonts.java deleted file mode 100644 index e63be0b..0000000 --- a/java/spl/notepad/Variant00008java/Fonts.java +++ /dev/null @@ -1,136 +0,0 @@ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - -/** - *A class for creating JFontDialog - */ -public class Fonts extends JDialog { - - private static final long serialVersionUID = 1L; - - - /** - *@see Center.java - *this class to make the JDialog in the center - */ - public Center center = new Center(this); - - - - //declaration of the private variables used in the program - private JPanel jp = new JPanel(); - - - private JLabel fjl = new JLabel("Fonts: "); - - - private JComboBox fjcb = new JComboBox(); - - - /** - *-> GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames() <- - * WE USING THIS METHOD TO GET ALL FONT IN THE SYSTEM (OS) - */ - private String fonts[]=GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); - - - private JLabel sjl = new JLabel("Sizes: "); - - - private JComboBox sjcb = new JComboBox(); - - - private String sizes[] = {"8","10","12","14","16","18","20","24","28","32","48","72"}; - - - private JLabel tjl = new JLabel("Types: "); - - - private JComboBox tjcb = new JComboBox(); - - - private String types[] = {"Regular", "Bold", "Italic", "Bold Italic"}; - - - private JLabel jjl = new JLabel("Preview:"); - - - private JLabel jl = new JLabel("AaBaCcDdeEfFgGhHjJ"); - - - private JButton okjb = new JButton("OK"); - - - private JButton cajb = new JButton("Cancel"); - - - //for using ok & cancel button @Actions.java - public JButton getOkjb(){ - return okjb; - } - - - public JButton getCajb(){ - return cajb; - } - - - //Constructor of Fonts - public Fonts(){ - //for setting the title - setTitle("Font Dialog"); - setResizable(false); - /** - *setting the layout (GridLayout: 5 rows & 2 columns) - *add font JLabel, add font JComboBox - *add type JLabel, add type JComboBox - *add size JLabel, add size JComboBox - *add preview JLabel,add test JLabel - *add ok button, add cancel button - */ - jp.setLayout(new GridLayout(5,2,1,1)); - jp.add(fjl); - jp.add(fjcb = new JComboBox(fonts)); - jp.add(sjl); - jp.add(sjcb = new JComboBox(sizes)); - jp.add(tjl); - jp.add(tjcb = new JComboBox(types)); - jp.add(jjl); - jl.setBorder(BorderFactory.createEtchedBorder()); - jp.add(jl); - jp.add(okjb); - jp.add(cajb); - //add JPanel to the Container - this.getContentPane().add(jp); - /** - *for making JDialog at the center, - *@Center.java - */ - center.fCenter(); - //add action listener to Font JComboBox to get the selected item for setting the preview - fjcb.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - jl.setFont(new Font(String.valueOf(fjcb.getSelectedItem()),tjcb.getSelectedIndex(),14)); - } - }); - //add action listener to Type JComboBox to get the selected index for setting the preview - tjcb.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - jl.setFont(new Font(String.valueOf(fjcb.getSelectedItem()),tjcb.getSelectedIndex(),14)); - } - }); - } - - - /* - *@return font value: (Font,Type,Size) - */ - public Font font(){ - Font font = new Font(String.valueOf(fjcb.getSelectedItem()), tjcb.getSelectedIndex(), - Integer.parseInt(String.valueOf(sjcb.getSelectedItem()))); - return font; - } - - -} diff --git a/java/spl/notepad/Variant00008java/Notepad.java b/java/spl/notepad/Variant00008java/Notepad.java deleted file mode 100644 index cb87828..0000000 --- a/java/spl/notepad/Variant00008java/Notepad.java +++ /dev/null @@ -1,425 +0,0 @@ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import javax.swing.event.*; import javax.swing.undo.*; - -public - -class Notepad extends JFrame { - - private static final long serialVersionUID = 1; - - - //for using the methods in these classes - public Actions actions = new Actions(this); - - - public Center center = new Center(this); - - - - //declaration of the private variables used in the program - //create the text area - private JTextArea textArea; - - - //create the Menu Bar that contains the JMenu "filE, ediT, vieW, formaT, helP" - private JMenuBar Menubar; - - - //Create the menu that contains the items - private JMenu filE, ediT, vieW, formaT, helP; - - - //Create the menu items - private JMenuItem neW, opeN, savE, saveAS, prinT, exiT, fonT, abouT, - cuT, copY, pastE, selectALL; - - - private JCheckBoxMenuItem lineWraP; - - - //Create the Tool Bar that contains the JButton - private JToolBar toolBar; - - - //Create the buttons - private JButton newButton, openButton, saveButton, saveAsButton, printButton, - fontButton, aboutButton; - - - - //for using lineWrap & textArea @Actions.java - public JCheckBoxMenuItem getLineWrap(){ - return lineWraP; - } - - - public JTextArea getTextArea(){ - return textArea; - } - - - - public Notepad (){ - //set the title for Notepad and set the size for it. - setTitle("Untitled - JAVA??? Notepad"); - setSize(800,600); - - //get the graphical user interface components display area - Container cp = getContentPane(); - /** - *adding the text area, - *adding the tool bar & - *adding the scroll pane to the container - */ - cp.add(textArea = new JTextArea()); - cp.add("North", toolBar = new JToolBar("Tool Bar")); - cp.add(new JScrollPane(textArea)); - - //for setting the menu bar - setJMenuBar(Menubar= new JMenuBar()); - //adding file, edit, view, format, help to the menu bar - Menubar.add(filE = new JMenu("File")); - Menubar.add(ediT = new JMenu("Edit")); - Menubar.add(vieW = new JMenu("View")); - Menubar.add(formaT = new JMenu("Format")); - Menubar.add(helP = new JMenu("Help")); - - /** - *adding neW, opeN, savE, saveAS, prinT & exiT to the filE Menu, - *adding a small image icon to the menu item & - *adding separator between the menu item - */ - filE.add(neW = new JMenuItem("New", new ImageIcon(this.getClass().getResource("images/new.gif")))); - filE.add(opeN = new JMenuItem("Open", new ImageIcon(this.getClass().getResource("images/open.gif")))); - filE.add(savE = new JMenuItem("Save", new ImageIcon(this.getClass().getResource("images/save.gif")))); - filE.add(saveAS = new JMenuItem("Save As", new ImageIcon(this.getClass().getResource("images/saveAs.gif")))); - filE.add(prinT = new JMenuItem("Print", new ImageIcon(this.getClass().getResource("images/print.gif")))); - filE.add(exiT = new JMenuItem("Exit")); //, new ImageIcon(this.getClass().getResource("images/exit.gif")))); -- exit.gif missing - filE.insertSeparator(4); - filE.insertSeparator(6); - - /** - *adding undO, redO, cuT, copY, pastE, finD, findNexT & selectALL to the ediT Menu, - *adding a small image icon to the menu item & - *adding separator between the menu item - */ - ediT.add(selectALL= new JMenuItem("Select All")); - //ediT.insertSeparator(2); - //ediT.insertSeparator(6); - - /** - *adding lineWraP & fonT to the formaT Menu, - *adding abouT to the helP Menu & - *adding a small image icon to the menu item - */ - formaT.add(lineWraP = new JCheckBoxMenuItem("Line Wrap")); - formaT.add(fonT = new JMenuItem("Font", new ImageIcon(this.getClass().getResource("images/font.gif")))); - helP.add(abouT = new JMenuItem("About Notepad", new ImageIcon(this.getClass().getResource("images/about.gif")))); - - /** - *allowing the file menu to be selected by pressing ALT + F - *allowing the edit menu to be selected by pressing ALT + E - *allowing the view menu to be selected by pressing ALT + V - *allowing the format menu to be selected by pressing ALT + O - *allowing the help menu to be selected by pressing ALT + H - */ - filE.setMnemonic('f'); - ediT.setMnemonic('e'); - vieW.setMnemonic('v'); - formaT.setMnemonic('o'); - helP.setMnemonic('h'); - - /** - *allowing the neW menu item to be selected by pressing ALT + N - *allowing the opeN menu item to be selected by pressing ALT + O - *allowing the savE menu item to be selected by pressing ALT + S - *allowing the prinT menu item to be selected by pressing ALT + P - *allowing the exiT menu item to be selected by pressing ALT + F4 - *allowing the cuT menu item to be selected by pressing ALT + X - *allowing the copY menu item to be selected by pressing ALT + C - *allowing the pastE menu item to be selected by pressing ALT + V - *allowing the selectAll menu item to be selected by pressing ALT + A - */ - neW.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK)); - opeN.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK)); - savE.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK)); - prinT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.CTRL_MASK)); - exiT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, ActionEvent.CTRL_MASK)); - selectALL.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.CTRL_MASK)); - - /** - *adding newButton, openButton, saveButton, saveAsButton, printButton, undoButton, - *redoButton, cutButton, copyButton, pasteButton, fontButton & aboutButton to the tool bar, - *adding a small image icon to the menu item & - *adding separator between the button - */ - toolBar.add(newButton = new JButton(new ImageIcon(this.getClass().getResource("images/new.gif")))); - toolBar.add(openButton = new JButton(new ImageIcon(this.getClass().getResource("images/open.gif")))); - toolBar.add(saveButton = new JButton(new ImageIcon(this.getClass().getResource("images/save.gif")))); - toolBar.add(saveAsButton= new JButton(new ImageIcon(this.getClass().getResource("images/saveAs.gif")))); - toolBar.add(printButton = new JButton(new ImageIcon(this.getClass().getResource("images/print.gif")))); - toolBar.addSeparator(); - toolBar.add(fontButton = new JButton(new ImageIcon(this.getClass().getResource("images/font.gif")))); - toolBar.add(aboutButton = new JButton(new ImageIcon(this.getClass().getResource("images/about.gif")))); - - //adding a tool tip text to the button for descriping the image icon. - newButton.setToolTipText("New"); - openButton.setToolTipText("Open"); - saveButton.setToolTipText("Save"); - saveAsButton.setToolTipText("Save As"); - printButton.setToolTipText("Print"); - fontButton.setToolTipText("Font"); - aboutButton.setToolTipText("About Notepad"); - - /** - *setting the default close operation to false & - *using own action (exiT action @Actions.java) - */ - setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); - addWindowListener(new WindowAdapter(){ - public void windowClosing(WindowEvent e){ - actions.exiT(); - } - }); - /** - *adding action listener for menu item: neW, opeN, savE, saveAS, prinT, exiT, - *redO, undO, copY, cuT, pastE, finD, findNexT, selectALL, lineWraP, fonT & abouT - *the actions was written @Actions.java - */ - neW.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.neW(); - } - }); - opeN.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.opeN(); - } - }); - savE.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.savE(); - } - }); - saveAS.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.saveAs(); - } - }); - prinT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.prinT(); - } - }); - exiT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.exiT(); - } - }); - selectALL.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.selectALL(); - } - }); - lineWraP.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.lineWraP(); - } - }); - fonT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.fonT(); - } - }); - abouT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.abouT(); - } - }); - - /** - *adding action listener for the button in the tool bar: newButton, openButton, - *saveButton, saveAsButton, printButton, redoButton, undoButton, copyButton, - *cutButton, pasteButton, findButton, selectALL, lineWraP, fontButton & aboutButton - *the actions was written @Actions.java - */ - newButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.neW(); - } - }); - openButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.opeN(); - } - }); - saveButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.savE(); - } - }); - saveAsButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.saveAs(); - } - }); - printButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.prinT(); - } - }); - fontButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.fonT(); - } - }); - aboutButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.abouT(); - } - }); - - /** - *Setting the Line Wrap & Wrap Style Word features are true - */ - textArea.setLineWrap(true); - textArea.setWrapStyleWord(true); - /** - *for making the program at the center, - *@see Center.java - */ - center.nCenter(); - show(); - - ediT.add(cuT = new JMenuItem("Cut", new ImageIcon(this.getClass().getResource("images/cut.gif")))); - ediT.add(copY = new JMenuItem("Copy", new ImageIcon(this.getClass().getResource("images/copy.gif")))); - ediT.add(pastE= new JMenuItem("Paste",new ImageIcon(this.getClass().getResource("images/paste.gif")))); - - cuT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.CTRL_MASK)); - copY.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK)); - pastE.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.CTRL_MASK)); - - toolBar.add(cutButton = new JButton(new ImageIcon(this.getClass().getResource("images/cut.gif")))); - toolBar.add(copyButton = new JButton(new ImageIcon(this.getClass().getResource("images/copy.gif")))); - toolBar.add(pasteButton = new JButton(new ImageIcon(this.getClass().getResource("images/paste.gif")))); - - cutButton.setToolTipText("Cut"); - copyButton.setToolTipText("Copy"); - pasteButton.setToolTipText("Paste"); - - cuT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.cuT(); - } - }); - copY.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.copY(); - } - }); - pastE.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.pastE(); - } - }); - - cutButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.cuT(); - } - }); - copyButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.copY(); - } - }); - pasteButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.pastE(); - } - }); - - - ediT.add(finD = new JMenuItem("Find", new ImageIcon(this.getClass().getResource("images/find.gif")))); - ediT.add(findNexT = new JMenuItem("Find Next")); - //ediT.insertSeparator(8); - - /** - *allowing the finD menu item to be selected by pressing ALT + F - *allowing the findNexT menu item to be selected by pressing ALT + F3 - */ - finD.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F, ActionEvent.CTRL_MASK)); - findNexT.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F3, ActionEvent.CTRL_MASK)); - toolBar.add(findButton = new JButton(new ImageIcon(this.getClass().getResource("images/find.gif")))); - findButton.setToolTipText("Find"); - - finD.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.finD(); - } - }); - findNexT.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.findNexT(); - } - }); - - findButton.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent ae){ - actions.finD(); - } - }); - - ediT.add(undoAction); - ediT.add(redoAction); - - toolBar.addSeparator(); - toolBar.add(undoAction); - toolBar.add(redoAction); - toolBar.addSeparator(); - - textArea.getDocument().addUndoableEditListener(new UndoableEditListener(){ - public void undoableEditHappened(UndoableEditEvent e){ - //Remember the edit and update the menus - undo.addEdit(e.getEdit()); - undoAction.update(); - redoAction.update(); - } - }); - } - - - //Main Method - public static void main(String[] args){ - new Notepad(); - - } - - - private JButton cutButton, copyButton, pasteButton; - - - - private JButton findButton; - - - private JMenuItem finD, findNexT; - - - //for using undo & redo - UndoManager undo = new UndoManager(); - - - UndoAction undoAction = new UndoAction(this); - - - RedoAction redoAction = new RedoAction(this); - - - - private JButton undoButton, redoButton; - - -} diff --git a/java/spl/notepad/Variant00008java/Print.java b/java/spl/notepad/Variant00008java/Print.java deleted file mode 100644 index 132daed..0000000 --- a/java/spl/notepad/Variant00008java/Print.java +++ /dev/null @@ -1,64 +0,0 @@ -import java.awt.*; -import java.awt.print.*; -import javax.swing.*; - -/** - *A class for creating a printer option. - */ -public class Print implements Printable { - - private Component componentToBePrinted; - - - - public static void printComponent(Component c){ - new Print(c).print(); - } - - - public Print(Component componentToBePrinted){ - this.componentToBePrinted = componentToBePrinted; - } - - - public void print(){ - PrinterJob printJob = PrinterJob.getPrinterJob(); - printJob.setPrintable(this); - if(printJob.printDialog()) - try{ - printJob.print(); - } - catch(PrinterException pe){ - System.out.println("Error printing: " + pe); - } - } - - - public int print(Graphics g, PageFormat pageFormat, int pageIndex){ - if(pageIndex > 0){ - return(NO_SUCH_PAGE); - } - else{ - Graphics2D g2d = (Graphics2D)g; - g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); - disableDoubleBuffering(componentToBePrinted); - componentToBePrinted.paint(g2d); - enableDoubleBuffering(componentToBePrinted); - return(PAGE_EXISTS); - } - } - - - public static void disableDoubleBuffering(Component c){ - RepaintManager currentManager = RepaintManager.currentManager(c); - currentManager.setDoubleBufferingEnabled(false); - } - - - public static void enableDoubleBuffering(Component c){ - RepaintManager currentManager = RepaintManager.currentManager(c); - currentManager.setDoubleBufferingEnabled(true); - } - - -} diff --git a/java/spl/notepad/Variant00008java/RedoAction.java b/java/spl/notepad/Variant00008java/RedoAction.java deleted file mode 100644 index ccd8eaf..0000000 --- a/java/spl/notepad/Variant00008java/RedoAction.java +++ /dev/null @@ -1,50 +0,0 @@ -import java.awt.event.*; -import javax.swing.*; -import javax.swing.undo.*; - - - -class RedoAction extends AbstractAction { - - private static final long serialVersionUID = 1; - - - Notepad notepad; - - - - public RedoAction(Notepad notepad){ - super("Redo"); - putValue( Action.SMALL_ICON, - new ImageIcon(this.getClass().getResource("images/redo.gif"))); - setEnabled(false); - this.notepad = notepad; - } - - - public void actionPerformed(ActionEvent e){ - try{ - notepad.undo.redo(); - } - catch (CannotRedoException ex){ - System.out.println("Unable to redo: " + ex); - ex.printStackTrace(); - } - update(); - notepad.undoAction.update(); - } - - - protected void update(){ - if(notepad.undo.canRedo()){ - setEnabled(true); - putValue("Redo", notepad.undo.getRedoPresentationName()); - } - else{ - setEnabled(false); - putValue(Action.NAME, "Redo"); - } - } - - -} diff --git a/java/spl/notepad/Variant00008java/UndoAction.java b/java/spl/notepad/Variant00008java/UndoAction.java deleted file mode 100644 index 3298a36..0000000 --- a/java/spl/notepad/Variant00008java/UndoAction.java +++ /dev/null @@ -1,50 +0,0 @@ -import java.awt.event.*; -import javax.swing.*; -import javax.swing.undo.*; - - - -class UndoAction extends AbstractAction { - - private static final long serialVersionUID = 1; - - - Notepad notepad; - - - - public UndoAction(Notepad notepad){ - super( "Undo" ); - putValue( Action.SMALL_ICON, - new ImageIcon( this.getClass().getResource( "images/undo.gif" ) ) ); - setEnabled( false ); - this.notepad = notepad; - } - - - public void actionPerformed( ActionEvent e ) { - try { - notepad.undo.undo(); - } - catch ( CannotUndoException ex ) { - System.out.println( "Unable to undo: " + ex ); - ex.printStackTrace(); - } - update(); - notepad.redoAction.update(); - } - - - protected void update() { - if( notepad.undo.canUndo() ) { - setEnabled( true ); - putValue( "Undo", notepad.undo.getUndoPresentationName() ); - } - else { - setEnabled( false ); - putValue( Action.NAME, "Undo" ); - } - } - - -} diff --git a/js/gumtree_v0.js b/js/gumtree_v0.js deleted file mode 100644 index e34f63b..0000000 --- a/js/gumtree_v0.js +++ /dev/null @@ -1,90 +0,0 @@ -currentMapping = 0; - -if (typeof String.prototype.startsWith != 'function') { - String.prototype.startsWith = function (str){ - return this.slice(0, str.length) == str; - }; -} - -function getMappedElement(eltId) { - if (eltId.startsWith("move-src")) { - return eltId.replace("src","dst"); - } - else { - return eltId.replace("dst","src"); - } -} - -function nextMapping() { - if (currentMapping == 0) { - currentMapping = 1; - return "#mapping-" + currentMapping.toString(); - } else { - currentMapping++; - - if ($("#mapping-" + currentMapping.toString()).length > 0) { - return "#mapping-" + currentMapping.toString(); - } else { - currentMapping = 1; - return "#mapping-" + currentMapping.toString(); - } - } -} - -function isSrc(eltId) { - return eltId.startsWith("move-src"); -} - -$("body").keypress( - function (event) { - console.log(event.which.toString()); - if (event.which == 110) { - var mapping = nextMapping(); - $('html, body').animate({scrollTop: $(mapping).offset().top - 200}, 100); - } else if (event.which == 116) { - $('html, body').animate({scrollTop: 0}, 100); - } else if (event.which == 98) { - $("html, body").animate({ scrollTop: $(document).height() }, 100); - } else if (event.which == 113) { - window.location = "/quit"; - } - } -) - -$("span.mv.token, span.token.upd").click( - function(event) { - if ($(this).hasClass("selected")) { - $("span.mv.token, span.token.upd").removeClass("selected"); - } else { - $("span.mv.token, span.token.upd").removeClass("selected"); - var eltId = $(this).attr("id"); - var refEltId = getMappedElement(eltId); - $("#" + refEltId).addClass("selected"); - $(this).addClass("selected"); - var sel = "#dst"; - if (isSrc(refEltId)) var sel = "#src"; - - $div = $(sel); - $span = $("#" + refEltId); - } - event.stopPropagation(); - } -) - -$("span.add.token, span.token.del").click( - function(event) { - $("span.mv.token, span.token.upd").removeClass("selected"); - event.stopPropagation(); - } -) - -$("span.token").hover( - function (event) { - $(this).tooltip('show'); - event.stopPropagation(); - }, - function (event) { - $(this).tooltip('hide'); - event.stopPropagation(); - } -); diff --git a/js/gumtree_v1.js b/js/gumtree_v1.js deleted file mode 100644 index e5417b9..0000000 --- a/js/gumtree_v1.js +++ /dev/null @@ -1,91 +0,0 @@ -currentMapping = 0; - -if (typeof String.prototype.startsWith != 'function') { - String.prototype.startsWith = function (str){ - return this.slice(0, str.length) == str; - }; -} - -function getMappedElement(eltId) { - if (eltId.startsWith("move-src")) { - return eltId.replace("src","dst"); - } - else { - return eltId.replace("dst","src"); - } -} - -function nextMapping() { - if (currentMapping == 0) { - currentMapping = 1; - return "#mapping-" + currentMapping.toString(); - } else { - currentMapping++; - - if ($("#mapping-" + currentMapping.toString()).length > 0) { - return "#mapping-" + currentMapping.toString(); - } else { - currentMapping = 1; - return "#mapping-" + currentMapping.toString(); - } - } -} - -function isSrc(eltId) { - return eltId.startsWith("move-src"); -} - -$("body").keypress( - function (event) { - console.log(event.which.toString()); - if (event.which == 110) { - var mapping = nextMapping(); - $('html, body').animate({scrollTop: $(mapping).offset().top - 200}, 100); - } else if (event.which == 116) { - $('html, body').animate({scrollTop: 0}, 100); - } else if (event.which == 98) { - $("html, body").animate({ scrollTop: $(document).height() }, 100); - } else if (event.which == 113) { - window.location = "/quit"; - } - } -) - -$("span.mv.token, span.token.upd").click( - function(event) { - if ($(this).hasClass("selected")) { - $("span.mv.token, span.token.upd").removeClass("selected"); - } else { - $("span.mv.token, span.token.upd").removeClass("selected"); - var eltId = $(this).attr("id"); - var refEltId = getMappedElement(eltId); - $("#" + refEltId).addClass("selected"); - $(this).addClass("selected"); - var sel = "#dst"; - if (isSrc(refEltId)) var sel = "#src"; - - $div = $(sel); - $span = $("#" + refEltId); - } - event.stopPropagation(); - } -) - -$("span.token").hover( - function (event) { - $(this).tooltip('show'); - event.stopPropagation(); - }, - function (event) { - $(this).tooltip('hide'); - event.stopPropagation(); - } -) - -$("span.add.token, span.token.del").click( - function(event) { - $("span.mv.token, span.token.upd").removeClass("selected"); - event.stopPropagation(); - } -) -; diff --git a/json/ast_v0.json b/json/ast_v0.json deleted file mode 100644 index edc31c8..0000000 --- a/json/ast_v0.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "type": "Program", - "body": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "express" - }, - "init": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "require" - }, - "arguments": [ - { - "type": "Literal", - "value": "express", - "raw": "'express'" - } - ] - } - } - ], - "kind": "const" - } - ] -} \ No newline at end of file diff --git a/json/ast_v1.json b/json/ast_v1.json deleted file mode 100644 index 87b026e..0000000 --- a/json/ast_v1.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "type": "Program", - "body": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "express" - }, - "init": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "foo" - }, - "arguments": [ - { - "type": "Literal", - "value": "express", - "raw": "'express'" - } - ] - } - } - ], - "kind": "const" - } - ] -} \ No newline at end of file diff --git a/json/fullast_v0.json b/json/fullast_v0.json deleted file mode 100644 index 6273261..0000000 --- a/json/fullast_v0.json +++ /dev/null @@ -1,961 +0,0 @@ -{ - "type": "Program", - "body": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "express" - }, - "init": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "require" - }, - "arguments": [ - { - "type": "Literal", - "value": "express", - "raw": "'express'" - } - ] - } - } - ], - "kind": "const" - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "router" - }, - "init": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "express" - }, - "property": { - "type": "Identifier", - "name": "Router" - } - }, - "arguments": [] - } - } - ], - "kind": "const" - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "bodyParser" - }, - "init": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "require" - }, - "arguments": [ - { - "type": "Literal", - "value": "body-parser", - "raw": "'body-parser'" - } - ] - }, - "property": { - "type": "Identifier", - "name": "json" - } - }, - "arguments": [] - } - } - ], - "kind": "const" - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "Project" - }, - "init": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "require" - }, - "arguments": [ - { - "type": "Literal", - "value": "../models/project", - "raw": "'../models/project'" - } - ] - } - } - ], - "kind": "const" - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "router" - }, - "property": { - "type": "Identifier", - "name": "get" - } - }, - "arguments": [ - { - "type": "Literal", - "value": "/", - "raw": "'/'" - }, - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "req" - }, - { - "type": "Identifier", - "name": "res" - }, - { - "type": "Identifier", - "name": "next" - } - ], - "body": { - "type": "BlockStatement", - "body": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "Project" - }, - "property": { - "type": "Identifier", - "name": "find" - } - }, - "arguments": [] - }, - "property": { - "type": "Identifier", - "name": "lean" - } - }, - "arguments": [] - }, - "property": { - "type": "Identifier", - "name": "then" - } - }, - "arguments": [ - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "projects" - } - ], - "body": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "res" - }, - "property": { - "type": "Identifier", - "name": "send" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "projects" - } - ] - }, - "generator": false, - "expression": true, - "async": false - } - ] - }, - "property": { - "type": "Identifier", - "name": "catch" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "next" - } - ] - } - } - ] - }, - "generator": false, - "expression": false, - "async": false - } - ] - }, - "property": { - "type": "Identifier", - "name": "get" - } - }, - "arguments": [ - { - "type": "Literal", - "value": "/:id", - "raw": "'/:id'" - }, - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "req" - }, - { - "type": "Identifier", - "name": "res" - }, - { - "type": "Identifier", - "name": "next" - } - ], - "body": { - "type": "BlockStatement", - "body": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "Project" - }, - "property": { - "type": "Identifier", - "name": "findById" - } - }, - "arguments": [ - { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "req" - }, - "property": { - "type": "Identifier", - "name": "params" - } - }, - "property": { - "type": "Identifier", - "name": "id" - } - } - ] - }, - "property": { - "type": "Identifier", - "name": "then" - } - }, - "arguments": [ - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "project" - } - ], - "body": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "res" - }, - "property": { - "type": "Identifier", - "name": "send" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "project" - } - ] - }, - "generator": false, - "expression": true, - "async": false - } - ] - }, - "property": { - "type": "Identifier", - "name": "catch" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "next" - } - ] - } - } - ] - }, - "generator": false, - "expression": false, - "async": false - } - ] - }, - "property": { - "type": "Identifier", - "name": "delete" - } - }, - "arguments": [ - { - "type": "Literal", - "value": "/:id", - "raw": "'/:id'" - }, - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "req" - }, - { - "type": "Identifier", - "name": "res" - }, - { - "type": "Identifier", - "name": "next" - } - ], - "body": { - "type": "BlockStatement", - "body": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "Project" - }, - "property": { - "type": "Identifier", - "name": "findByIdAndRemove" - } - }, - "arguments": [ - { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "req" - }, - "property": { - "type": "Identifier", - "name": "params" - } - }, - "property": { - "type": "Identifier", - "name": "id" - } - } - ] - }, - "property": { - "type": "Identifier", - "name": "then" - } - }, - "arguments": [ - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "deleted" - } - ], - "body": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "res" - }, - "property": { - "type": "Identifier", - "name": "send" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "deleted" - } - ] - }, - "generator": false, - "expression": true, - "async": false - } - ] - }, - "property": { - "type": "Identifier", - "name": "catch" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "next" - } - ] - } - } - ] - }, - "generator": false, - "expression": false, - "async": false - } - ] - }, - "property": { - "type": "Identifier", - "name": "post" - } - }, - "arguments": [ - { - "type": "Literal", - "value": "/", - "raw": "'/'" - }, - { - "type": "Identifier", - "name": "bodyParser" - }, - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "req" - }, - { - "type": "Identifier", - "name": "res" - }, - { - "type": "Identifier", - "name": "next" - } - ], - "body": { - "type": "BlockStatement", - "body": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "proj" - }, - "init": { - "type": "NewExpression", - "callee": { - "type": "Identifier", - "name": "Project" - }, - "arguments": [ - { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "req" - }, - "property": { - "type": "Identifier", - "name": "body" - } - } - ] - } - } - ], - "kind": "let" - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "proj" - }, - "property": { - "type": "Identifier", - "name": "user" - } - }, - "right": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "req" - }, - "property": { - "type": "Identifier", - "name": "user" - } - }, - "property": { - "type": "Identifier", - "name": "id" - } - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "proj" - }, - "property": { - "type": "Identifier", - "name": "save" - } - }, - "arguments": [] - }, - "property": { - "type": "Identifier", - "name": "then" - } - }, - "arguments": [ - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "saved" - } - ], - "body": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "res" - }, - "property": { - "type": "Identifier", - "name": "send" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "saved" - } - ] - }, - "generator": false, - "expression": true, - "async": false - } - ] - }, - "property": { - "type": "Identifier", - "name": "catch" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "next" - } - ] - } - } - ] - }, - "generator": false, - "expression": false, - "async": false - } - ] - }, - "property": { - "type": "Identifier", - "name": "put" - } - }, - "arguments": [ - { - "type": "Literal", - "value": "/:id", - "raw": "'/:id'" - }, - { - "type": "Identifier", - "name": "bodyParser" - }, - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "req" - }, - { - "type": "Identifier", - "name": "res" - }, - { - "type": "Identifier", - "name": "next" - } - ], - "body": { - "type": "BlockStatement", - "body": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "Project" - }, - "property": { - "type": "Identifier", - "name": "findByIdAndUpdate" - } - }, - "arguments": [ - { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "req" - }, - "property": { - "type": "Identifier", - "name": "params" - } - }, - "property": { - "type": "Identifier", - "name": "id" - } - }, - { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "req" - }, - "property": { - "type": "Identifier", - "name": "body" - } - } - ] - }, - "property": { - "type": "Identifier", - "name": "then" - } - }, - "arguments": [ - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "saved" - } - ], - "body": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "res" - }, - "property": { - "type": "Identifier", - "name": "send" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "saved" - } - ] - }, - "generator": false, - "expression": true, - "async": false - } - ] - }, - "property": { - "type": "Identifier", - "name": "catch" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "next" - } - ] - } - } - ] - }, - "generator": false, - "expression": false, - "async": false - } - ] - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "module" - }, - "property": { - "type": "Identifier", - "name": "exports" - } - }, - "right": { - "type": "Identifier", - "name": "router" - } - } - } - ], - "sourceType": "script" -} \ No newline at end of file diff --git a/json/fullast_v1.json b/json/fullast_v1.json deleted file mode 100644 index 22965c1..0000000 --- a/json/fullast_v1.json +++ /dev/null @@ -1,961 +0,0 @@ -{ - "type": "Program", - "body": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "express" - }, - "init": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "require" - }, - "arguments": [ - { - "type": "Literal", - "value": "express", - "raw": "'express'" - } - ] - } - } - ], - "kind": "const" - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "router" - }, - "init": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "express" - }, - "property": { - "type": "Identifier", - "name": "Router" - } - }, - "arguments": [] - } - } - ], - "kind": "const" - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "bodyParser" - }, - "init": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "require" - }, - "arguments": [ - { - "type": "Literal", - "value": "body-parser", - "raw": "'body-parser'" - } - ] - }, - "property": { - "type": "Identifier", - "name": "json" - } - }, - "arguments": [] - } - } - ], - "kind": "const" - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "Project" - }, - "init": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "require" - }, - "arguments": [ - { - "type": "Literal", - "value": "../models/project", - "raw": "'../models/project'" - } - ] - } - } - ], - "kind": "const" - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "router" - }, - "property": { - "type": "Identifier", - "name": "get" - } - }, - "arguments": [ - { - "type": "Literal", - "value": "/", - "raw": "'/'" - }, - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "req" - }, - { - "type": "Identifier", - "name": "res" - }, - { - "type": "Identifier", - "name": "next" - } - ], - "body": { - "type": "BlockStatement", - "body": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "Project" - }, - "property": { - "type": "Identifier", - "name": "find" - } - }, - "arguments": [] - }, - "property": { - "type": "Identifier", - "name": "lean" - } - }, - "arguments": [] - }, - "property": { - "type": "Identifier", - "name": "then" - } - }, - "arguments": [ - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "projects" - } - ], - "body": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "res" - }, - "property": { - "type": "Identifier", - "name": "send" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "projects" - } - ] - }, - "generator": false, - "expression": true, - "async": false - } - ] - }, - "property": { - "type": "Identifier", - "name": "catch" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "next" - } - ] - } - } - ] - }, - "generator": false, - "expression": false, - "async": false - } - ] - }, - "property": { - "type": "Identifier", - "name": "get" - } - }, - "arguments": [ - { - "type": "Literal", - "value": "/:id", - "raw": "'/:id'" - }, - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "req" - }, - { - "type": "Identifier", - "name": "res" - }, - { - "type": "Identifier", - "name": "next" - } - ], - "body": { - "type": "BlockStatement", - "body": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "Project" - }, - "property": { - "type": "Identifier", - "name": "findById" - } - }, - "arguments": [ - { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "req" - }, - "property": { - "type": "Identifier", - "name": "params" - } - }, - "property": { - "type": "Identifier", - "name": "id" - } - } - ] - }, - "property": { - "type": "Identifier", - "name": "then" - } - }, - "arguments": [ - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "project" - } - ], - "body": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "res" - }, - "property": { - "type": "Identifier", - "name": "send" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "project" - } - ] - }, - "generator": false, - "expression": true, - "async": false - } - ] - }, - "property": { - "type": "Identifier", - "name": "catch" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "next" - } - ] - } - } - ] - }, - "generator": false, - "expression": false, - "async": false - } - ] - }, - "property": { - "type": "Identifier", - "name": "delete" - } - }, - "arguments": [ - { - "type": "Literal", - "value": "/:id", - "raw": "'/:id'" - }, - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "req" - }, - { - "type": "Identifier", - "name": "res" - }, - { - "type": "Identifier", - "name": "next" - } - ], - "body": { - "type": "BlockStatement", - "body": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "Project" - }, - "property": { - "type": "Identifier", - "name": "findByIdAndRemove" - } - }, - "arguments": [ - { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "req" - }, - "property": { - "type": "Identifier", - "name": "params" - } - }, - "property": { - "type": "Identifier", - "name": "id" - } - } - ] - }, - "property": { - "type": "Identifier", - "name": "then" - } - }, - "arguments": [ - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "deleted" - } - ], - "body": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "res" - }, - "property": { - "type": "Identifier", - "name": "send" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "deleted" - } - ] - }, - "generator": false, - "expression": true, - "async": false - } - ] - }, - "property": { - "type": "Identifier", - "name": "catch" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "next" - } - ] - } - } - ] - }, - "generator": false, - "expression": false, - "async": false - } - ] - }, - "property": { - "type": "Identifier", - "name": "post" - } - }, - "arguments": [ - { - "type": "Literal", - "value": "/", - "raw": "'/'" - }, - { - "type": "Identifier", - "name": "bodyParser" - }, - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "req" - }, - { - "type": "Identifier", - "name": "res" - }, - { - "type": "Identifier", - "name": "next" - } - ], - "body": { - "type": "BlockStatement", - "body": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "proj" - }, - "init": { - "type": "NewExpression", - "callee": { - "type": "Identifier", - "name": "Project" - }, - "arguments": [ - { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "req" - }, - "property": { - "type": "Identifier", - "name": "body" - } - } - ] - } - } - ], - "kind": "let" - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "proj" - }, - "property": { - "type": "Identifier", - "name": "userId" - } - }, - "right": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "req" - }, - "property": { - "type": "Identifier", - "name": "user" - } - }, - "property": { - "type": "Identifier", - "name": "id" - } - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "proj" - }, - "property": { - "type": "Identifier", - "name": "save" - } - }, - "arguments": [] - }, - "property": { - "type": "Identifier", - "name": "then" - } - }, - "arguments": [ - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "saved" - } - ], - "body": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "res" - }, - "property": { - "type": "Identifier", - "name": "send" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "saved" - } - ] - }, - "generator": false, - "expression": true, - "async": false - } - ] - }, - "property": { - "type": "Identifier", - "name": "catch" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "next" - } - ] - } - } - ] - }, - "generator": false, - "expression": false, - "async": false - } - ] - }, - "property": { - "type": "Identifier", - "name": "put" - } - }, - "arguments": [ - { - "type": "Literal", - "value": "/:id", - "raw": "'/:id'" - }, - { - "type": "Identifier", - "name": "bodyParser" - }, - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "req" - }, - { - "type": "Identifier", - "name": "res" - }, - { - "type": "Identifier", - "name": "next" - } - ], - "body": { - "type": "BlockStatement", - "body": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "Project" - }, - "property": { - "type": "Identifier", - "name": "findByIdAndUpdate" - } - }, - "arguments": [ - { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "req" - }, - "property": { - "type": "Identifier", - "name": "params" - } - }, - "property": { - "type": "Identifier", - "name": "id" - } - }, - { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "req" - }, - "property": { - "type": "Identifier", - "name": "body" - } - } - ] - }, - "property": { - "type": "Identifier", - "name": "then" - } - }, - "arguments": [ - { - "type": "ArrowFunctionExpression", - "id": null, - "params": [ - { - "type": "Identifier", - "name": "saved" - } - ], - "body": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "res" - }, - "property": { - "type": "Identifier", - "name": "send" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "saved" - } - ] - }, - "generator": false, - "expression": true, - "async": false - } - ] - }, - "property": { - "type": "Identifier", - "name": "catch" - } - }, - "arguments": [ - { - "type": "Identifier", - "name": "next" - } - ] - } - } - ] - }, - "generator": false, - "expression": false, - "async": false - } - ] - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "computed": false, - "object": { - "type": "Identifier", - "name": "module" - }, - "property": { - "type": "Identifier", - "name": "exports" - } - }, - "right": { - "type": "Identifier", - "name": "router" - } - } - } - ], - "sourceType": "script" -} \ No newline at end of file diff --git a/json/stack_v0.json b/json/stack_v0.json deleted file mode 100644 index 0b5d091..0000000 --- a/json/stack_v0.json +++ /dev/null @@ -1,510 +0,0 @@ - - -{ - "items": [ - { - "owner": { - "reputation": 16, - "user_id": 2473093, - "user_type": "registered", - "profile_image": "http:\/\/i.stack.imgur.com\/Oh4Gc.jpg?s=128&g=1", - "display_name": "urman", - "link": "http:\/\/stackoverflow.com\/users\/2473093\/urman" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591411, - "last_edit_date": 1431591411, - "creation_date": 1431582116, - "answer_id": 30230049, - "question_id": 30148202 - }, - { - "owner": { - "reputation": 52, - "user_id": 4864889, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/8378261cf0d4950301ad65087487f51b?s=128&d=identicon&r=PG&f=1", - "display_name": "Amir H", - "link": "http:\/\/stackoverflow.com\/users\/4864889\/amir-h" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591407, - "creation_date": 1431591407, - "answer_id": 30232512, - "question_id": 30231345 - }, - { - "owner": { - "reputation": 1523, - "user_id": 4391147, - "user_type": "registered", - "profile_image": "https:\/\/lh5.googleusercontent.com\/-WJ2zykPbiqI\/AAAAAAAAAAI\/AAAAAAAAAng\/9C2D_oliqD8\/photo.jpg?sz=128", - "display_name": "Alexander Dayan", - "link": "http:\/\/stackoverflow.com\/users\/4391147\/alexander-dayan" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591407, - "creation_date": 1431591407, - "answer_id": 30232511, - "question_id": 30232423 - }, - { - "owner": { - "reputation": 9, - "user_id": 3433258, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/31795b700ed9401855a752f1728565e9?s=128&d=identicon&r=PG&f=1", - "display_name": "swapnilagarwal", - "link": "http:\/\/stackoverflow.com\/users\/3433258\/swapnilagarwal" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591405, - "creation_date": 1431591405, - "answer_id": 30232510, - "question_id": 30227759 - }, - { - "owner": { - "reputation": 94, - "user_id": 1808654, - "user_type": "registered", - "accept_rate": 89, - "profile_image": "https:\/\/www.gravatar.com\/avatar\/f685c091ceb85bd4053dfc84c3b1fc74?s=128&d=identicon&r=PG", - "display_name": "oyjh", - "link": "http:\/\/stackoverflow.com\/users\/1808654\/oyjh" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591395, - "creation_date": 1431591395, - "answer_id": 30232509, - "question_id": 30209710 - }, - { - "owner": { - "reputation": 123, - "user_id": 2589810, - "user_type": "registered", - "profile_image": "http:\/\/graph.facebook.com\/1195031301\/picture?type=large", - "display_name": "Akshin Jalilov", - "link": "http:\/\/stackoverflow.com\/users\/2589810\/akshin-jalilov" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591388, - "creation_date": 1431591388, - "answer_id": 30232508, - "question_id": 30224912 - }, - { - "owner": { - "reputation": 2871, - "user_id": 4519059, - "user_type": "registered", - "accept_rate": 17, - "profile_image": "http:\/\/i.stack.imgur.com\/RDPZo.png?s=128&g=1", - "display_name": "shA.t", - "link": "http:\/\/stackoverflow.com\/users\/4519059\/sha-t" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591366, - "last_edit_date": 1431591366, - "creation_date": 1431587344, - "answer_id": 30231391, - "question_id": 30228478 - }, - { - "owner": { - "reputation": 128178, - "user_id": 330315, - "user_type": "registered", - "accept_rate": 83, - "profile_image": "https:\/\/www.gravatar.com\/avatar\/4b152262d9ba55197f609625358ff7e0?s=128&d=identicon&r=PG", - "display_name": "a_horse_with_no_name", - "link": "http:\/\/stackoverflow.com\/users\/330315\/a-horse-with-no-name" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591343, - "creation_date": 1431591343, - "answer_id": 30232502, - "question_id": 30231832 - }, - { - "owner": { - "reputation": 750, - "user_id": 2468158, - "user_type": "registered", - "profile_image": "http:\/\/i.stack.imgur.com\/LSk1F.jpg?s=128&g=1", - "display_name": "Drumbeg", - "link": "http:\/\/stackoverflow.com\/users\/2468158\/drumbeg" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591341, - "last_edit_date": 1431591341, - "creation_date": 1431590718, - "answer_id": 30232332, - "question_id": 30231746 - }, - { - "owner": { - "reputation": 28424, - "user_id": 1256624, - "user_type": "registered", - "profile_image": "http:\/\/i.stack.imgur.com\/EdJaa.jpg?s=128&g=1", - "display_name": "huon-dbaupp", - "link": "http:\/\/stackoverflow.com\/users\/1256624\/huon-dbaupp" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591335, - "creation_date": 1431591335, - "answer_id": 30232500, - "question_id": 30177395 - }, - { - "owner": { - "reputation": 11, - "user_id": 4799901, - "user_type": "registered", - "profile_image": "http:\/\/graph.facebook.com\/851364241589275\/picture?type=large", - "display_name": "Sågär \u015aåxë\u0144á", - "link": "http:\/\/stackoverflow.com\/users\/4799901\/s%c3%a5g%c3%a4r-%c5%9a%c3%a5x%c3%ab%c5%84%c3%a1" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591333, - "creation_date": 1431591333, - "answer_id": 30232499, - "question_id": 12258814 - }, - { - "owner": { - "reputation": 76046, - "user_id": 1919155, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/0d7d26642f016f64f37619d209037dff?s=128&d=identicon&r=PG", - "display_name": "Mats Petersson", - "link": "http:\/\/stackoverflow.com\/users\/1919155\/mats-petersson" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591333, - "creation_date": 1431591333, - "answer_id": 30232498, - "question_id": 30231938 - }, - { - "owner": { - "reputation": 21598, - "user_id": 17875, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/9589a0b8efc6bb869bedfa51e7d28f16?s=128&d=identicon&r=PG", - "display_name": "Eevee", - "link": "http:\/\/stackoverflow.com\/users\/17875\/eevee" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591321, - "creation_date": 1431591321, - "answer_id": 30232496, - "question_id": 30232421 - }, - { - "owner": { - "reputation": 11, - "user_id": 4890577, - "user_type": "registered", - "profile_image": "http:\/\/i.stack.imgur.com\/aehYB.png?s=128&g=1", - "display_name": "lord63. j", - "link": "http:\/\/stackoverflow.com\/users\/4890577\/lord63-j" - }, - "is_accepted": false, - "score": 1, - "last_activity_date": 1431591321, - "creation_date": 1431591321, - "answer_id": 30232495, - "question_id": 30232344 - }, - { - "owner": { - "reputation": 10121, - "user_id": 1351469, - "user_type": "registered", - "accept_rate": 100, - "profile_image": "https:\/\/www.gravatar.com\/avatar\/d0a659b0aa7c7dfc45ab9cff52f3c140?s=128&d=identicon&r=PG", - "display_name": "jcesarmobile", - "link": "http:\/\/stackoverflow.com\/users\/1351469\/jcesarmobile" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591320, - "creation_date": 1431591320, - "answer_id": 30232494, - "question_id": 30217167 - }, - { - "owner": { - "reputation": 1, - "user_id": 4896508, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/d9be840fb80aed5a6b27da4b78452b74?s=128&d=identicon&r=PG&f=1", - "display_name": "Leo", - "link": "http:\/\/stackoverflow.com\/users\/4896508\/leo" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591309, - "creation_date": 1431591309, - "answer_id": 30232492, - "question_id": 30224254 - }, - { - "owner": { - "reputation": 76, - "user_id": 4628456, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/b1217b1f012b0638d589bcdfdb27fe8b?s=128&d=identicon&r=PG&f=1", - "display_name": "swelsh", - "link": "http:\/\/stackoverflow.com\/users\/4628456\/swelsh" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591308, - "creation_date": 1431591308, - "answer_id": 30232490, - "question_id": 30223997 - }, - { - "owner": { - "reputation": 44, - "user_id": 162615, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/647972e0840d0dd84e87a4317f0c91c7?s=128&d=identicon&r=PG", - "display_name": "Thommas", - "link": "http:\/\/stackoverflow.com\/users\/162615\/thommas" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591302, - "creation_date": 1431591302, - "answer_id": 30232489, - "question_id": 23519983 - }, - { - "owner": { - "reputation": 28, - "user_id": 3302933, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/f25042331fe29187bfd5ad2a5eb461c2?s=128&d=identicon&r=PG", - "display_name": "JVercout", - "link": "http:\/\/stackoverflow.com\/users\/3302933\/jvercout" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591292, - "creation_date": 1431591292, - "answer_id": 30232487, - "question_id": 30229995 - }, - { - "owner": { - "reputation": 28575, - "user_id": 704848, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/3f9be2c2958e208c8d9b629ac43c9c42?s=128&d=identicon&r=PG", - "display_name": "EdChum", - "link": "http:\/\/stackoverflow.com\/users\/704848\/edchum" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591291, - "creation_date": 1431591291, - "answer_id": 30232486, - "question_id": 30230548 - }, - { - "owner": { - "reputation": 12492, - "user_id": 2435473, - "user_type": "registered", - "accept_rate": 60, - "profile_image": "http:\/\/i.stack.imgur.com\/GOWOI.jpg?s=128&g=1", - "display_name": "pankajparkar", - "link": "http:\/\/stackoverflow.com\/users\/2435473\/pankajparkar" - }, - "is_accepted": true, - "score": 1, - "last_activity_date": 1431591288, - "last_edit_date": 1431591288, - "creation_date": 1431590547, - "answer_id": 30232282, - "question_id": 30232179 - }, - { - "owner": { - "reputation": 5733, - "user_id": 3518452, - "user_type": "registered", - "accept_rate": 94, - "profile_image": "https:\/\/www.gravatar.com\/avatar\/71c8adf8d0ebc93a00ac2a0498509091?s=128&d=identicon&r=PG", - "display_name": "rnevius", - "link": "http:\/\/stackoverflow.com\/users\/3518452\/rnevius" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591286, - "creation_date": 1431591286, - "answer_id": 30232484, - "question_id": 30232305 - }, - { - "owner": { - "reputation": 58530, - "user_id": 92315, - "user_type": "registered", - "accept_rate": 50, - "profile_image": "https:\/\/www.gravatar.com\/avatar\/d2824c2017a878f6fe05db2797694608?s=128&d=identicon&r=PG", - "display_name": "Fabien Ménager", - "link": "http:\/\/stackoverflow.com\/users\/92315\/fabien-m%c3%a9nager" - }, - "is_accepted": true, - "score": 4706, - "last_activity_date": 1431591279, - "last_edit_date": 1431591279, - "creation_date": 1259067936, - "answer_id": 1789952, - "question_id": 1789945 - }, - { - "owner": { - "reputation": 341, - "user_id": 3254377, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/108584ca35efbc205efe9160bb3d7fc7?s=128&d=identicon&r=PG&f=1", - "display_name": "wsl", - "link": "http:\/\/stackoverflow.com\/users\/3254377\/wsl" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591266, - "creation_date": 1431591266, - "answer_id": 30232479, - "question_id": 30232349 - }, - { - "owner": { - "reputation": 699, - "user_id": 1519186, - "user_type": "registered", - "accept_rate": 100, - "profile_image": "http:\/\/i.stack.imgur.com\/VJWGi.jpg?s=128&g=1", - "display_name": "Marco Kerwitz", - "link": "http:\/\/stackoverflow.com\/users\/1519186\/marco-kerwitz" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591260, - "last_edit_date": 1431591260, - "creation_date": 1431590862, - "answer_id": 30232366, - "question_id": 30232320 - }, - { - "owner": { - "reputation": 13, - "user_id": 1827885, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/3f3fe425330ed46481d3abdac97da62c?s=128&d=identicon&r=PG", - "display_name": "Mebibyte", - "link": "http:\/\/stackoverflow.com\/users\/1827885\/mebibyte" - }, - "is_accepted": false, - "score": 1, - "last_activity_date": 1431591259, - "last_edit_date": 1431591259, - "creation_date": 1431590808, - "answer_id": 30232355, - "question_id": 30232095 - }, - { - "owner": { - "reputation": 1944, - "user_id": 1485701, - "user_type": "registered", - "accept_rate": 67, - "profile_image": "http:\/\/i.stack.imgur.com\/2XZYq.jpg?s=128&g=1", - "display_name": "Antoine", - "link": "http:\/\/stackoverflow.com\/users\/1485701\/antoine" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591256, - "last_edit_date": 1431591256, - "creation_date": 1431087914, - "answer_id": 30123839, - "question_id": 19196659 - }, - { - "owner": { - "reputation": 91, - "user_id": 4711799, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/1b2ec531248f7ad1c32328c9de0d2171?s=128&d=identicon&r=PG&f=1", - "display_name": "BDH", - "link": "http:\/\/stackoverflow.com\/users\/4711799\/bdh" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591242, - "creation_date": 1431591242, - "answer_id": 30232474, - "question_id": 30232171 - }, - { - "owner": { - "reputation": 891, - "user_id": 978690, - "user_type": "registered", - "accept_rate": 86, - "profile_image": "https:\/\/www.gravatar.com\/avatar\/700764aebc81328fccad1fbd558dca75?s=128&d=identicon&r=PG", - "display_name": "rap-2-h", - "link": "http:\/\/stackoverflow.com\/users\/978690\/rap-2-h" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591242, - "creation_date": 1431591242, - "answer_id": 30232473, - "question_id": 30232334 - }, - { - "owner": { - "reputation": 672, - "user_id": 2064336, - "user_type": "registered", - "accept_rate": 75, - "profile_image": "http:\/\/i.stack.imgur.com\/NpJar.jpg?s=128&g=1", - "display_name": "Jaydipsinh Zala", - "link": "http:\/\/stackoverflow.com\/users\/2064336\/jaydipsinh-zala" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591241, - "last_edit_date": 1431591241, - "creation_date": 1431588560, - "answer_id": 30231742, - "question_id": 16893209 - } - ], - "has_more": true, - "quota_max": 300, - "quota_remaining": 287 -} - diff --git a/json/stack_v1.json b/json/stack_v1.json deleted file mode 100644 index dfd20f7..0000000 --- a/json/stack_v1.json +++ /dev/null @@ -1,505 +0,0 @@ - - -{ - "items": [ - { - "owner": { - "reputation": 2207, - "user_id": 3231537, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/c4d3a1f41ad792af6260d0a6928ec2b0?s=128&d=identicon&r=PG&f=1", - "display_name": "Icepickle", - "link": "http:\/\/stackoverflow.com\/users\/3231537\/icepickle" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591436, - "creation_date": 1431591436, - "answer_id": 30232521, - "question_id": 30232423 - }, - { - "owner": { - "reputation": 3790, - "user_id": 264586, - "user_type": "registered", - "accept_rate": 73, - "profile_image": "https:\/\/www.gravatar.com\/avatar\/3ae79b0f532a46eee28cc7f6edf4c099?s=128&d=identicon&r=PG", - "display_name": "JSJ", - "link": "http:\/\/stackoverflow.com\/users\/264586\/jsj" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591435, - "creation_date": 1431591435, - "answer_id": 30232520, - "question_id": 30231910 - }, - { - "owner": { - "reputation": 16, - "user_id": 4885321, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/c966387fdadf996e8a5d8a14bc482903?s=128&d=identicon&r=PG", - "display_name": "alagner", - "link": "http:\/\/stackoverflow.com\/users\/4885321\/alagner" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591435, - "creation_date": 1431591435, - "answer_id": 30232519, - "question_id": 30231982 - }, - { - "owner": { - "reputation": 2702, - "user_id": 2432053, - "user_type": "registered", - "accept_rate": 31, - "profile_image": "http:\/\/i.stack.imgur.com\/0jpKi.jpg?s=128&g=1", - "display_name": "arturdev", - "link": "http:\/\/stackoverflow.com\/users\/2432053\/arturdev" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591434, - "creation_date": 1431591434, - "answer_id": 30232518, - "question_id": 30161173 - }, - { - "owner": { - "reputation": 32, - "user_id": 4801298, - "user_type": "registered", - "profile_image": "http:\/\/i.stack.imgur.com\/N043H.jpg?s=128&g=1", - "display_name": "Sarfaraaz", - "link": "http:\/\/stackoverflow.com\/users\/4801298\/sarfaraaz" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591427, - "creation_date": 1431591427, - "answer_id": 30232517, - "question_id": 30232026 - }, - { - "owner": { - "reputation": 199747, - "user_id": 114251, - "user_type": "registered", - "accept_rate": 89, - "profile_image": "http:\/\/i.stack.imgur.com\/sNLiB.jpg?s=128&g=1", - "display_name": "Arun P Johny", - "link": "http:\/\/stackoverflow.com\/users\/114251\/arun-p-johny" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591420, - "creation_date": 1431591420, - "answer_id": 30232516, - "question_id": 30232423 - }, - { - "owner": { - "reputation": 1, - "user_id": 4898880, - "user_type": "registered", - "profile_image": "http:\/\/i.stack.imgur.com\/GiiSv.png?s=128&g=1", - "display_name": "headuck", - "link": "http:\/\/stackoverflow.com\/users\/4898880\/headuck" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591420, - "creation_date": 1431591420, - "answer_id": 30232515, - "question_id": 26924618 - }, - { - "owner": { - "reputation": 16, - "user_id": 2473093, - "user_type": "registered", - "profile_image": "http:\/\/i.stack.imgur.com\/Oh4Gc.jpg?s=128&g=1", - "display_name": "urman", - "link": "http:\/\/stackoverflow.com\/users\/2473093\/urman" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591411, - "last_edit_date": 1431591411, - "creation_date": 1431582116, - "answer_id": 30230049, - "question_id": 30148202 - }, - { - "owner": { - "reputation": 52, - "user_id": 4864889, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/8378261cf0d4950301ad65087487f51b?s=128&d=identicon&r=PG&f=1", - "display_name": "Amir H", - "link": "http:\/\/stackoverflow.com\/users\/4864889\/amir-h" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591407, - "creation_date": 1431591407, - "answer_id": 30232512, - "question_id": 30231345 - }, - { - "owner": { - "reputation": 1523, - "user_id": 4391147, - "user_type": "registered", - "profile_image": "https:\/\/lh5.googleusercontent.com\/-WJ2zykPbiqI\/AAAAAAAAAAI\/AAAAAAAAAng\/9C2D_oliqD8\/photo.jpg?sz=128", - "display_name": "Alexander Dayan", - "link": "http:\/\/stackoverflow.com\/users\/4391147\/alexander-dayan" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591407, - "creation_date": 1431591407, - "answer_id": 30232511, - "question_id": 30232423 - }, - { - "owner": { - "reputation": 9, - "user_id": 3433258, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/31795b700ed9401855a752f1728565e9?s=128&d=identicon&r=PG&f=1", - "display_name": "swapnilagarwal", - "link": "http:\/\/stackoverflow.com\/users\/3433258\/swapnilagarwal" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591405, - "creation_date": 1431591405, - "answer_id": 30232510, - "question_id": 30227759 - }, - { - "owner": { - "reputation": 123, - "user_id": 2589810, - "user_type": "registered", - "profile_image": "http:\/\/graph.facebook.com\/1195031301\/picture?type=large", - "display_name": "Akshin Jalilov", - "link": "http:\/\/stackoverflow.com\/users\/2589810\/akshin-jalilov" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591388, - "creation_date": 1431591388, - "answer_id": 30232508, - "question_id": 30224912 - }, - { - "owner": { - "reputation": 2871, - "user_id": 4519059, - "user_type": "registered", - "accept_rate": 17, - "profile_image": "http:\/\/i.stack.imgur.com\/RDPZo.png?s=128&g=1", - "display_name": "shA.t", - "link": "http:\/\/stackoverflow.com\/users\/4519059\/sha-t" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591366, - "last_edit_date": 1431591366, - "creation_date": 1431587344, - "answer_id": 30231391, - "question_id": 30228478 - }, - { - "owner": { - "reputation": 128178, - "user_id": 330315, - "user_type": "registered", - "accept_rate": 83, - "profile_image": "https:\/\/www.gravatar.com\/avatar\/4b152262d9ba55197f609625358ff7e0?s=128&d=identicon&r=PG", - "display_name": "a_horse_with_no_name", - "link": "http:\/\/stackoverflow.com\/users\/330315\/a-horse-with-no-name" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591343, - "creation_date": 1431591343, - "answer_id": 30232502, - "question_id": 30231832 - }, - { - "owner": { - "reputation": 750, - "user_id": 2468158, - "user_type": "registered", - "profile_image": "http:\/\/i.stack.imgur.com\/LSk1F.jpg?s=128&g=1", - "display_name": "Drumbeg", - "link": "http:\/\/stackoverflow.com\/users\/2468158\/drumbeg" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591341, - "last_edit_date": 1431591341, - "creation_date": 1431590718, - "answer_id": 30232332, - "question_id": 30231746 - }, - { - "owner": { - "reputation": 28424, - "user_id": 1256624, - "user_type": "registered", - "profile_image": "http:\/\/i.stack.imgur.com\/EdJaa.jpg?s=128&g=1", - "display_name": "huon-dbaupp", - "link": "http:\/\/stackoverflow.com\/users\/1256624\/huon-dbaupp" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591335, - "creation_date": 1431591335, - "answer_id": 30232500, - "question_id": 30177395 - }, - { - "owner": { - "reputation": 11, - "user_id": 4799901, - "user_type": "registered", - "profile_image": "http:\/\/graph.facebook.com\/851364241589275\/picture?type=large", - "display_name": "Sågär \u015aåxë\u0144á", - "link": "http:\/\/stackoverflow.com\/users\/4799901\/s%c3%a5g%c3%a4r-%c5%9a%c3%a5x%c3%ab%c5%84%c3%a1" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591333, - "creation_date": 1431591333, - "answer_id": 30232499, - "question_id": 12258814 - }, - { - "owner": { - "reputation": 76046, - "user_id": 1919155, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/0d7d26642f016f64f37619d209037dff?s=128&d=identicon&r=PG", - "display_name": "Mats Petersson", - "link": "http:\/\/stackoverflow.com\/users\/1919155\/mats-petersson" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591333, - "creation_date": 1431591333, - "answer_id": 30232498, - "question_id": 30231938 - }, - { - "owner": { - "reputation": 21598, - "user_id": 17875, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/9589a0b8efc6bb869bedfa51e7d28f16?s=128&d=identicon&r=PG", - "display_name": "Eevee", - "link": "http:\/\/stackoverflow.com\/users\/17875\/eevee" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591321, - "creation_date": 1431591321, - "answer_id": 30232496, - "question_id": 30232421 - }, - { - "owner": { - "reputation": 11, - "user_id": 4890577, - "user_type": "registered", - "profile_image": "http:\/\/i.stack.imgur.com\/aehYB.png?s=128&g=1", - "display_name": "lord63. j", - "link": "http:\/\/stackoverflow.com\/users\/4890577\/lord63-j" - }, - "is_accepted": false, - "score": 1, - "last_activity_date": 1431591321, - "creation_date": 1431591321, - "answer_id": 30232495, - "question_id": 30232344 - }, - { - "owner": { - "reputation": 10121, - "user_id": 1351469, - "user_type": "registered", - "accept_rate": 100, - "profile_image": "https:\/\/www.gravatar.com\/avatar\/d0a659b0aa7c7dfc45ab9cff52f3c140?s=128&d=identicon&r=PG", - "display_name": "jcesarmobile", - "link": "http:\/\/stackoverflow.com\/users\/1351469\/jcesarmobile" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591320, - "creation_date": 1431591320, - "answer_id": 30232494, - "question_id": 30217167 - }, - { - "owner": { - "reputation": 1, - "user_id": 4896508, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/d9be840fb80aed5a6b27da4b78452b74?s=128&d=identicon&r=PG&f=1", - "display_name": "Leo", - "link": "http:\/\/stackoverflow.com\/users\/4896508\/leo" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591309, - "creation_date": 1431591309, - "answer_id": 30232492, - "question_id": 30224254 - }, - { - "owner": { - "reputation": 76, - "user_id": 4628456, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/b1217b1f012b0638d589bcdfdb27fe8b?s=128&d=identicon&r=PG&f=1", - "display_name": "swelsh", - "link": "http:\/\/stackoverflow.com\/users\/4628456\/swelsh" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591308, - "creation_date": 1431591308, - "answer_id": 30232490, - "question_id": 30223997 - }, - { - "owner": { - "reputation": 44, - "user_id": 162615, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/647972e0840d0dd84e87a4317f0c91c7?s=128&d=identicon&r=PG", - "display_name": "Thommas", - "link": "http:\/\/stackoverflow.com\/users\/162615\/thommas" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591302, - "creation_date": 1431591302, - "answer_id": 30232489, - "question_id": 23519983 - }, - { - "owner": { - "reputation": 28, - "user_id": 3302933, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/f25042331fe29187bfd5ad2a5eb461c2?s=128&d=identicon&r=PG", - "display_name": "JVercout", - "link": "http:\/\/stackoverflow.com\/users\/3302933\/jvercout" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591292, - "creation_date": 1431591292, - "answer_id": 30232487, - "question_id": 30229995 - }, - { - "owner": { - "reputation": 28575, - "user_id": 704848, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/3f9be2c2958e208c8d9b629ac43c9c42?s=128&d=identicon&r=PG", - "display_name": "EdChum", - "link": "http:\/\/stackoverflow.com\/users\/704848\/edchum" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591291, - "creation_date": 1431591291, - "answer_id": 30232486, - "question_id": 30230548 - }, - { - "owner": { - "reputation": 12492, - "user_id": 2435473, - "user_type": "registered", - "accept_rate": 60, - "profile_image": "http:\/\/i.stack.imgur.com\/GOWOI.jpg?s=128&g=1", - "display_name": "pankajparkar", - "link": "http:\/\/stackoverflow.com\/users\/2435473\/pankajparkar" - }, - "is_accepted": true, - "score": 1, - "last_activity_date": 1431591288, - "last_edit_date": 1431591288, - "creation_date": 1431590547, - "answer_id": 30232282, - "question_id": 30232179 - }, - { - "owner": { - "reputation": 58530, - "user_id": 92315, - "user_type": "registered", - "accept_rate": 50, - "profile_image": "https:\/\/www.gravatar.com\/avatar\/d2824c2017a878f6fe05db2797694608?s=128&d=identicon&r=PG", - "display_name": "Fabien Ménager", - "link": "http:\/\/stackoverflow.com\/users\/92315\/fabien-m%c3%a9nager" - }, - "is_accepted": true, - "score": 4706, - "last_activity_date": 1431591279, - "last_edit_date": 1431591279, - "creation_date": 1259067936, - "answer_id": 1789952, - "question_id": 1789945 - }, - { - "owner": { - "reputation": 341, - "user_id": 3254377, - "user_type": "registered", - "profile_image": "https:\/\/www.gravatar.com\/avatar\/108584ca35efbc205efe9160bb3d7fc7?s=128&d=identicon&r=PG&f=1", - "display_name": "wsl", - "link": "http:\/\/stackoverflow.com\/users\/3254377\/wsl" - }, - "is_accepted": false, - "score": 0, - "last_activity_date": 1431591266, - "creation_date": 1431591266, - "answer_id": 30232479, - "question_id": 30232349 - }, - { - "owner": { - "reputation": 709, - "user_id": 1519186, - "user_type": "registered", - "accept_rate": 100, - "profile_image": "http:\/\/i.stack.imgur.com\/VJWGi.jpg?s=128&g=1", - "display_name": "Marco Kerwitz", - "link": "http:\/\/stackoverflow.com\/users\/1519186\/marco-kerwitz" - }, - "is_accepted": false, - "score": 1, - "last_activity_date": 1431591260, - "last_edit_date": 1431591260, - "creation_date": 1431590862, - "answer_id": 30232366, - "question_id": 30232320 - } - ], - "has_more": true, - "quota_max": 300, - "quota_remaining": 286 -} - diff --git a/php/hashids_src.php b/php/hashids_src.php deleted file mode 100644 index fe1c590..0000000 --- a/php/hashids_src.php +++ /dev/null @@ -1,307 +0,0 @@ -salt = $salt; - - if ((int)$min_hash_length > 0) - $this->min_hash_length = (int)$min_hash_length; - - if ($alphabet) - $this->alphabet = implode('', array_unique(str_split($alphabet))); - - if (strlen($this->alphabet) < 4) - throw new Exception('Alphabet must contain at least 4 unique characters'); - - $this->seps = array(); - foreach ($this->primes as $i => $prime) { - - if (isset($this->alphabet[$prime - 1])) { - $this->seps[] = $char = $this->alphabet[$prime - 1]; - $this->alphabet = str_replace($char, ' ', $this->alphabet); - } else - break; - - } - - $this->alphabet = str_replace(' ', '', $this->alphabet); - $this->guards = array(); - - foreach (array(0, 4, 8, 12) as $index) { - if (isset($this->seps[$index])) { - $this->guards[] = $this->seps[$index]; - unset($this->seps[$index]); - } - } - - $this->alphabet = $this->_consistent_shuffle($this->alphabet, $this->salt); - $this->seps = array_merge($this->seps); - - } - - function encrypt() { - - $ret = ''; - $numbers = func_get_args(); - - if (!$numbers) - return $ret; - - foreach ($numbers as $number) { - if (!is_int($number) || $number < 0) - return $ret; - } - - return $this->_encode($numbers, $this->alphabet, $this->salt, $this->min_hash_length); - - } - - function decrypt($hash) { - - $ret = array(); - - if (!$hash || !is_string($hash)) - return $ret; - - return $this->_decode($hash); - - } - - private function _encode($numbers, $alphabet, $salt, $min_hash_length = 0) { - - $ret = ''; - - $func = __FUNCTION__; - $seps = str_split($this->_consistent_shuffle($this->seps, $numbers)); - - foreach ($numbers as $i => $number) { - - if (!$i) { - - $lottery_salt = implode('-', $numbers); - foreach ($numbers as $sub_number) - $lottery_salt .= '-' . ($sub_number + 1) * 2; - - $lottery = $this->_consistent_shuffle($alphabet, $lottery_salt); - $ret .= $lottery_char = $lottery[0]; - - $alphabet = $lottery_char . str_replace($lottery_char, '', $alphabet); - - } - - $alphabet = $this->_consistent_shuffle($alphabet, ord($lottery_char) & 12345 . $salt); - $ret .= $this->_hash($number, $alphabet); - - if ($i + 1 < sizeof($numbers)) { - $seps_index = ($number + $i) % sizeof($seps); - $ret .= $seps[$seps_index]; - } - - } - - if (strlen($ret) < $min_hash_length) { - - $first_index = 0; - foreach ($numbers as $i => $number) - $first_index += ($i + 1) * $number; - - $guard_index = $first_index % sizeof($this->guards); - $guard = $this->guards[$guard_index]; - - $ret = $guard . $ret; - if (strlen($ret) < $min_hash_length) { - - $guard_index = ($guard_index + strlen($ret)) % sizeof($this->guards); - $guard = $this->guards[$guard_index]; - - $ret .= $guard; - - } - - } - - while (strlen($ret) < $min_hash_length) { - - $pad_array = array(ord($alphabet[1]), ord($alphabet[0])); - - $pad_left = $this->func($pad_array, $alphabet, $salt); - - $pad_right = $this->func($pad_array, $alphabet, implode('', $pad_array)); - - $ret = $pad_left . $ret . $pad_right; - $excess = strlen($ret) - $min_hash_length; - - if ($excess > 0) - $ret = substr($ret, $excess / 2, $min_hash_length); - - $alphabet = $this->_consistent_shuffle($alphabet, $salt . $ret); - - } - - return $ret; - - } - - private function _decode($hash) { - - $ret = array(); - - if ($hash) { - - $original_hash = $hash; - - $hash = str_replace($this->guards, ' ', $hash); - $hash_explode = explode(' ', $hash); - - $i = 0; - if (sizeof($hash_explode) == 3 || sizeof($hash_explode) == 2) - $i = 1; - - $hash = $hash_explode[$i]; - - $hash = str_replace($this->seps, ' ', $hash); - $hash_array = explode(' ', $hash); - - foreach ($hash_array as $i => $sub_hash) { - if (strlen($sub_hash)) { - - if (!$i) { - $lottery_char = $hash[0]; - $sub_hash = substr($sub_hash, 1); - $alphabet = $lottery_char . str_replace($lottery_char, '', $this->alphabet); - } - - if (isset($alphabet) && isset($lottery_char)) { - $alphabet = $this->_consistent_shuffle($alphabet, ord($lottery_char) & 12345 . $this->salt); - $ret[] = $this->_unhash($sub_hash, $alphabet); - } - - } - } - - if (call_user_func_array([$this, 'encrypt'], $ret) != $original_hash) - $ret = array(); - - } - - return $ret; - - } - - private function _consistent_shuffle($alphabet, $salt) { - - $ret = ''; - $func = __FUNCTION__; - - if (is_array($alphabet)) - $alphabet = implode('', $alphabet); - - if (is_array($salt)) - $salt = implode('', $salt); - - if ($alphabet) { - - $alphabet_array = str_split($alphabet); - $salt_array = str_split($salt); - - $sorting_array = array(); - foreach ($salt_array as $char) - $sorting_array[] = ord($char); - - foreach ($sorting_array as $i => $int) { - - $add = true; - for ($k = $i, $j = sizeof($sorting_array) + $i - 1; $k != $j; $k++) { - - $next_index = ($k + 1) % (sizeof($sorting_array)); - - if ($add) - $sorting_array[$i] += $sorting_array[$next_index] + ($k * $i); - else - $sorting_array[$i] -= $sorting_array[$next_index]; - - $add = !$add; - - } - - $sorting_array[$i] = abs($sorting_array[$i]); - - } - - $i = 0; - while ($alphabet_array) { - - $alphabet_size = sizeof($alphabet_array); - $pos = $sorting_array[$i]; - - if ($pos >= $alphabet_size) - $pos = $pos % $alphabet_size; - - $ret .= $alphabet_array[$pos]; - unset($alphabet_array[$pos]); - $alphabet_array = array_merge($alphabet_array); - - $i++; - $i %= sizeof($sorting_array); - - } - - } - - return $ret; - - } - - private function _hash($input, $alphabet) { - - $ret = ''; - $alphabet_length = strlen($alphabet); - - do { - $rem = $input % $alphabet_length; - $input = (int)($input / $alphabet_length); - $ret = $alphabet[$rem] . $ret; - } while ($input); - - return $ret; - - } - - private function _unhash($input, $alphabet) { - - $ret = 0; - - if (strlen($input) && $alphabet) { - - $alphabet_length = strlen($alphabet); - $input_chars = str_split($input); - - foreach ($input_chars as $i => $char) { - $pos = strpos($alphabet, $char); - $ret += $pos * pow($alphabet_length, (strlen($input) - $i - 1)); - } - - } - - return $ret; - - } - -} -?> diff --git a/python/whois_v0.py b/python/whois_v0.py deleted file mode 100644 index d3d3873..0000000 --- a/python/whois_v0.py +++ /dev/null @@ -1,5 +0,0 @@ -import whois - -def show_whois(): - w = whois.whois("foo.org") - print(w) \ No newline at end of file diff --git a/python/whois_v1.py b/python/whois_v1.py deleted file mode 100644 index f61dd8f..0000000 --- a/python/whois_v1.py +++ /dev/null @@ -1,8 +0,0 @@ -import whois - -verbose = true - -def show_whois(): - if verbose: - w = whois.whois("foo.org") - print(w) \ No newline at end of file diff --git a/r/SSplotComps_r658_src.R b/r/SSplotComps_r658_src.R deleted file mode 100644 index 80431d4..0000000 --- a/r/SSplotComps_r658_src.R +++ /dev/null @@ -1,981 +0,0 @@ -SSplotComps <- - function(replist, subplots=1:11, - kind="LEN", sizemethod=1, aalyear=-1, aalbin=-1, plot=TRUE, print=FALSE, - fleets="all", fleetnames="default", sexes="all", - datonly=FALSE, samplesizeplots=TRUE, compresidplots=TRUE, bub=FALSE, - showsampsize=TRUE, showeffN=TRUE, minnbubble=8, pntscalar=2.6, - pwidth=7, pheight=7, punits="in", ptsize=12, res=300, - plotdir="default", cex.main=1, linepos=1, fitbar=FALSE, maxsize=3, - do.sqrt=TRUE, smooth=TRUE, cohortlines=c(), - labels = c("Length (cm)", #1 - "Age (yr)", #2 - "Year", #3 - "Observed sample size", #4 - "Effective sample size", #5 - "Proportion", #6 - "cm", #7 - "Frequency", #8 - "Weight", #9 - "Length", #10 - "(mt)", #11 - "(numbers x1000)", #12 - "Stdev (Age) (yr)", #13 - "Andre's conditional AAL plot, "), #14 - printmkt=TRUE,printsex=TRUE, - maxrows=6,maxcols=6,maxrows2=2,maxcols2=4,rows=1,cols=1, - fixdims=TRUE,fixdims2=FALSE,maxneff=5000,verbose=TRUE, - scalebins=FALSE,...) -{ - ################################################################################ - # SSplotComps March 23, 2011 - ################################################################################ - if(!exists("make_multifig")) stop("you are missing the function 'make_mulitifig'") - - pngfun <- function(file,caption=NA){ - png(file=file,width=pwidth,height=pheight, - units=punits,res=res,pointsize=ptsize) - plotinfo <- rbind(plotinfo,data.frame(file=file,caption=caption)) - return(plotinfo) - } - plotinfo <- NULL - - lendbase <- replist$lendbase - sizedbase <- replist$sizedbase - agedbase <- replist$agedbase - condbase <- replist$condbase - ghostagedbase <- replist$ghostagedbase - ghostlendbase <- replist$ghostlendbase - ladbase <- replist$ladbase - wadbase <- replist$wadbase - tagdbase1 <- replist$tagdbase1 - tagdbase2 <- replist$tagdbase2 - - nfleets <- replist$nfleets - nseasons <- replist$nseasons - seasfracs <- replist$seasfracs - FleetNames <- replist$FleetNames - nsexes <- replist$nsexes - - titles <- NULL - titlemkt <- "" - if(plotdir=="default") plotdir <- replist$inputs$dir - - if(fleets[1]=="all"){ - fleets <- 1:nfleets - }else{ - if(length(intersect(fleets,1:nfleets))!=length(fleets)){ - stop("Input 'fleets' should be 'all' or a vector of values between 1 and nfleets.") - } - } - if(sexes[1]=="all") sexes <- 1:2 - if(fleetnames[1]=="default") fleetnames <- FleetNames - - # a few quantities related to data type and plot number - if(kind=="LEN"){ - dbase_kind <- lendbase - kindlab=labels[1] - if(datonly){ - filenamestart <- "comp_lendat_" - titledata <- "length comp data, " - }else{ - filenamestart <- "comp_lenfit_" - titledata <- "length comps, " - } - } - if(kind=="GSTLEN"){ - dbase_kind <- ghostlendbase - kindlab=labels[1] - if(datonly){ - filenamestart <- "comp_gstlendat_" - titledata <- "ghost length comp data, " - }else{ - filenamestart <- "comp_gstlenfit_" - titledata <- "ghost length comps, " - } - } - if(kind=="SIZE"){ - dbase_kind <- sizedbase[sizedbase$method==sizemethod,] - sizeunits <- unique(dbase_kind$units) - if(length(sizeunits)>1) - stop("!error with size units in generalized size comp plots:\n", - " more than one unit value per method.\n") - if(sizeunits %in% c("in","cm")) - kindlab <- paste(labels[10]," (",sizeunits,")",sep="") - if(sizeunits %in% c("lb","kg")) - kindlab <- paste(labels[9]," (",sizeunits,")",sep="") - if(datonly){ - filenamestart <- "comp_sizedat_" - titledata <- "size comp data, " - }else{ - filenamestart <- "comp_sizefit_" - titledata <- "size comps, " - } - } - if(kind=="AGE"){ - dbase_kind <- agedbase - kindlab=labels[2] - if(datonly){ - filenamestart <- "comp_agedat_" - titledata <- "age comp data, " - }else{ - filenamestart <- "comp_agefit_" - titledata <- "age comps, " - } - } - if(kind=="cond"){ - dbase_kind <- condbase - kindlab=labels[2] - if(datonly){ - filenamestart <- "comp_condAALdat_" - titledata <- "conditional age-at-length data, " - }else{ - filenamestart <- "comp_condAALfit_" - titledata <- "conditional age-at-length, " - } - } - if(kind=="GSTAGE"){ - dbase_kind <- ghostagedbase - kindlab=labels[2] - if(datonly){ - filenamestart <- "comp_gstagedat_" - titledata <- "ghost age comp data, " - }else{ - filenamestart <- "comp_gstagefit_" - titledata <- "ghost age comps, " - } - } - if(kind=="GSTcond"){ - dbase_kind <- ghostagedbase - kindlab=labels[2] - if(datonly){ - filenamestart <- "comp_gstCAALdat_" - titledata <- "ghost conditional age-at-length data, " - }else{ - filenamestart <- "comp_gstCAALfit_" - titledata <- "ghost conditional age-at-length comps, " - } - } - if(kind=="L@A"){ - dbase_kind <- ladbase[ladbase$N!=0,] # remove values with 0 sample size - kindlab=labels[2] - filenamestart <- "comp_LAAfit_" - titledata <- "mean length at age, " - dbase_kind$SD <- dbase_kind$Lbin_lo/dbase_kind$N - } - if(kind=="W@A"){ - dbase_kind <- wadbase[wadbase$N!=0,] # remove values with 0 sample size - kindlab=labels[2] - filenamestart <- "comp_WAAfit_" - titledata <- "mean weight at age, " - } - if(!(kind%in%c("LEN","SIZE","AGE","cond","GSTAGE","GSTLEN","L@A","W@A"))) stop("Input 'kind' to SSplotComps is not right.") - - # add asterix to indicate super periods and then remove rows labeled "skip" - # would be better to somehow show the range of years, but that seems difficult - # at this point - if(any(dbase_kind$SuprPer=="Sup" & dbase_kind$Used=="skip")){ - cat("Note: removing super-period composition values labeled 'skip'\n", - " and designating super-period values with a '*'\n") - dbase_kind <- dbase_kind[dbase_kind$SuprPer=="No" | dbase_kind$Used!="skip",] - dbase_kind$YrSeasName <- paste(dbase_kind$YrSeasName,ifelse(dbase_kind$SuprPer=="Sup","*",""),sep="") - } - - # loop over fleets - for(f in fleets) - { - # check for the presence of data - if(length(dbase_kind$Obs[dbase_kind$Fleet==f])>0) - { - dbasef <- dbase_kind[dbase_kind$Fleet==f,] - testor <- length(dbasef$Gender[dbasef$Gender==1 & dbasef$Pick_gender==0 ])>0 - testor[2] <- length(dbasef$Gender[dbasef$Gender==1 & dbasef$Pick_gender %in% c(1,3)])>0 - testor[3] <- length(dbasef$Gender[dbasef$Gender==2])>0 - - # loop over genders combinations - for(k in (1:3)[testor]) - { - if(k==1){dbase_k <- dbasef[dbasef$Gender==1 & dbasef$Pick_gender==0,]} - if(k==2){dbase_k <- dbasef[dbasef$Gender==1 & dbasef$Pick_gender %in% c(1,3),]} - if(k==3){dbase_k <- dbasef[dbasef$Gender==2,]} - sex <- ifelse(k==3, 2, 1) - if(sex %in% sexes){ - # loop over partitions (discard, retain, total) - for(j in unique(dbase_k$Part)) - { - dbase <- dbase_k[dbase_k$Part==j,] - # dbase is the final data.frame used in the individual plots - # it is subset based on the kind (age, len, age-at-len), fleet, gender, and partition - - # check for multiple ageing error types within a year to plot separately - max_n_ageerr <- max(apply(table(dbase$Yr,dbase$Ageerr)>0,1,sum)) - if(max_n_ageerr > 1){ - dbase$YrSeasName <- paste(dbase$YrSeasName,"a",dbase$Ageerr,sep="") - # add fraction of season to distinguish between samples - dbase$Yr <- dbase$Yr + (1/max_n_ageerr)*(0.5/nseasons)*dbase$Ageerr - } - - ## assemble pieces of plot title - # sex - if(k==1) titlesex <- "sexes combined, " - if(k==2) titlesex <- "female, " - if(k==3) titlesex <- "male, " - titlesex <- ifelse(printsex,titlesex,"") - - # market category - if(j==0) titlemkt <- "whole catch, " - if(j==1) titlemkt <- "discard, " - if(j==2) titlemkt <- "retained, " - titlemkt <- ifelse(printmkt,titlemkt,"") - - # plot bars for data only or if input 'fitbar=TRUE' - if(datonly | fitbar) bars <- TRUE else bars <- FALSE - - # aggregating identifiers for plot titles and filenames - title_sexmkt <- paste(titlesex,titlemkt,sep="") - filename_fltsexmkt <- paste("flt",f,"sex",k,"mkt",j,sep="") - - ### subplot 1: multi-panel composition plot - if(1 %in% subplots & kind!="cond"){ # for age or length comps, but not conditional AAL - ptitle <- paste(titledata,title_sexmkt, fleetnames[f],sep="") # total title - titles <- c(ptitle,titles) # compiling list of all plot titles - tempfun <- function(ipage,...){ - # a function to combine a bunch of repeated commands - if(!(kind %in% c("GSTAGE","GSTLEN","L@A","W@A"))){ - make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr,linesx=dbase$Bin,linesy=dbase$Exp, - sampsize=dbase$N,effN=dbase$effN,showsampsize=showsampsize,showeffN=showeffN, - bars=bars,linepos=(1-datonly)*linepos, - nlegends=3,legtext=list(dbase$YrSeasName,"sampsize","effN"), - main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6], - maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - fixdims=fixdims,ipage=ipage,scalebins=scalebins,...) - } - if(kind=="GSTAGE"){ - make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr,linesx=dbase$Bin,linesy=dbase$Exp, - sampsize=dbase$N,effN=dbase$effN,showsampsize=FALSE,showeffN=FALSE, - bars=bars,linepos=(1-datonly)*linepos, - nlegends=3,legtext=list(dbase$YrSeasName,"sampsize","effN"), - main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6], - maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - fixdims=fixdims,ipage=ipage,scalebins=scalebins,...) - } - if(kind=="GSTLEN"){ - make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr,linesx=dbase$Bin,linesy=dbase$Exp, - sampsize=dbase$N,effN=dbase$effN,showsampsize=FALSE,showeffN=FALSE, - bars=bars,linepos=(1-datonly)*linepos, - nlegends=3,legtext=list(dbase$YrSeasName,"sampsize","effN"), - main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6], - maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - fixdims=fixdims,ipage=ipage,scalebins=scalebins,...) - } - if(kind %in% c("L@A","W@A")){ - make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr,linesx=dbase$Bin,linesy=dbase$Exp, - ptsSD=dbase$SD, - sampsize=dbase$N,effN=0,showsampsize=FALSE,showeffN=FALSE, - nlegends=1,legtext=list(dbase$YrSeasName), - bars=bars,linepos=(1-datonly)*linepos, - main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=ifelse(kind=="W@A",labels[9],labels[1]), - maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - fixdims=fixdims,ipage=ipage,scalebins=scalebins,...) - } - } # end tempfun - - if(plot) tempfun(ipage=0,...) - if(print){ # set up plotting to png file if required - npages <- ceiling(length(unique(dbase$Yr))/maxrows/maxcols) - for(ipage in 1:npages){ - if(npages>1) pagetext <- paste("_page",ipage,sep="") else pagetext <- "" - file <- paste(plotdir,"/",filenamestart,filename_fltsexmkt,pagetext,".png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - tempfun(ipage=ipage,...) - dev.off() - } - } - } # end subplot 1 - - # some things related to the next two bubble plots (single or multi-panel) - if(datonly){ - z <- dbase$Obs - col <- rep("black",2) - titletype <- titledata - filetype <- "bub" - allopen <- TRUE - }else{ - z <- dbase$Pearson - col <- rep("blue",2) - titletype <- "Pearson residuals, " - filetype <- "resids" - allopen <- FALSE - } - - ### subplot 2: single panel bubble plot for numbers at length or age - if(2 %in% subplots & bub & kind!="cond"){ - # get growth curves if requested - if(length(cohortlines)>0){ - growdat <- replist$endgrowth - growdatF <- growdat[growdat$Gender==1 & growdat$Morph==min(growdat$Morph[growdat$Gender==1]),] - if(nsexes > 1){ - growdatM <- growdat[growdat$Gender==2 & growdat$Morph==min(growdat$Morph[growdat$Gender==2]),] - } - } - ptitle <- paste(titletype, title_sexmkt, fleetnames[f],sep="") - ptitle <- paste(ptitle," (max=",round(max(z),digits=2),")",sep="") - titles <- c(ptitle,titles) # compiling list of all plot titles - - tempfun <- function(){ - bubble3(x=dbase$Yr, y=dbase$Bin, z=z, xlab=labels[3],ylab=kindlab,col=col, - las=1,main=ptitle,cex.main=cex.main,maxsize=pntscalar,allopen=allopen,minnbubble=minnbubble) - # add lines for growth of individual cohorts if requested - if(length(cohortlines)>0){ - for(icohort in 1:length(cohortlines)){ - cat(" Adding line for",cohortlines[icohort],"cohort\n") - if(k %in% c(1,2)) lines(growdatF$Age+cohortlines[icohort],growdatF$Len_Mid, col="red") #females - if(k %in% c(1,3)) lines(growdatM$Age+cohortlines[icohort],growdatM$Len_Mid, col="blue") #males - } - } - } - - if(plot) tempfun() - if(print){ # set up plotting to png file if required - file <- paste(plotdir,"/",filenamestart,filetype,filename_fltsexmkt,".png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - tempfun() - dev.off() # close device if png - } - } # end bubble plot - - ### subplot 3: multi-panel bubble plots for conditional age-at-length - if(3 %in% subplots & kind=="cond"){ - ptitle <- paste(titletype, title_sexmkt, fleetnames[f],sep="") - ptitle <- paste(ptitle," (max=",round(max(z),digits=2),")",sep="") - titles <- c(ptitle,titles) # compiling list of all plot titles - tempfun <- function(ipage,...){ - make_multifig(ptsx=dbase$Bin,ptsy=dbase$Lbin_mid,yr=dbase$Yr,size=z, - sampsize=dbase$N,showsampsize=showsampsize,showeffN=FALSE, - nlegends=1,legtext=list(dbase$YrSeasName), - bars=FALSE,linepos=0,main=ptitle,cex.main=cex.main, - xlab=labels[2],ylab=labels[1],ymin0=FALSE,maxrows=maxrows2,maxcols=maxcols2, - fixdims=fixdims,allopen=allopen,minnbubble=minnbubble, - ptscol=col[1],ptscol2=col[2],ipage=ipage,scalebins=scalebins,...) - } - if(plot) tempfun(ipage=0,...) - if(print){ # set up plotting to png file if required - npages <- ceiling(length(unique(dbase$Yr))/maxrows2/maxcols2) - for(ipage in 1:npages){ - if(npages>1) pagetext <- paste("_page",ipage,sep="") else pagetext <- "" - file <- paste(plotdir,"/",filenamestart,filetype,filename_fltsexmkt,pagetext,".png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - tempfun(ipage=ipage,...) - dev.off() # close device if png - } - } - } # end conditional bubble plot - ### subplots 4 and 5: multi-panel plot of point and line fit to conditional age-at-length - # and Pearson residuals of A-L key for specific years - if((4 %in% subplots | 5 %in% subplots) & aalyear[1] > 0 & kind=="cond"){ - for(y in 1:length(aalyear)){ - aalyr <- aalyear[y] - if(length(dbase$Obs[dbase$Yr==aalyr])>0){ - if(4 %in% subplots){ - ### subplot 4: multi-panel plot of fit to conditional age-at-length for specific years - ptitle <- paste(aalyr," age-at-length bin, ",title_sexmkt,fleetnames[f],sep="") - titles <- c(ptitle,titles) # compiling list of all plot titles - ydbase <- dbase[dbase$Yr==aalyr,] - lenbinlegend <- paste(ydbase$Lbin_lo,labels[7],sep="") - lenbinlegend[ydbase$Lbin_range>0] <- paste(ydbase$Lbin_lo,"-",ydbase$Lbin_hi,labels[7],sep="") - tempfun <- function(ipage,...){ # temporary function to aid repeating the big function call - make_multifig(ptsx=ydbase$Bin,ptsy=ydbase$Obs,yr=ydbase$Lbin_lo, - linesx=ydbase$Bin,linesy=ydbase$Exp, - sampsize=ydbase$N,effN=ydbase$effN,showsampsize=showsampsize,showeffN=showeffN, - nlegends=3,legtext=list(lenbinlegend,"sampsize","effN"), - bars=FALSE,linepos=linepos,main=ptitle,cex.main=cex.main, - xlab=labels[2],ylab=labels[6],maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - fixdims=fixdims,ipage=ipage,scalebins=scalebins,...) - } - if(plot) tempfun(ipage=0,...) - if(print){ - npages <- ceiling(length(unique(ydbase$Yr))/maxrows/maxcols) - for(ipage in 1:npages){ - if(npages>1) pagetext <- paste("_page",ipage,sep="") else pagetext <- "" - file <- paste(plotdir,"/",filenamestart,filename_fltsexmkt,"_",aalyr,"_",pagetext,".png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - tempfun(ipage=ipage,...) - dev.off() # close device if print - } - } - } # end if 4 in subplots - if(5 %in% subplots){ - ### subplot 5: Pearson residuals for A-L key - z <- ydbase$Pearson - ptitle <- paste(aalyr," Pearson residuals for A-L key, ",title_sexmkt,fleetnames[f],sep="") - ptitle <- paste(ptitle," (max=",round(abs(max(z)),digits=2),")",sep="") - titles <- c(ptitle,titles) # compiling list of all plot titles - tempfun <- function(){ - bubble3(x=ydbase$Bin,y=ydbase$Lbin_lo,z=z,xlab=labels[2],ylab=labels[1],col=rep("blue",2), - las=1,main=ptitle,cex.main=cex.main,maxsize=pntscalar,allopen=FALSE,minnbubble=minnbubble) - } - if(plot) tempfun() - if(print){ - file <- paste(plotdir,"/",filenamestart,"yearresids_",filename_fltsexmkt,"_",aalyr,".png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - tempfun() - dev.off() # close device if print - } - } # end if 5 in subplots - } - } - } - - ### subplot 6: multi-panel plot of point and line fit to conditional age-at-length - # for specific length bins - if(6 %in% subplots & aalbin[1] > 0){ - badbins <- setdiff(aalbin, dbase$Lbin_hi) - goodbins <- intersect(aalbin, dbase$Lbin_hi) - if(length(goodbins)>0){ - if(length(badbins)>0){ - cat("Error! the following inputs for 'aalbin' do not match the Lbin_hi values for the conditional age-at-length data:",badbins,"\n", - " the following inputs for 'aalbin' are fine:",goodbins,"\n") - } - for(ibin in 1:length(goodbins)){ # loop over good bins - ilenbin <- goodbins[ibin] - abindbase <- dbase[dbase$Lbin_hi==ilenbin,] - if(nrow(abindbase)>0){ # check for data associated with this bin - ptitle <- paste("Age-at-length ",ilenbin,labels[7],", ",title_sexmkt,fleetnames[f],sep="") - titles <- c(ptitle,titles) # compiling list of all plot titles - tempfun <- function(ipage,...){ # temporary function to aid repeating the big function call - make_multifig(ptsx=abindbase$Bin,ptsy=abindbase$Obs,yr=abindbase$Yr,linesx=abindbase$Bin,linesy=abindbase$Exp, - sampsize=abindbase$N,effN=abindbase$effN,showsampsize=showsampsize,showeffN=showeffN, - nlegends=3,legtext=list(abindbase$YrSeasName,"sampsize","effN"), - bars=bars,linepos=(1-datonly)*linepos, - main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6],maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - fixdims=fixdims,ipage=ipage,scalebins=scalebins,...) - } - if(plot) tempfun(ipage=0,...) - if(print){ - npages <- ceiling(length(unique(abindbase$Yr))/maxrows/maxcols) - for(ipage in 1:npages){ - if(npages>1) pagetext <- paste("_page",ipage,sep="") else pagetext <- "" - file <- paste(plotdir,filenamestart,filename_fltsexmkt,"_length",ilenbin,labels[7],pagetext,".png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - tempfun(ipage=ipage,...) - dev.off() # close device if print - } - } # end print - } # end if data - } # end loop over length bins - } # end if length(goodbins)>0 - } # end if plot requested - - ### subplot 7: sample size plot - if(7 %in% subplots & samplesizeplots & !datonly & !(kind %in% c("GSTAGE","GSTLEN","L@A","W@A"))){ - ptitle <- paste("N-EffN comparison, ",titledata,title_sexmkt,fleetnames[f], sep="") - titles <- c(ptitle,titles) # compiling list of all plot titles - lfitfunc <- function(){ - if(kind=="cond"){ - # trap nonrobust effective n's - # should this only be for conditional age-at-length or all plots? - dbasegood <- dbase[dbase$Obs>=0.0001 & dbase$Exp<0.99 & !is.na(dbase$effN) & dbase$effN0){ - plot(dbasegood$N,dbasegood$effN,xlab=labels[4],main=ptitle,cex.main=cex.main, - ylim=c(0,1.05*max(dbasegood$effN)),xlim=c(0,1.05*max(dbasegood$N)), - col="blue",pch=19,ylab=labels[5],xaxs="i",yaxs="i") - abline(h=0,col="grey") - abline(0,1,col="black") - # add loess smoother if there's at least 6 points with a range greater than 2 - if(smooth & length(unique(dbasegood$N)) > 6 & diff(range(dbasegood$N))>2){ - psmooth <- loess(dbasegood$effN~dbasegood$N,degree=1) - lines(psmooth$x[order(psmooth$x)],psmooth$fit[order(psmooth$x)],lwd=1.2,col="red",lty="dashed") - } - } - } - if(plot) lfitfunc() - if(print){ # set up plotting to png file if required - file <- paste(plotdir,filenamestart,"sampsize_",filename_fltsexmkt,".png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - lfitfunc() - dev.off() - } - } # end subplot 7 - - ### subplot 8: Andre's mean age and std. dev. in conditional AAL - if(8 %in% subplots & kind=="cond"){ - ptitle <- paste(labels[14], title_sexmkt, fleetnames[f],sep="") - andrefun <- function(ipage=0){ - Lens <-sort(unique(dbase$Lbin_lo)) - Yrs <- sort(unique(dbase$Yr)) - - # do some stuff so that figures that span multiple pages can be output as separate PNG files - npanels <- length(Yrs) - andrerows <- 3 - npages <- npanels/andrerows - panelrange <- 1:npanels - if(npages > 1 & ipage!=0) panelrange <- intersect(panelrange, 1:andrerows + andrerows*(ipage-1)) - Yrs2 <- Yrs[panelrange] - - par(mfrow=c(andrerows,2),mar=c(2,4,1,1),oma=c(3,0,3,0)) - for (Yr in Yrs2){ - y <- dbase[dbase$Yr==Yr,] - Size <- NULL; Size2 <- NULL - Obs <- NULL; Obs2 <- NULL - Pred <- NULL; Pred2 <- NULL - Upp <- NULL; Low <- NULL; Upp2 <- NULL; Low2 <- NULL - for (Ilen in Lens){ - z <- y[y$Lbin_lo == Ilen,] - if (length(z[,1]) > 0){ - weightsPred <- z$Exp/sum(z$Exp) - weightsObs <- z$Obs/sum(z$Obs) - ObsV <- sum(z$Bin*weightsObs) - ObsV2 <- sum(z$Bin*z$Bin*weightsObs) - PredV <- sum(z$Bin*weightsPred) - PredV2 <- sum(z$Bin*z$Bin*weightsPred) - # Overdispersion on N - # NN <- z$N[1]*0.01 # Andre did this for reasons unknown - NN <- z$N[1] - if (max(z$Obs) > 1.0e-4){ - Size <- c(Size,Ilen) - Obs <- c(Obs,ObsV) - Pred <- c(Pred,PredV) - varn <-sqrt(PredV2-PredV*PredV)/sqrt(NN) - Pred2 <- c(Pred2,varn) - varn <-sqrt(max(0,ObsV2-ObsV*ObsV))/sqrt(NN) - Obs2 <- c(Obs2,varn) - Low <- c(Low,ObsV-1.64*varn) - Upp <- c(Upp,ObsV+1.64*varn) - if (NN > 1){ - Size2 <- c(Size2,Ilen) - Low2 <- c(Low2,varn*sqrt((NN-1)/qchisq(0.95,NN))) - Upp2 <- c(Upp2,varn*sqrt((NN-1)/qchisq(0.05,NN))) - } - } - } - } - if (length(Obs) > 0){ - ymax <- max(Pred,Obs,Upp)*1.1 - plot(Size,Obs,xlab="",ylab="Age",pch=16,xlim=c(min(Lens),max(Lens)),ylim=c(0,ymax),yaxs="i") - text(x=par("usr")[1],y=.9*ymax,labels=Yr,adj=c(-.5,0),font=2,cex=1.2) - lines(Size,Pred) - lines(Size,Low,lty=3) - lines(Size,Upp,lty=3) - #title(paste("Year = ",Yr,"; Gender = ",Gender)) - - if(par("mfg")[1] & par("mfg")[2]==1){ # first plot on any new page - title(main=ptitle,xlab=labels[1],outer=TRUE,line=1) - } - ymax <- max(Obs2,Pred2)*1.1 - plot(Size,Obs2,xlab=labels[1],ylab=labels[13],pch=16,xlim=c(min(Lens),max(Lens)),ylim=c(0,ymax),yaxs="i") - lines(Size,Pred2) - lines(Size2,Low2,lty=3) - lines(Size2,Upp2,lty=3) - - - } # end if data exist - } # end loop over years - } # end andrefun - if(plot) andrefun() - if(print){ # set up plotting to png file if required - npages <- ceiling(length(unique(dbase$Yr))/3) - for(ipage in 1:npages){ - if(npages>1) pagetext <- paste("_page",ipage,sep="") else pagetext <- "" - file <- paste(plotdir,"/",filenamestart,"Andre_plots",filename_fltsexmkt,pagetext,".png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - andrefun(ipage=ipage) - dev.off() # close device if png - } # end loop over pages - } # end test for print to PNG option - } # end subplot 8 - } # end loop over partitions - } # end test for whether gender in vector of requested sexes - } # end loop over combined/not-combined genders - } # end if data - } # end loop over fleets - - ### subplot 9: by fleet aggregating across years - if(9 %in% subplots & kind!="cond") # for age or length comps, but not conditional AAL - { - dbasef <- dbase_kind[dbase_kind$Fleet %in% fleets,] - # check for the presence of data - if(nrow(dbasef)>0) - { - testor <- length(dbasef$Gender[dbasef$Gender==1 & dbasef$Pick_gender==0 ])>0 - testor[2] <- length(dbasef$Gender[dbasef$Gender==1 & dbasef$Pick_gender %in% c(1,3)])>0 - testor[3] <- length(dbasef$Gender[dbasef$Gender==2])>0 - - # loop over genders combinations - for(k in (1:3)[testor]) - { - if(k==1){dbase_k <- dbasef[dbasef$Gender==1 & dbasef$Pick_gender==0,]} - if(k==2){dbase_k <- dbasef[dbasef$Gender==1 & dbasef$Pick_gender %in% c(1,3),]} - if(k==3){dbase_k <- dbasef[dbasef$Gender==2,]} - sex <- ifelse(k==3, 2, 1) - - # loop over partitions (discard, retain, total) - for(j in unique(dbase_k$Part)) - { - # dbase is the final data.frame used in the individual plots - # it is subset based on the kind (age, len, age-at-len), fleet, gender, and partition - dbase <- dbase_k[dbase_k$Part==j,] - if(nrow(dbase)>0){ - ## assemble pieces of plot title - # sex - if(k==1) titlesex <- "sexes combined, " - if(k==2) titlesex <- "female, " - if(k==3) titlesex <- "male, " - titlesex <- ifelse(printsex,titlesex,"") - - # market category - if(j==0) titlemkt <- "whole catch, " - if(j==1) titlemkt <- "discard, " - if(j==2) titlemkt <- "retained, " - titlemkt <- ifelse(printmkt,titlemkt,"") - - # plot bars for data only or if input 'fitbar=TRUE' - if(datonly | fitbar) bars <- TRUE else bars <- FALSE - - # aggregating identifiers for plot titles and filenames - title_sexmkt <- paste(titlesex,titlemkt,sep="") - filename_fltsexmkt <- paste("sex",k,"mkt",j,sep="") - - ptitle <- paste(titledata,title_sexmkt, "aggregated across time by fleet",sep="") # total title - titles <- c(ptitle,titles) # compiling list of all plot titles - - Bins <- sort(unique(dbase$Bin)) - nbins <- length(Bins) - df <- data.frame(N=dbase$N, - effN=dbase$effN, - obs=dbase$Obs*dbase$N, - exp=dbase$Exp*dbase$N) - agg <- aggregate(x=df, by=list(bin=dbase$Bin,f=dbase$Fleet), FUN=sum) - agg <- agg[agg$f %in% fleets,] - agg$obs <- agg$obs/agg$N - agg$exp <- agg$exp/agg$N - # note: sample sizes will be different for each bin if tail compression is used - # printed sample sizes in plot will be maximum, which may or may not - # represent sum of sample sizes over all years/ages - for(f in unique(agg$f)){ - infleet <- agg$f==f - agg$N[infleet] <- max(agg$N[infleet]) - agg$effN[infleet] <- max(agg$effN[infleet]) - } - - namesvec <- fleetnames[agg$f] - if(!(kind %in% c("GSTAGE","GSTLEN","L@A","W@A"))){ - # group remaining calculations as a function - tempfun <- function(ipage,...){ - make_multifig(ptsx=agg$bin,ptsy=agg$obs,yr=agg$f, - linesx=agg$bin,linesy=agg$exp, - sampsize=agg$N,effN=agg$effN, - showsampsize=showsampsize,showeffN=showeffN, - bars=bars,linepos=(1-datonly)*linepos, - nlegends=3, - legtext=list(namesvec,"sampsize","effN"), - main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6], - maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - fixdims=fixdims2,ipage=ipage,lwd=2,scalebins=scalebins,...) - } - if(plot) tempfun(ipage=0,...) - if(print){ # set up plotting to png file if required - npages <- ceiling(length(unique(agg$f))/maxrows/maxcols) - for(ipage in 1:npages){ - if(npages>1) pagetext <- paste("_page",ipage,sep="") else pagetext <- "" - file <- paste(plotdir,filenamestart,filename_fltsexmkt,pagetext,"aggregated across time.png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - tempfun(ipage=ipage,...) - dev.off() - } - } # end print function - }else{ - # haven't configured this aggregated plot for other types - ## if(kind=="GSTAGE"){ - ## make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr,linesx=dbase$Bin,linesy=dbase$Exp, - ## sampsize=dbase$N,effN=dbase$effN,showsampsize=FALSE,showeffN=FALSE, - ## bars=bars,linepos=(1-datonly)*linepos, - ## nlegends=3,legtext=list(dbase$YrSeasName,"sampsize","effN"), - ## main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6], - ## maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - ## fixdims=fixdims,ipage=ipage,...) - ## } - ## if(kind %in% c("L@A","W@A")){ - ## make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr,linesx=dbase$Bin,linesy=dbase$Exp, - ## sampsize=dbase$N,effN=0,showsampsize=FALSE,showeffN=FALSE, - ## nlegends=1,legtext=list(dbase$YrSeasName), - ## bars=bars,linepos=(1-datonly)*linepos, - ## main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=ifelse(kind=="W@A",labels[9],labels[1]), - ## maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - ## fixdims=fixdims,ipage=ipage,...) - ## } - } - } # end test for presence of observations in this partition - } # end loop over partitions - } # end loop over combined/not-combined genders - } # end if data - } # end subplot 9 - - ### subplot 10: by fleet aggregating across years - if(10 %in% subplots & kind!="cond" & nseasons>1) # for age or length comps, but not conditional AAL - { - dbasef <- dbase_kind[dbase_kind$Fleet %in% fleets,] - # check for the presence of data - if(nrow(dbasef)>0) - { - testor <- length(dbasef$Gender[dbasef$Gender==1 & dbasef$Pick_gender==0 ])>0 - testor[2] <- length(dbasef$Gender[dbasef$Gender==1 & dbasef$Pick_gender %in% c(1,3)])>0 - testor[3] <- length(dbasef$Gender[dbasef$Gender==2])>0 - - # loop over genders combinations - for(k in (1:3)[testor]) - { - if(k==1){dbase_k <- dbasef[dbasef$Gender==1 & dbasef$Pick_gender==0,]} - if(k==2){dbase_k <- dbasef[dbasef$Gender==1 & dbasef$Pick_gender %in% c(1,3),]} - if(k==3){dbase_k <- dbasef[dbasef$Gender==2,]} - sex <- ifelse(k==3, 2, 1) - - # loop over partitions (discard, retain, total) - for(j in unique(dbase_k$Part)) - { - # dbase is the final data.frame used in the individual plots - # it is subset based on the kind (age, len, age-at-len), fleet, gender, and partition - dbase <- dbase_k[dbase_k$Part==j,] - if(nrow(dbase)>0){ - ## assemble pieces of plot title - # sex - if(k==1) titlesex <- "sexes combined, " - if(k==2) titlesex <- "female, " - if(k==3) titlesex <- "male, " - titlesex <- ifelse(printsex,titlesex,"") - - # market category - if(j==0) titlemkt <- "whole catch, " - if(j==1) titlemkt <- "discard, " - if(j==2) titlemkt <- "retained, " - titlemkt <- ifelse(printmkt,titlemkt,"") - - # plot bars for data only or if input 'fitbar=TRUE' - if(datonly | fitbar) bars <- TRUE else bars <- FALSE - - # aggregating identifiers for plot titles and filenames - title_sexmkt <- paste(titlesex,titlemkt,sep="") - filename_fltsexmkt <- paste("sex",k,"mkt",j,sep="") - - ptitle <- paste(titledata,title_sexmkt, "\naggregated within season by fleet",sep="") # total title - titles <- c(ptitle,titles) # compiling list of all plot titles - - Bins <- sort(unique(dbase$Bin)) - nbins <- length(Bins) - df <- data.frame(N=dbase$N, - effN=dbase$effN, - obs=dbase$Obs*dbase$N, - exp=dbase$Exp*dbase$N) - agg <- aggregate(x=df, by=list(bin=dbase$Bin,f=dbase$Fleet,s=dbase$Seas), FUN=sum) - agg <- agg[agg$f %in% fleets,] - if(any(agg$s<=0)){ - cat("super-periods may not work correctly in plots of aggregated comps\n") - agg <- agg[agg$s > 0,] - } - agg$obs <- agg$obs/agg$N - agg$exp <- agg$exp/agg$N - # note: sample sizes will be different for each bin if tail compression is used - # printed sample sizes in plot will be maximum, which may or may not - # represent sum of sample sizes over all years/ages - for(f in unique(agg$f)){ - for(s in unique(agg$s[agg$ff==f])){ - infleetseas <- agg$f==f & agg$s==s - agg$N[infleetseas] <- max(agg$N[infleetseas]) - agg$effN[infleetseas] <- max(agg$effN[infleetseas]) - } - } - agg$fseas <- agg$f + seasfracs[agg$s] - - namesvec <- paste(fleetnames[agg$f]," s",agg$s,sep="") - - # group remaining calculations as a function - tempfun <- function(ipage,...){ - if(!(kind %in% c("GSTAGE","GSTLEN","L@A","W@A"))){ - make_multifig(ptsx=agg$bin,ptsy=agg$obs,yr=agg$fseas, - linesx=agg$bin,linesy=agg$exp, - sampsize=agg$N,effN=agg$effN, - showsampsize=showsampsize,showeffN=showeffN, - bars=bars,linepos=(1-datonly)*linepos, - nlegends=3, - legtext=list(namesvec,"sampsize","effN"), - main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6], - maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - fixdims=fixdims2,ipage=ipage,lwd=2,scalebins=scalebins,...) - } - - # haven't configured this aggregated plot for other types - ## if(kind=="GSTAGE"){ - ## make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr,linesx=dbase$Bin,linesy=dbase$Exp, - ## sampsize=dbase$N,effN=dbase$effN,showsampsize=FALSE,showeffN=FALSE, - ## bars=bars,linepos=(1-datonly)*linepos, - ## nlegends=3,legtext=list(dbase$YrSeasName,"sampsize","effN"), - ## main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6], - ## maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - ## fixdims=fixdims,ipage=ipage,...) - ## } - ## if(kind %in% c("L@A","W@A")){ - ## make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr,linesx=dbase$Bin,linesy=dbase$Exp, - ## sampsize=dbase$N,effN=0,showsampsize=FALSE,showeffN=FALSE, - ## nlegends=1,legtext=list(dbase$YrSeasName), - ## bars=bars,linepos=(1-datonly)*linepos, - ## main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=ifelse(kind=="W@A",labels[9],labels[1]), - ## maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - ## fixdims=fixdims,ipage=ipage,...) - ## } - - } - if(plot) tempfun(ipage=0,...) - if(print){ # set up plotting to png file if required - npages <- ceiling(length(unique(agg$fseas))/maxrows/maxcols) - for(ipage in 1:npages) - { - if(npages>1) pagetext <- paste("_page",ipage,sep="") else pagetext <- "" - file <- paste(plotdir,filenamestart,filename_fltsexmkt,pagetext, - "aggregated within season.png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - tempfun(ipage=ipage,...) - dev.off() - } - } # end print function - } # end test for presence of observations in this partition - } # end loop over partitions - } # end loop over combined/not-combined genders - } # end if data - } # end subplot 10 - - ### subplot 11: by fleet aggregating across years - if(11 %in% subplots & kind!="cond" & nseasons>1){ # for age or length comps, but not conditional AAL - # loop over fleets - for(f in fleets){ - dbasef <- dbase_kind[dbase_kind$Fleet==f,] - # check for the presence of data - if(nrow(dbasef)>0){ - testor <- length(dbasef$Gender[dbasef$Gender==1 & dbasef$Pick_gender==0 ])>0 - testor[2] <- length(dbasef$Gender[dbasef$Gender==1 & dbasef$Pick_gender %in% c(1,3)])>0 - testor[3] <- length(dbasef$Gender[dbasef$Gender==2])>0 - # loop over genders combinations - for(k in (1:3)[testor]){ - if(k==1){dbase_k <- dbasef[dbasef$Gender==1 & dbasef$Pick_gender==0,]} - if(k==2){dbase_k <- dbasef[dbasef$Gender==1 & dbasef$Pick_gender %in% c(1,3),]} - if(k==3){dbase_k <- dbasef[dbasef$Gender==2,]} - sex <- ifelse(k==3, 2, 1) - - # loop over partitions (discard, retain, total) - for(j in unique(dbase_k$Part)){ - # dbase is the final data.frame used in the individual plots - # it is subset based on the kind (age, len, age-at-len), fleet, gender, and partition - dbase <- dbase_k[dbase_k$Part==j,] - if(nrow(dbase)>0){ - ## assemble pieces of plot title - # sex - if(k==1) titlesex <- "sexes combined, " - if(k==2) titlesex <- "female, " - if(k==3) titlesex <- "male, " - titlesex <- ifelse(printsex,titlesex,"") - - # market category - if(j==0) titlemkt <- "whole catch, " - if(j==1) titlemkt <- "discard, " - if(j==2) titlemkt <- "retained, " - titlemkt <- ifelse(printmkt,titlemkt,"") - - # plot bars for data only or if input 'fitbar=TRUE' - if(datonly | fitbar) bars <- TRUE else bars <- FALSE - - # aggregating identifiers for plot titles and filenames - title_sexmkt <- paste(titlesex,titlemkt,sep="") - filename_fltsexmkt <- paste("flt",f,"sex",k,"mkt",j,sep="") - - Bins <- sort(unique(dbase$Bin)) - nbins <- length(Bins) - df <- data.frame(N=dbase$N, - effN=dbase$effN, - obs=dbase$Obs*dbase$N, - exp=dbase$Exp*dbase$N) - agg <- aggregate(x=df, by=list(bin=dbase$Bin,f=dbase$Fleet,y=floor(dbase$Yr)), FUN=sum) - agg <- agg[agg$f %in% fleets,] - agg$obs <- agg$obs/agg$N - agg$exp <- agg$exp/agg$N - # note: sample sizes will be different for each bin if tail compression is used - # printed sample sizes in plot will be maximum, which may or may not - # represent sum of sample sizes over all years/ages - for(f in unique(agg$f)){ - for(y in unique(agg$y[agg$ff==f])){ - infleetyr <- agg$f==f & agg$y==y - agg$N[infleetyr] <- max(agg$N[infleetyr]) - agg$effN[infleetyr] <- max(agg$effN[infleetyr]) - } - } - agg$fy <- agg$f + agg$y/10000 - - # group remaining calculations as a function - tempfun <- function(ipage,...){ - ptitle <- paste(titledata,title_sexmkt,fleetnames[f], "\naggregated across seasons within year",sep="") # total title - if(!(kind %in% c("GSTAGE","GSTLEN","L@A","W@A"))){ - make_multifig(ptsx=agg$bin,ptsy=agg$obs,yr=agg$fy, - linesx=agg$bin,linesy=agg$exp, - sampsize=agg$N,effN=agg$effN, - showsampsize=showsampsize,showeffN=showeffN, - bars=bars,linepos=(1-datonly)*linepos, - nlegends=3, - legtext=list(agg$y,"sampsize","effN"), - main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6], - maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - fixdims=fixdims2,ipage=ipage,lwd=2,scalebins=scalebins,...) - } - - # haven't configured this aggregated plot for other types - ## if(kind=="GSTAGE"){ - ## make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr,linesx=dbase$Bin,linesy=dbase$Exp, - ## sampsize=dbase$N,effN=dbase$effN,showsampsize=FALSE,showeffN=FALSE, - ## bars=bars,linepos=(1-datonly)*linepos, - ## nlegends=3,legtext=list(dbase$YrSeasName,"sampsize","effN"), - ## main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6], - ## maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - ## fixdims=fixdims,ipage=ipage,...) - ## } - ## if(kind %in% c("L@A","W@A")){ - ## make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr,linesx=dbase$Bin,linesy=dbase$Exp, - ## sampsize=dbase$N,effN=0,showsampsize=FALSE,showeffN=FALSE, - ## nlegends=1,legtext=list(dbase$YrSeasName), - ## bars=bars,linepos=(1-datonly)*linepos, - ## main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=ifelse(kind=="W@A",labels[9],labels[1]), - ## maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - ## fixdims=fixdims,ipage=ipage,...) - ## } - - } # end tempfun - - if(plot) tempfun(ipage=0,...) - if(print){ # set up plotting to png file if required - npages <- ceiling(length(unique(agg$fy))/maxrows/maxcols) - for(ipage in 1:npages){ - if(npages>1) pagetext <- paste("_page",ipage,sep="") else pagetext <- "" - filename <- paste(plotdir,filenamestart,filename_fltsexmkt,pagetext, - "aggregated across seasons within year.png",sep="") - pngfun(file=filename) - tempfun(ipage=ipage,...) - dev.off() - } - } # end print function - } # end test for presence of observations in this partition - } # end loop over partitions - } # end loop over combined/not-combined genders - } # end if data - } # end loop over fleets - } # end subplot 11 - if(!is.null(plotinfo)) plotinfo$category <- "Comp" - return(invisible(plotinfo)) -} # end embedded SSplotComps function -########################### diff --git a/r/SSplotComps_r684_dst.R b/r/SSplotComps_r684_dst.R deleted file mode 100644 index 39df35e..0000000 --- a/r/SSplotComps_r684_dst.R +++ /dev/null @@ -1,997 +0,0 @@ -SSplotComps <- - function(replist, subplots=1:11, - kind="LEN", sizemethod=1, aalyear=-1, aalbin=-1, plot=TRUE, print=FALSE, - fleets="all", fleetnames="default", sexes="all", - datonly=FALSE, samplesizeplots=TRUE, compresidplots=TRUE, bub=FALSE, - showsampsize=TRUE, showeffN=TRUE, minnbubble=8, pntscalar=2.6, - pwidth=7, pheight=7, punits="in", ptsize=12, res=300, - plotdir="default", cex.main=1, linepos=1, fitbar=FALSE, maxsize=3, - do.sqrt=TRUE, smooth=TRUE, cohortlines=c(), - labels = c("Length (cm)", #1 - "Age (yr)", #2 - "Year", #3 - "Observed sample size", #4 - "Effective sample size", #5 - "Proportion", #6 - "cm", #7 - "Frequency", #8 - "Weight", #9 - "Length", #10 - "(mt)", #11 - "(numbers x1000)", #12 - "Stdev (Age) (yr)", #13 - "Andre's conditional AAL plot, "), #14 - printmkt=TRUE,printsex=TRUE, - maxrows=6,maxcols=6,maxrows2=2,maxcols2=4,rows=1,cols=1, - fixdims=TRUE,fixdims2=FALSE,maxneff=5000,verbose=TRUE, - scalebins=FALSE,...) -{ - ################################################################################ - # SSplotComps - ################################################################################ - if(!exists("make_multifig")) stop("you are missing the function 'make_mulitifig'") - - pngfun <- function(file,caption=NA){ - png(file=file,width=pwidth,height=pheight, - units=punits,res=res,pointsize=ptsize) - plotinfo <- rbind(plotinfo,data.frame(file=file,caption=caption)) - return(plotinfo) - } - plotinfo <- NULL - - SS_versionNumeric <- replist$SS_versionNumeric - - lendbase <- replist$lendbase - sizedbase <- replist$sizedbase - agedbase <- replist$agedbase - condbase <- replist$condbase - ghostagedbase <- replist$ghostagedbase - ghostlendbase <- replist$ghostlendbase - ladbase <- replist$ladbase - wadbase <- replist$wadbase - tagdbase1 <- replist$tagdbase1 - tagdbase2 <- replist$tagdbase2 - - nfleets <- replist$nfleets - nseasons <- replist$nseasons - seasfracs <- replist$seasfracs - FleetNames <- replist$FleetNames - nsexes <- replist$nsexes - - titles <- NULL - titlemkt <- "" - if(plotdir=="default") plotdir <- replist$inputs$dir - - if(fleets[1]=="all"){ - fleets <- 1:nfleets - }else{ - if(length(intersect(fleets,1:nfleets))!=length(fleets)){ - stop("Input 'fleets' should be 'all' or a vector of values between 1 and nfleets.") - } - } - if(sexes[1]=="all") sexes <- 1:2 - if(fleetnames[1]=="default") fleetnames <- FleetNames - - # a few quantities related to data type and plot number - if(kind=="LEN"){ - dbase_kind <- lendbase - kindlab=labels[1] - if(datonly){ - filenamestart <- "comp_lendat_" - titledata <- "length comp data, " - }else{ - filenamestart <- "comp_lenfit_" - titledata <- "length comps, " - } - } - if(kind=="GSTLEN"){ - dbase_kind <- ghostlendbase - kindlab=labels[1] - if(datonly){ - filenamestart <- "comp_gstlendat_" - titledata <- "ghost length comp data, " - }else{ - filenamestart <- "comp_gstlenfit_" - titledata <- "ghost length comps, " - } - } - if(kind=="SIZE"){ - dbase_kind <- sizedbase[sizedbase$method==sizemethod,] - sizeunits <- unique(dbase_kind$units) - if(length(sizeunits)>1) - stop("!error with size units in generalized size comp plots:\n", - " more than one unit value per method.\n") - if(sizeunits %in% c("in","cm")) - kindlab <- paste(labels[10]," (",sizeunits,")",sep="") - if(sizeunits %in% c("lb","kg")) - kindlab <- paste(labels[9]," (",sizeunits,")",sep="") - if(datonly){ - filenamestart <- "comp_sizedat_" - titledata <- "size comp data, " - }else{ - filenamestart <- "comp_sizefit_" - titledata <- "size comps, " - } - } - if(kind=="AGE"){ - dbase_kind <- agedbase - kindlab=labels[2] - if(datonly){ - filenamestart <- "comp_agedat_" - titledata <- "age comp data, " - }else{ - filenamestart <- "comp_agefit_" - titledata <- "age comps, " - } - } - if(kind=="cond"){ - dbase_kind <- condbase - kindlab=labels[2] - if(datonly){ - filenamestart <- "comp_condAALdat_" - titledata <- "conditional age-at-length data, " - }else{ - filenamestart <- "comp_condAALfit_" - titledata <- "conditional age-at-length, " - } - } - if(kind=="GSTAGE"){ - dbase_kind <- ghostagedbase - kindlab=labels[2] - if(datonly){ - filenamestart <- "comp_gstagedat_" - titledata <- "ghost age comp data, " - }else{ - filenamestart <- "comp_gstagefit_" - titledata <- "ghost age comps, " - } - } - if(kind=="GSTcond"){ - dbase_kind <- ghostagedbase - kindlab=labels[2] - if(datonly){ - filenamestart <- "comp_gstCAALdat_" - titledata <- "ghost conditional age-at-length data, " - }else{ - filenamestart <- "comp_gstCAALfit_" - titledata <- "ghost conditional age-at-length comps, " - } - } - if(kind=="L@A"){ - dbase_kind <- ladbase[ladbase$N!=0,] # remove values with 0 sample size - kindlab=labels[2] - filenamestart <- "comp_LAAfit_" - titledata <- "mean length at age, " - dbase_kind$SD <- dbase_kind$Lbin_lo/dbase_kind$N - } - if(kind=="W@A"){ - dbase_kind <- wadbase[wadbase$N!=0,] # remove values with 0 sample size - kindlab=labels[2] - filenamestart <- "comp_WAAfit_" - titledata <- "mean weight at age, " - } - if(!(kind%in%c("LEN","SIZE","AGE","cond","GSTAGE","GSTLEN","L@A","W@A"))) stop("Input 'kind' to SSplotComps is not right.") - - # add asterix to indicate super periods and then remove rows labeled "skip" - # would be better to somehow show the range of years, but that seems difficult - # at this point - if(any(dbase_kind$SuprPer=="Sup" & dbase_kind$Used=="skip")){ - cat("Note: removing super-period composition values labeled 'skip'\n", - " and designating super-period values with a '*'\n") - dbase_kind <- dbase_kind[dbase_kind$SuprPer=="No" | dbase_kind$Used!="skip",] - dbase_kind$YrSeasName <- paste(dbase_kind$YrSeasName,ifelse(dbase_kind$SuprPer=="Sup","*",""),sep="") - } - ageerr_warning <- TRUE - - # loop over fleets - for(f in fleets) - { - # check for the presence of data - if(length(dbase_kind$Obs[dbase_kind$Fleet==f])>0) - { - dbasef <- dbase_kind[dbase_kind$Fleet==f,] - testor <- length(dbasef$Gender[dbasef$Gender==1 & dbasef$Pick_gender==0 ])>0 - testor[2] <- length(dbasef$Gender[dbasef$Gender==1 & dbasef$Pick_gender %in% c(1,3)])>0 - testor[3] <- length(dbasef$Gender[dbasef$Gender==2])>0 - - # loop over genders combinations - for(k in (1:3)[testor]) - { - if(k==1){dbase_k <- dbasef[dbasef$Gender==1 & dbasef$Pick_gender==0,]} - if(k==2){dbase_k <- dbasef[dbasef$Gender==1 & dbasef$Pick_gender %in% c(1,3),]} - if(k==3){dbase_k <- dbasef[dbasef$Gender==2,]} - sex <- ifelse(k==3, 2, 1) - if(sex %in% sexes){ - # loop over partitions (discard, retain, total) - for(j in unique(dbase_k$Part)) - { - dbase <- dbase_k[dbase_k$Part==j,] - # dbase is the final data.frame used in the individual plots - # it is subset based on the kind (age, len, age-at-len), fleet, gender, and partition - - # starting with SSv3.24a, the Yr.S column is already in the output, otherwise fill it in - if(!"Yr.S" %in% names(dbase)){ - # add fraction of season to distinguish between samples - dbase$Yr.S <- dbase$Yr + (0.5/nseasons)*dbase$Seas - } - # check for multiple ageing error types within a year to plot separately - max_n_ageerr <- max(apply(table(dbase$Yr.S,dbase$Ageerr)>0,1,sum)) - - if(max_n_ageerr > 1){ - if(ageerr_warning){ - cat("Note: multiple samples with different ageing error types within fleet/year.\n", - " Plots label '2005a3' indicates ageing error type 3 for 2005 sample.\n", - " Bubble plots may be misleading with overlapping bubbles.\n") - ageerr_warning <- FALSE - } - # add 1/1000 of a year for each ageing error type to distinguish between types within a year - dbase$Yr.S <- dbase$Yr.S + dbase$Ageerr/(1000*max_n_ageerr) - dbase$YrSeasName <- paste(dbase$YrSeasName,"a",dbase$Ageerr,sep="") - } - - ## assemble pieces of plot title - # sex - if(k==1) titlesex <- "sexes combined, " - if(k==2) titlesex <- "female, " - if(k==3) titlesex <- "male, " - titlesex <- ifelse(printsex,titlesex,"") - - # market category - if(j==0) titlemkt <- "whole catch, " - if(j==1) titlemkt <- "discard, " - if(j==2) titlemkt <- "retained, " - titlemkt <- ifelse(printmkt,titlemkt,"") - - # plot bars for data only or if input 'fitbar=TRUE' - if(datonly | fitbar) bars <- TRUE else bars <- FALSE - - # aggregating identifiers for plot titles and filenames - title_sexmkt <- paste(titlesex,titlemkt,sep="") - filename_fltsexmkt <- paste("flt",f,"sex",k,"mkt",j,sep="") - - ### subplot 1: multi-panel composition plot - if(1 %in% subplots & kind!="cond"){ # for age or length comps, but not conditional AAL - ptitle <- paste(titledata,title_sexmkt, fleetnames[f],sep="") # total title - titles <- c(ptitle,titles) # compiling list of all plot titles - tempfun <- function(ipage,...){ - # a function to combine a bunch of repeated commands - if(!(kind %in% c("GSTAGE","GSTLEN","L@A","W@A"))){ - make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr.S,linesx=dbase$Bin,linesy=dbase$Exp, - sampsize=dbase$N,effN=dbase$effN,showsampsize=showsampsize,showeffN=showeffN, - bars=bars,linepos=(1-datonly)*linepos, - nlegends=3,legtext=list(dbase$YrSeasName,"sampsize","effN"), - main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6], - maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - fixdims=fixdims,ipage=ipage,scalebins=scalebins,...) - } - if(kind=="GSTAGE"){ - make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr.S,linesx=dbase$Bin,linesy=dbase$Exp, - sampsize=dbase$N,effN=dbase$effN,showsampsize=FALSE,showeffN=FALSE, - bars=bars,linepos=(1-datonly)*linepos, - nlegends=3,legtext=list(dbase$YrSeasName,"sampsize","effN"), - main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6], - maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - fixdims=fixdims,ipage=ipage,scalebins=scalebins,...) - } - if(kind=="GSTLEN"){ - make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr.S,linesx=dbase$Bin,linesy=dbase$Exp, - sampsize=dbase$N,effN=dbase$effN,showsampsize=FALSE,showeffN=FALSE, - bars=bars,linepos=(1-datonly)*linepos, - nlegends=3,legtext=list(dbase$YrSeasName,"sampsize","effN"), - main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6], - maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - fixdims=fixdims,ipage=ipage,scalebins=scalebins,...) - } - if(kind %in% c("L@A","W@A")){ - make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr.S,linesx=dbase$Bin,linesy=dbase$Exp, - ptsSD=dbase$SD, - sampsize=dbase$N,effN=0,showsampsize=FALSE,showeffN=FALSE, - nlegends=1,legtext=list(dbase$YrSeasName), - bars=bars,linepos=(1-datonly)*linepos, - main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=ifelse(kind=="W@A",labels[9],labels[1]), - maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - fixdims=fixdims,ipage=ipage,scalebins=scalebins,...) - } - } # end tempfun - - if(plot) tempfun(ipage=0,...) - if(print){ # set up plotting to png file if required - npages <- ceiling(length(unique(dbase$Yr.S))/maxrows/maxcols) - for(ipage in 1:npages){ - if(npages>1) pagetext <- paste("_page",ipage,sep="") else pagetext <- "" - file <- paste(plotdir,"/",filenamestart,filename_fltsexmkt,pagetext,".png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - tempfun(ipage=ipage,...) - dev.off() - } - } - } # end subplot 1 - - # some things related to the next two bubble plots (single or multi-panel) - if(datonly){ - z <- dbase$Obs - col <- rep("black",2) - titletype <- titledata - filetype <- "bub" - allopen <- TRUE - }else{ - z <- dbase$Pearson - col <- rep("blue",2) - titletype <- "Pearson residuals, " - filetype <- "resids" - allopen <- FALSE - } - - ### subplot 2: single panel bubble plot for numbers at length or age - if(2 %in% subplots & bub & kind!="cond"){ - # get growth curves if requested - if(length(cohortlines)>0){ - growdat <- replist$endgrowth - growdatF <- growdat[growdat$Gender==1 & growdat$Morph==min(growdat$Morph[growdat$Gender==1]),] - if(nsexes > 1){ - growdatM <- growdat[growdat$Gender==2 & growdat$Morph==min(growdat$Morph[growdat$Gender==2]),] - } - } - ptitle <- paste(titletype, title_sexmkt, fleetnames[f],sep="") - ptitle <- paste(ptitle," (max=",round(max(z),digits=2),")",sep="") - titles <- c(ptitle,titles) # compiling list of all plot titles - - tempfun <- function(){ - bubble3(x=dbase$Yr.S, y=dbase$Bin, z=z, xlab=labels[3],ylab=kindlab,col=col, - las=1,main=ptitle,cex.main=cex.main,maxsize=pntscalar,allopen=allopen,minnbubble=minnbubble) - # add lines for growth of individual cohorts if requested - if(length(cohortlines)>0){ - for(icohort in 1:length(cohortlines)){ - cat(" Adding line for",cohortlines[icohort],"cohort\n") - if(k %in% c(1,2)) lines(growdatF$Age+cohortlines[icohort],growdatF$Len_Mid, col="red") #females - if(k %in% c(1,3)) lines(growdatM$Age+cohortlines[icohort],growdatM$Len_Mid, col="blue") #males - } - } - } - - if(plot) tempfun() - if(print){ # set up plotting to png file if required - file <- paste(plotdir,"/",filenamestart,filetype,filename_fltsexmkt,".png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - tempfun() - dev.off() # close device if png - } - } # end bubble plot - - ### subplot 3: multi-panel bubble plots for conditional age-at-length - if(3 %in% subplots & kind=="cond"){ - ptitle <- paste(titletype, title_sexmkt, fleetnames[f],sep="") - ptitle <- paste(ptitle," (max=",round(max(z),digits=2),")",sep="") - titles <- c(ptitle,titles) # compiling list of all plot titles - tempfun <- function(ipage,...){ - make_multifig(ptsx=dbase$Bin,ptsy=dbase$Lbin_mid,yr=dbase$Yr.S,size=z, - sampsize=dbase$N,showsampsize=showsampsize,showeffN=FALSE, - nlegends=1,legtext=list(dbase$YrSeasName), - bars=FALSE,linepos=0,main=ptitle,cex.main=cex.main, - xlab=labels[2],ylab=labels[1],ymin0=FALSE,maxrows=maxrows2,maxcols=maxcols2, - fixdims=fixdims,allopen=allopen,minnbubble=minnbubble, - ptscol=col[1],ptscol2=col[2],ipage=ipage,scalebins=scalebins,...) - } - if(plot) tempfun(ipage=0,...) - if(print){ # set up plotting to png file if required - npages <- ceiling(length(unique(dbase$Yr.S))/maxrows2/maxcols2) - for(ipage in 1:npages){ - if(npages>1) pagetext <- paste("_page",ipage,sep="") else pagetext <- "" - file <- paste(plotdir,"/",filenamestart,filetype,filename_fltsexmkt,pagetext,".png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - tempfun(ipage=ipage,...) - dev.off() # close device if png - } - } - } # end conditional bubble plot - ### subplots 4 and 5: multi-panel plot of point and line fit to conditional age-at-length - # and Pearson residuals of A-L key for specific years - if((4 %in% subplots | 5 %in% subplots) & aalyear[1] > 0 & kind=="cond"){ - for(y in 1:length(aalyear)){ - aalyr <- aalyear[y] - if(length(dbase$Obs[dbase$Yr==aalyr])>0){ - if(4 %in% subplots){ - ### subplot 4: multi-panel plot of fit to conditional age-at-length for specific years - ptitle <- paste(aalyr," age-at-length bin, ",title_sexmkt,fleetnames[f],sep="") - titles <- c(ptitle,titles) # compiling list of all plot titles - ydbase <- dbase[dbase$Yr==aalyr,] - lenbinlegend <- paste(ydbase$Lbin_lo,labels[7],sep="") - lenbinlegend[ydbase$Lbin_range>0] <- paste(ydbase$Lbin_lo,"-",ydbase$Lbin_hi,labels[7],sep="") - tempfun <- function(ipage,...){ # temporary function to aid repeating the big function call - make_multifig(ptsx=ydbase$Bin,ptsy=ydbase$Obs,yr=ydbase$Lbin_lo, - linesx=ydbase$Bin,linesy=ydbase$Exp, - sampsize=ydbase$N,effN=ydbase$effN,showsampsize=showsampsize,showeffN=showeffN, - nlegends=3,legtext=list(lenbinlegend,"sampsize","effN"), - bars=FALSE,linepos=linepos,main=ptitle,cex.main=cex.main, - xlab=labels[2],ylab=labels[6],maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - fixdims=fixdims,ipage=ipage,scalebins=scalebins,...) - } - if(plot) tempfun(ipage=0,...) - if(print){ - npages <- ceiling(length(unique(ydbase$Yr.S))/maxrows/maxcols) - for(ipage in 1:npages){ - if(npages>1) pagetext <- paste("_page",ipage,sep="") else pagetext <- "" - file <- paste(plotdir,"/",filenamestart,filename_fltsexmkt,"_",aalyr,"_",pagetext,".png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - tempfun(ipage=ipage,...) - dev.off() # close device if print - } - } - } # end if 4 in subplots - if(5 %in% subplots){ - ### subplot 5: Pearson residuals for A-L key - z <- ydbase$Pearson - ptitle <- paste(aalyr," Pearson residuals for A-L key, ",title_sexmkt,fleetnames[f],sep="") - ptitle <- paste(ptitle," (max=",round(abs(max(z)),digits=2),")",sep="") - titles <- c(ptitle,titles) # compiling list of all plot titles - tempfun <- function(){ - bubble3(x=ydbase$Bin,y=ydbase$Lbin_lo,z=z,xlab=labels[2],ylab=labels[1],col=rep("blue",2), - las=1,main=ptitle,cex.main=cex.main,maxsize=pntscalar,allopen=FALSE,minnbubble=minnbubble) - } - if(plot) tempfun() - if(print){ - file <- paste(plotdir,"/",filenamestart,"yearresids_",filename_fltsexmkt,"_",aalyr,".png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - tempfun() - dev.off() # close device if print - } - } # end if 5 in subplots - } - } - } - - ### subplot 6: multi-panel plot of point and line fit to conditional age-at-length - # for specific length bins - if(6 %in% subplots & aalbin[1] > 0){ - badbins <- setdiff(aalbin, dbase$Lbin_hi) - goodbins <- intersect(aalbin, dbase$Lbin_hi) - if(length(goodbins)>0){ - if(length(badbins)>0){ - cat("Error! the following inputs for 'aalbin' do not match the Lbin_hi values for the conditional age-at-length data:",badbins,"\n", - " the following inputs for 'aalbin' are fine:",goodbins,"\n") - } - for(ibin in 1:length(goodbins)){ # loop over good bins - ilenbin <- goodbins[ibin] - abindbase <- dbase[dbase$Lbin_hi==ilenbin,] - if(nrow(abindbase)>0){ # check for data associated with this bin - ptitle <- paste("Age-at-length ",ilenbin,labels[7],", ",title_sexmkt,fleetnames[f],sep="") - titles <- c(ptitle,titles) # compiling list of all plot titles - tempfun <- function(ipage,...){ # temporary function to aid repeating the big function call - make_multifig(ptsx=abindbase$Bin,ptsy=abindbase$Obs,yr=abindbase$Yr.S,linesx=abindbase$Bin,linesy=abindbase$Exp, - sampsize=abindbase$N,effN=abindbase$effN,showsampsize=showsampsize,showeffN=showeffN, - nlegends=3,legtext=list(abindbase$YrSeasName,"sampsize","effN"), - bars=bars,linepos=(1-datonly)*linepos, - main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6],maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - fixdims=fixdims,ipage=ipage,scalebins=scalebins,...) - } - if(plot) tempfun(ipage=0,...) - if(print){ - npages <- ceiling(length(unique(abindbase$Yr.S))/maxrows/maxcols) - for(ipage in 1:npages){ - if(npages>1) pagetext <- paste("_page",ipage,sep="") else pagetext <- "" - file <- paste(plotdir,filenamestart,filename_fltsexmkt,"_length",ilenbin,labels[7],pagetext,".png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - tempfun(ipage=ipage,...) - dev.off() # close device if print - } - } # end print - } # end if data - } # end loop over length bins - } # end if length(goodbins)>0 - } # end if plot requested - - ### subplot 7: sample size plot - if(7 %in% subplots & samplesizeplots & !datonly & !(kind %in% c("GSTAGE","GSTLEN","L@A","W@A"))){ - ptitle <- paste("N-EffN comparison, ",titledata,title_sexmkt,fleetnames[f], sep="") - titles <- c(ptitle,titles) # compiling list of all plot titles - lfitfunc <- function(){ - if(kind=="cond"){ - # trap nonrobust effective n's - # should this only be for conditional age-at-length or all plots? - dbasegood <- dbase[dbase$Obs>=0.0001 & dbase$Exp<0.99 & !is.na(dbase$effN) & dbase$effN0){ - plot(dbasegood$N,dbasegood$effN,xlab=labels[4],main=ptitle,cex.main=cex.main, - ylim=c(0,1.05*max(dbasegood$effN)),xlim=c(0,1.05*max(dbasegood$N)), - col="blue",pch=19,ylab=labels[5],xaxs="i",yaxs="i") - abline(h=0,col="grey") - abline(0,1,col="black") - # add loess smoother if there's at least 6 points with a range greater than 2 - if(smooth & length(unique(dbasegood$N)) > 6 & diff(range(dbasegood$N))>2){ - psmooth <- loess(dbasegood$effN~dbasegood$N,degree=1) - lines(psmooth$x[order(psmooth$x)],psmooth$fit[order(psmooth$x)],lwd=1.2,col="red",lty="dashed") - } - } - } - if(plot) lfitfunc() - if(print){ # set up plotting to png file if required - file <- paste(plotdir,filenamestart,"sampsize_",filename_fltsexmkt,".png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - lfitfunc() - dev.off() - } - } # end subplot 7 - - ### subplot 8: Andre's mean age and std. dev. in conditional AAL - if(8 %in% subplots & kind=="cond"){ - ptitle <- paste(labels[14], title_sexmkt, fleetnames[f],sep="") - andrefun <- function(ipage=0){ - Lens <-sort(unique(dbase$Lbin_lo)) - Yrs <- sort(unique(dbase$Yr.S)) - - # do some stuff so that figures that span multiple pages can be output as separate PNG files - npanels <- length(Yrs) - andrerows <- 3 - npages <- npanels/andrerows - panelrange <- 1:npanels - if(npages > 1 & ipage!=0) panelrange <- intersect(panelrange, 1:andrerows + andrerows*(ipage-1)) - Yrs2 <- Yrs[panelrange] - - par(mfrow=c(andrerows,2),mar=c(2,4,1,1),oma=c(3,0,3,0)) - for (Yr in Yrs2){ - y <- dbase[dbase$Yr.S==Yr,] - Size <- NULL; Size2 <- NULL - Obs <- NULL; Obs2 <- NULL - Pred <- NULL; Pred2 <- NULL - Upp <- NULL; Low <- NULL; Upp2 <- NULL; Low2 <- NULL - for (Ilen in Lens){ - z <- y[y$Lbin_lo == Ilen,] - if (length(z[,1]) > 0){ - weightsPred <- z$Exp/sum(z$Exp) - weightsObs <- z$Obs/sum(z$Obs) - ObsV <- sum(z$Bin*weightsObs) - ObsV2 <- sum(z$Bin*z$Bin*weightsObs) - PredV <- sum(z$Bin*weightsPred) - PredV2 <- sum(z$Bin*z$Bin*weightsPred) - # Overdispersion on N - # NN <- z$N[1]*0.01 # Andre did this for reasons unknown - NN <- z$N[1] - if (max(z$Obs) > 1.0e-4){ - Size <- c(Size,Ilen) - Obs <- c(Obs,ObsV) - Pred <- c(Pred,PredV) - varn <-sqrt(PredV2-PredV*PredV)/sqrt(NN) - Pred2 <- c(Pred2,varn) - varn <-sqrt(max(0,ObsV2-ObsV*ObsV))/sqrt(NN) - Obs2 <- c(Obs2,varn) - Low <- c(Low,ObsV-1.64*varn) - Upp <- c(Upp,ObsV+1.64*varn) - if (NN > 1){ - Size2 <- c(Size2,Ilen) - Low2 <- c(Low2,varn*sqrt((NN-1)/qchisq(0.95,NN))) - Upp2 <- c(Upp2,varn*sqrt((NN-1)/qchisq(0.05,NN))) - } - } - } - } - if (length(Obs) > 0){ - ymax <- max(Pred,Obs,Upp)*1.1 - plot(Size,Obs,xlab="",ylab="Age",pch=16,xlim=c(min(Lens),max(Lens)),ylim=c(0,ymax),yaxs="i") - text(x=par("usr")[1],y=.9*ymax,labels=Yr,adj=c(-.5,0),font=2,cex=1.2) - lines(Size,Pred) - lines(Size,Low,lty=3) - lines(Size,Upp,lty=3) - #title(paste("Year = ",Yr,"; Gender = ",Gender)) - - if(par("mfg")[1] & par("mfg")[2]==1){ # first plot on any new page - title(main=ptitle,xlab=labels[1],outer=TRUE,line=1) - } - ymax <- max(Obs2,Pred2)*1.1 - plot(Size,Obs2,xlab=labels[1],ylab=labels[13],pch=16,xlim=c(min(Lens),max(Lens)),ylim=c(0,ymax),yaxs="i") - lines(Size,Pred2) - lines(Size2,Low2,lty=3) - lines(Size2,Upp2,lty=3) - - - } # end if data exist - } # end loop over years - } # end andrefun - if(plot) andrefun() - if(print){ # set up plotting to png file if required - npages <- ceiling(length(unique(dbase$Yr.S))/3) - for(ipage in 1:npages){ - if(npages>1) pagetext <- paste("_page",ipage,sep="") else pagetext <- "" - file <- paste(plotdir,"/",filenamestart,"Andre_plots",filename_fltsexmkt,pagetext,".png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - andrefun(ipage=ipage) - dev.off() # close device if png - } # end loop over pages - } # end test for print to PNG option - } # end subplot 8 - } # end loop over partitions - } # end test for whether gender in vector of requested sexes - } # end loop over combined/not-combined genders - } # end if data - } # end loop over fleets - - ### subplot 9: by fleet aggregating across years - if(9 %in% subplots & kind!="cond") # for age or length comps, but not conditional AAL - { - dbasef <- dbase_kind[dbase_kind$Fleet %in% fleets,] - # check for the presence of data - if(nrow(dbasef)>0) - { - testor <- length(dbasef$Gender[dbasef$Gender==1 & dbasef$Pick_gender==0 ])>0 - testor[2] <- length(dbasef$Gender[dbasef$Gender==1 & dbasef$Pick_gender %in% c(1,3)])>0 - testor[3] <- length(dbasef$Gender[dbasef$Gender==2])>0 - - # loop over genders combinations - for(k in (1:3)[testor]) - { - if(k==1){dbase_k <- dbasef[dbasef$Gender==1 & dbasef$Pick_gender==0,]} - if(k==2){dbase_k <- dbasef[dbasef$Gender==1 & dbasef$Pick_gender %in% c(1,3),]} - if(k==3){dbase_k <- dbasef[dbasef$Gender==2,]} - sex <- ifelse(k==3, 2, 1) - - # loop over partitions (discard, retain, total) - for(j in unique(dbase_k$Part)) - { - # dbase is the final data.frame used in the individual plots - # it is subset based on the kind (age, len, age-at-len), fleet, gender, and partition - dbase <- dbase_k[dbase_k$Part==j,] - if(nrow(dbase)>0){ - ## assemble pieces of plot title - # sex - if(k==1) titlesex <- "sexes combined, " - if(k==2) titlesex <- "female, " - if(k==3) titlesex <- "male, " - titlesex <- ifelse(printsex,titlesex,"") - - # market category - if(j==0) titlemkt <- "whole catch, " - if(j==1) titlemkt <- "discard, " - if(j==2) titlemkt <- "retained, " - titlemkt <- ifelse(printmkt,titlemkt,"") - - # plot bars for data only or if input 'fitbar=TRUE' - if(datonly | fitbar) bars <- TRUE else bars <- FALSE - - # aggregating identifiers for plot titles and filenames - title_sexmkt <- paste(titlesex,titlemkt,sep="") - filename_fltsexmkt <- paste("sex",k,"mkt",j,sep="") - - ptitle <- paste(titledata,title_sexmkt, "aggregated across time by fleet",sep="") # total title - titles <- c(ptitle,titles) # compiling list of all plot titles - - Bins <- sort(unique(dbase$Bin)) - nbins <- length(Bins) - df <- data.frame(N=dbase$N, - effN=dbase$effN, - obs=dbase$Obs*dbase$N, - exp=dbase$Exp*dbase$N) - agg <- aggregate(x=df, by=list(bin=dbase$Bin,f=dbase$Fleet), FUN=sum) - agg <- agg[agg$f %in% fleets,] - agg$obs <- agg$obs/agg$N - agg$exp <- agg$exp/agg$N - # note: sample sizes will be different for each bin if tail compression is used - # printed sample sizes in plot will be maximum, which may or may not - # represent sum of sample sizes over all years/ages - for(f in unique(agg$f)){ - infleet <- agg$f==f - agg$N[infleet] <- max(agg$N[infleet]) - agg$effN[infleet] <- max(agg$effN[infleet]) - } - - namesvec <- fleetnames[agg$f] - if(!(kind %in% c("GSTAGE","GSTLEN","L@A","W@A"))){ - # group remaining calculations as a function - tempfun <- function(ipage,...){ - make_multifig(ptsx=agg$bin,ptsy=agg$obs,yr=agg$f, - linesx=agg$bin,linesy=agg$exp, - sampsize=agg$N,effN=agg$effN, - showsampsize=showsampsize,showeffN=showeffN, - bars=bars,linepos=(1-datonly)*linepos, - nlegends=3, - legtext=list(namesvec,"sampsize","effN"), - main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6], - maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - fixdims=fixdims2,ipage=ipage,lwd=2,scalebins=scalebins,...) - } - if(plot) tempfun(ipage=0,...) - if(print){ # set up plotting to png file if required - npages <- ceiling(length(unique(agg$f))/maxrows/maxcols) - for(ipage in 1:npages){ - if(npages>1) pagetext <- paste("_page",ipage,sep="") else pagetext <- "" - file <- paste(plotdir,filenamestart,filename_fltsexmkt,pagetext,"aggregated across time.png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - tempfun(ipage=ipage,...) - dev.off() - } - } # end print function - }else{ - # haven't configured this aggregated plot for other types - ## if(kind=="GSTAGE"){ - ## make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr.S,linesx=dbase$Bin,linesy=dbase$Exp, - ## sampsize=dbase$N,effN=dbase$effN,showsampsize=FALSE,showeffN=FALSE, - ## bars=bars,linepos=(1-datonly)*linepos, - ## nlegends=3,legtext=list(dbase$YrSeasName,"sampsize","effN"), - ## main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6], - ## maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - ## fixdims=fixdims,ipage=ipage,...) - ## } - ## if(kind %in% c("L@A","W@A")){ - ## make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr.S,linesx=dbase$Bin,linesy=dbase$Exp, - ## sampsize=dbase$N,effN=0,showsampsize=FALSE,showeffN=FALSE, - ## nlegends=1,legtext=list(dbase$YrSeasName), - ## bars=bars,linepos=(1-datonly)*linepos, - ## main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=ifelse(kind=="W@A",labels[9],labels[1]), - ## maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - ## fixdims=fixdims,ipage=ipage,...) - ## } - } - } # end test for presence of observations in this partition - } # end loop over partitions - } # end loop over combined/not-combined genders - } # end if data - } # end subplot 9 - - ### subplot 10: by fleet aggregating across years within each season - if(10 %in% subplots & kind!="cond" & nseasons>1) # for age or length comps, but not conditional AAL - { - dbasef <- dbase_kind[dbase_kind$Fleet %in% fleets,] - # check for the presence of data - if(nrow(dbasef)>0) - { - testor <- length(dbasef$Gender[dbasef$Gender==1 & dbasef$Pick_gender==0 ])>0 - testor[2] <- length(dbasef$Gender[dbasef$Gender==1 & dbasef$Pick_gender %in% c(1,3)])>0 - testor[3] <- length(dbasef$Gender[dbasef$Gender==2])>0 - - # loop over genders combinations - for(k in (1:3)[testor]) - { - if(k==1){dbase_k <- dbasef[dbasef$Gender==1 & dbasef$Pick_gender==0,]} - if(k==2){dbase_k <- dbasef[dbasef$Gender==1 & dbasef$Pick_gender %in% c(1,3),]} - if(k==3){dbase_k <- dbasef[dbasef$Gender==2,]} - sex <- ifelse(k==3, 2, 1) - - # loop over partitions (discard, retain, total) - for(j in unique(dbase_k$Part)) - { - # dbase is the final data.frame used in the individual plots - # it is subset based on the kind (age, len, age-at-len), fleet, gender, and partition - dbase <- dbase_k[dbase_k$Part==j,] - if(nrow(dbase)>0){ - ## assemble pieces of plot title - # sex - if(k==1) titlesex <- "sexes combined, " - if(k==2) titlesex <- "female, " - if(k==3) titlesex <- "male, " - titlesex <- ifelse(printsex,titlesex,"") - - # market category - if(j==0) titlemkt <- "whole catch, " - if(j==1) titlemkt <- "discard, " - if(j==2) titlemkt <- "retained, " - titlemkt <- ifelse(printmkt,titlemkt,"") - - # plot bars for data only or if input 'fitbar=TRUE' - if(datonly | fitbar) bars <- TRUE else bars <- FALSE - - # aggregating identifiers for plot titles and filenames - title_sexmkt <- paste(titlesex,titlemkt,sep="") - filename_fltsexmkt <- paste("sex",k,"mkt",j,sep="") - - ptitle <- paste(titledata,title_sexmkt, "\naggregated within season by fleet",sep="") # total title - titles <- c(ptitle,titles) # compiling list of all plot titles - - Bins <- sort(unique(dbase$Bin)) - nbins <- length(Bins) - df <- data.frame(N=dbase$N, - effN=dbase$effN, - obs=dbase$Obs*dbase$N, - exp=dbase$Exp*dbase$N) - agg <- aggregate(x=df, by=list(bin=dbase$Bin,f=dbase$Fleet,s=dbase$Seas), FUN=sum) - agg <- agg[agg$f %in% fleets,] - if(any(agg$s<=0)){ - cat("super-periods may not work correctly in plots of aggregated comps\n") - agg <- agg[agg$s > 0,] - } - agg$obs <- agg$obs/agg$N - agg$exp <- agg$exp/agg$N - # note: sample sizes will be different for each bin if tail compression is used - # printed sample sizes in plot will be maximum, which may or may not - # represent sum of sample sizes over all years/ages - - for(f in unique(agg$f)){ # loop over fleets - for(s in unique(agg$s[agg$f==f])){ # loop over seasons within fleet - infleetseas <- agg$f==f & agg$s==s - agg$N[infleetseas] <- max(agg$N[infleetseas]) - agg$effN[infleetseas] <- max(agg$effN[infleetseas]) - } - } - agg$fseas <- agg$f + seasfracs[agg$s] - - namesvec <- paste(fleetnames[agg$f]," s",agg$s,sep="") - - # group remaining calculations as a function - tempfun <- function(ipage,...){ - if(!(kind %in% c("GSTAGE","GSTLEN","L@A","W@A"))){ - make_multifig(ptsx=agg$bin,ptsy=agg$obs,yr=agg$fseas, - linesx=agg$bin,linesy=agg$exp, - sampsize=agg$N,effN=agg$effN, - showsampsize=showsampsize,showeffN=showeffN, - bars=bars,linepos=(1-datonly)*linepos, - nlegends=3, - legtext=list(namesvec,"sampsize","effN"), - main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6], - maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - fixdims=fixdims2,ipage=ipage,lwd=2,scalebins=scalebins,...) - } - - # haven't configured this aggregated plot for other types - ## if(kind=="GSTAGE"){ - ## make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr.S,linesx=dbase$Bin,linesy=dbase$Exp, - ## sampsize=dbase$N,effN=dbase$effN,showsampsize=FALSE,showeffN=FALSE, - ## bars=bars,linepos=(1-datonly)*linepos, - ## nlegends=3,legtext=list(dbase$YrSeasName,"sampsize","effN"), - ## main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6], - ## maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - ## fixdims=fixdims,ipage=ipage,...) - ## } - ## if(kind %in% c("L@A","W@A")){ - ## make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr.S,linesx=dbase$Bin,linesy=dbase$Exp, - ## sampsize=dbase$N,effN=0,showsampsize=FALSE,showeffN=FALSE, - ## nlegends=1,legtext=list(dbase$YrSeasName), - ## bars=bars,linepos=(1-datonly)*linepos, - ## main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=ifelse(kind=="W@A",labels[9],labels[1]), - ## maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - ## fixdims=fixdims,ipage=ipage,...) - ## } - - } - if(plot) tempfun(ipage=0,...) - if(print){ # set up plotting to png file if required - npages <- ceiling(length(unique(agg$fseas))/maxrows/maxcols) - for(ipage in 1:npages) - { - if(npages>1) pagetext <- paste("_page",ipage,sep="") else pagetext <- "" - file <- paste(plotdir,filenamestart,filename_fltsexmkt,pagetext, - "aggregated within season.png",sep="") - caption <- paste(ptitle, " (plot ",ipage,"of ",npages,")",sep="") - plotinfo <- pngfun(file=file, caption=caption) - tempfun(ipage=ipage,...) - dev.off() - } - } # end print function - } # end test for presence of observations in this partition - } # end loop over partitions - } # end loop over combined/not-combined genders - } # end if data - } # end subplot 10 - - ### subplot 11: by fleet aggregating across years - if(11 %in% subplots & kind!="cond" & nseasons>1){ # for age or length comps, but not conditional AAL - # loop over fleets - for(f in fleets){ - dbasef <- dbase_kind[dbase_kind$Fleet==f,] - # check for the presence of data - if(nrow(dbasef)>0){ - testor <- length(dbasef$Gender[dbasef$Gender==1 & dbasef$Pick_gender==0 ])>0 - testor[2] <- length(dbasef$Gender[dbasef$Gender==1 & dbasef$Pick_gender %in% c(1,3)])>0 - testor[3] <- length(dbasef$Gender[dbasef$Gender==2])>0 - # loop over genders combinations - for(k in (1:3)[testor]){ - if(k==1){dbase_k <- dbasef[dbasef$Gender==1 & dbasef$Pick_gender==0,]} - if(k==2){dbase_k <- dbasef[dbasef$Gender==1 & dbasef$Pick_gender %in% c(1,3),]} - if(k==3){dbase_k <- dbasef[dbasef$Gender==2,]} - sex <- ifelse(k==3, 2, 1) - - # loop over partitions (discard, retain, total) - for(j in unique(dbase_k$Part)){ - # dbase is the final data.frame used in the individual plots - # it is subset based on the kind (age, len, age-at-len), fleet, gender, and partition - dbase <- dbase_k[dbase_k$Part==j,] - if(nrow(dbase)>0){ - ## assemble pieces of plot title - # sex - if(k==1) titlesex <- "sexes combined, " - if(k==2) titlesex <- "female, " - if(k==3) titlesex <- "male, " - titlesex <- ifelse(printsex,titlesex,"") - - # market category - if(j==0) titlemkt <- "whole catch, " - if(j==1) titlemkt <- "discard, " - if(j==2) titlemkt <- "retained, " - titlemkt <- ifelse(printmkt,titlemkt,"") - - # plot bars for data only or if input 'fitbar=TRUE' - if(datonly | fitbar) bars <- TRUE else bars <- FALSE - - # aggregating identifiers for plot titles and filenames - title_sexmkt <- paste(titlesex,titlemkt,sep="") - filename_fltsexmkt <- paste("flt",f,"sex",k,"mkt",j,sep="") - - Bins <- sort(unique(dbase$Bin)) - nbins <- length(Bins) - df <- data.frame(N=dbase$N, - effN=dbase$effN, - obs=dbase$Obs*dbase$N, - exp=dbase$Exp*dbase$N) - agg <- aggregate(x=df, by=list(bin=dbase$Bin,f=dbase$Fleet,y=floor(dbase$Yr.S)), FUN=sum) - agg <- agg[agg$f %in% fleets,] - agg$obs <- agg$obs/agg$N - agg$exp <- agg$exp/agg$N - # note: sample sizes will be different for each bin if tail compression is used - # printed sample sizes in plot will be maximum, which may or may not - # represent sum of sample sizes over all years/ages - for(f in unique(agg$f)){ - for(y in unique(agg$y[agg$ff==f])){ - infleetyr <- agg$f==f & agg$y==y - agg$N[infleetyr] <- max(agg$N[infleetyr]) - agg$effN[infleetyr] <- max(agg$effN[infleetyr]) - } - } - agg$fy <- agg$f + agg$y/10000 - - # group remaining calculations as a function - tempfun <- function(ipage,...){ - ptitle <- paste(titledata,title_sexmkt,fleetnames[f], "\naggregated across seasons within year",sep="") # total title - if(!(kind %in% c("GSTAGE","GSTLEN","L@A","W@A"))){ - make_multifig(ptsx=agg$bin,ptsy=agg$obs,yr=agg$fy, - linesx=agg$bin,linesy=agg$exp, - sampsize=agg$N,effN=agg$effN, - showsampsize=showsampsize,showeffN=showeffN, - bars=bars,linepos=(1-datonly)*linepos, - nlegends=3, - legtext=list(agg$y,"sampsize","effN"), - main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6], - maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - fixdims=fixdims2,ipage=ipage,lwd=2,scalebins=scalebins,...) - } - - # haven't configured this aggregated plot for other types - ## if(kind=="GSTAGE"){ - ## make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr.S,linesx=dbase$Bin,linesy=dbase$Exp, - ## sampsize=dbase$N,effN=dbase$effN,showsampsize=FALSE,showeffN=FALSE, - ## bars=bars,linepos=(1-datonly)*linepos, - ## nlegends=3,legtext=list(dbase$YrSeasName,"sampsize","effN"), - ## main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=labels[6], - ## maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - ## fixdims=fixdims,ipage=ipage,...) - ## } - ## if(kind %in% c("L@A","W@A")){ - ## make_multifig(ptsx=dbase$Bin,ptsy=dbase$Obs,yr=dbase$Yr.S,linesx=dbase$Bin,linesy=dbase$Exp, - ## sampsize=dbase$N,effN=0,showsampsize=FALSE,showeffN=FALSE, - ## nlegends=1,legtext=list(dbase$YrSeasName), - ## bars=bars,linepos=(1-datonly)*linepos, - ## main=ptitle,cex.main=cex.main,xlab=kindlab,ylab=ifelse(kind=="W@A",labels[9],labels[1]), - ## maxrows=maxrows,maxcols=maxcols,rows=rows,cols=cols, - ## fixdims=fixdims,ipage=ipage,...) - ## } - - } # end tempfun - - if(plot) tempfun(ipage=0,...) - if(print){ # set up plotting to png file if required - npages <- ceiling(length(unique(agg$fy))/maxrows/maxcols) - for(ipage in 1:npages){ - if(npages>1) pagetext <- paste("_page",ipage,sep="") else pagetext <- "" - filename <- paste(plotdir,filenamestart,filename_fltsexmkt,pagetext, - "aggregated across seasons within year.png",sep="") - pngfun(file=filename) - tempfun(ipage=ipage,...) - dev.off() - } - } # end print function - } # end test for presence of observations in this partition - } # end loop over partitions - } # end loop over combined/not-combined genders - } # end if data - } # end loop over fleets - } # end subplot 11 - if(!is.null(plotinfo)) plotinfo$category <- "Comp" - return(invisible(plotinfo)) -} # end embedded SSplotComps function -########################### diff --git a/r/TSCplot_r692_src.R b/r/TSCplot_r692_src.R deleted file mode 100644 index 99f170c..0000000 --- a/r/TSCplot_r692_src.R +++ /dev/null @@ -1,77 +0,0 @@ -TSCplot <- function(SSout, - yrs="default", - ylimBar="default", - ylimDepl=c(0,1.025), - colBar= "yellow", - cexBarLabels=1.1, - cex.axis=1.1, - space=0.0, - pchDepl=19, - colDepl="red", - lwdDepl=3, - shiftDepl = 0.25, - pchSpace = 5, - ht=4,wd=7, - labelLines=2.8, - makePDF=NULL, - makePNG=NULL, - MCMC=F) { - - ### Plots the barchart of catches and depletion trajctory for the TSC report - - if(!is.null(makePDF) & !is.null(makePNG)) stop("Cannot specify both makePDF and makePNG. Choose only one.\n") - - indVirgin <- which(SSout$timeseries$Era=="VIRG") - ind <- which(SSout$timeseries$Era=="TIME") - ind <- c(ind,max(ind)+1) - if(yrs[1]=="default") yrs <- unique(sort(SSout$timeseries$Yr[ind])) - - deadCatch <- SSplotCatch(SSout,plot=F)$totcatchmat #get catches + discards summed over areas - if(ncol(deadCatch) > 2) { #sum over fisheries - deadCatch <- cbind(apply(deadCatch[,-ncol(deadCatch)],1,sum),deadCatch[,ncol(deadCatch)]) - } - deadCatch <- deadCatch[match(yrs,deadCatch[,2]),] - rownames(deadCatch) <- yrs - - SSout$SBzero - SB <- SSout$derived_quants[substring(SSout$derived_quants$LABEL,1,4)=="SPB_",] - SB <- SB[match(as.character(yrs),substring(SB$LABEL,5)),] - - SP <- data.frame(Yr=yrs, SpawnBio=SB[,"Value"], Dead_Catch=deadCatch[,1]) - print(SP) - if(ylimBar=="default") { - ylimBar <- c(0,max(SP$Dead_Catch,na.rm=T)*1.05) - } - ind <- seq(1,nrow(SP),pchSpace) - - if(MCMC) { - if(is.null(SSout$mcmc)) stop("There is no mcmc element on the model list.\nSet MCMC=F or add in the mcmc element to the list.\n") - tmp <- SSout$mcmc - #mcmcYrs <- - } - - if(is.null(makePDF)) { windows(height=ht,width=wd) } - if(!is.null(makePDF)) { pdf(file=makePDF,width=wd,height=ht) } - if(!is.null(makePNG)) { png(file=makePNG,width=wd,height=ht,units = "in", pointsize = 10, res=300) } - par(mar=c(4,5,2,5)) - barOut <- barplot(SP$Dead_Catch, names.arg = SP$Yr, ylim=ylimBar, ylab="", col='yellow', cex=cexBarLabels, cex.axis=cex.axis, space=space,xlim=c(0,nrow(SP)),axisnames=F) - axis(1,at=barOut[ind,1],labels=yrs[ind]) - par(new=T) - xpts <- (0:(nrow(SP)-1))+shiftDepl - plot(xpts, SP$SpawnBio/SSout$SBzero, yaxt='n', yaxs='i', xaxt = 'n', ylab="", xlab="", - ylim=ylimDepl, type='l', lwd=lwdDepl, cex.axis=cex.axis, xlim=c(0,nrow(SP))) - points(xpts[ind], SP$SpawnBio[ind]/SSout$SBzero, pch=pchDepl, col=colDepl) - axis(4, at=seq(0, 1, 0.1), cex.axis=cex.axis) - mtext(c("Year","Total mortality catch (mt)", "Depletion"), side=c(1,2,4), line=labelLines, cex=1.5) - - if(!is.null(makePDF)) { - dev.off() - cat("The plot is in pdf file",makePDF,"\n") - } - if(!is.null(makePNG)) { - dev.off() - cat("The plot is in png file",makePNG,"\n") - } - - invisible(SP) -} diff --git a/r/TSCplot_r693_dst.R b/r/TSCplot_r693_dst.R deleted file mode 100644 index 0f921c9..0000000 --- a/r/TSCplot_r693_dst.R +++ /dev/null @@ -1,86 +0,0 @@ -TSCplot <- function(SSout, - yrs="default", - ylimBar="default", - ylimDepl=c(0,1.025), - colBar= "yellow", - cexBarLabels=1.1, - cex.axis=1.1, - space=0.0, - pchDepl=19, - colDepl="red", - lwdDepl=3, - shiftDepl = 0.25, - pchSpace = 5, - ht=4,wd=7, - labelLines=2.8, - makePDF=NULL, - makePNG=NULL, - MCMC=F) { - - ### Plots the barchart of catches and depletion trajctory for the TSC report - - if(!is.null(makePDF) & !is.null(makePNG)) stop("Cannot specify both makePDF and makePNG. Choose only one.\n") - - indVirgin <- which(SSout$timeseries$Era=="VIRG") - ind <- which(SSout$timeseries$Era=="TIME") - ind <- c(ind,max(ind)+1) - if(yrs[1]=="default") yrs <- unique(sort(SSout$timeseries$Yr[ind])) - - deadCatch <- SSplotCatch(SSout,plot=F,verbose=F)$totcatchmat #get catches + discards summed over areas - if(ncol(deadCatch) > 2) { #sum over fisheries - deadCatch <- cbind(apply(deadCatch[,-ncol(deadCatch)],1,sum),deadCatch[,ncol(deadCatch)]) - } - deadCatch <- deadCatch[match(yrs,deadCatch[,2]),] - rownames(deadCatch) <- yrs - - if(!MCMC) { - SBzero <- SSout$SBzero - SB <- SSout$derived_quants[substring(SSout$derived_quants$LABEL,1,4)=="SPB_",] - SB <- SB[match(as.character(yrs),substring(SB$LABEL,5)),] - depl <- SSout$derived_quants[substring(SSout$derived_quants$LABEL,1,7)=="Bratio_",] - depl <- depl[match(as.character(yrs),substring(depl$LABEL,8)),] - SP <- data.frame(Yr=yrs, SpawnBio=SB[,"Value"], Depl=depl[,"Value"],Dead_Catch=deadCatch[,1]) - } - if(MCMC) { - if(is.null(SSout$mcmc)) stop("There is no mcmc element on the model list.\nSet MCMC=F or add in the mcmc element to the list.\n") - SBzero <- median(SSout$mcmc$SPB_Virgin) - SB <- SSout$mcmc[,substring(names(SSout$mcmc),1,4)=="SPB_"] - SB <- apply(SB[,match(as.character(yrs),substring(names(SB),5))],2,median) - depl <- SSout$mcmc[,substring(names(SSout$mcmc),1,7)=="Bratio_"] - tmp1 <- match(as.character(yrs),substring(names(depl),8)) #can have an NA in it and will cause an error - tmp2 <- tmp1[!is.na(tmp1)] #remove NA's to get the medians - depl <- apply(depl[,tmp2],2,median) - depl <- depl[match(as.character(yrs),substring(names(depl),8))] - SP <- data.frame(Yr=yrs, SpawnBio=SB, Depl=depl, Dead_Catch=deadCatch[,1]) - } - - if(ylimBar=="default") { - ylimBar <- c(0,max(SP$Dead_Catch,na.rm=T)*1.05) - } - ind <- seq(1,nrow(SP),pchSpace) - - if(is.null(makePDF)) { windows(height=ht,width=wd) } - if(!is.null(makePDF)) { pdf(file=makePDF,width=wd,height=ht) } - if(!is.null(makePNG)) { png(file=makePNG,width=wd,height=ht,units = "in", pointsize = 10, res=300) } - par(mar=c(4,5,2,5)) - barOut <- barplot(SP$Dead_Catch, names.arg = SP$Yr, ylim=ylimBar, ylab="", col='yellow', cex=cexBarLabels, cex.axis=cex.axis, space=space,xlim=c(0,nrow(SP)),axisnames=F) - axis(1,at=barOut[ind,1],labels=yrs[ind]) - par(new=T) - xpts <- (0:(nrow(SP)-1))+shiftDepl - plot(xpts, SP$Depl, yaxt='n', yaxs='i', xaxt = 'n', ylab="", xlab="", - ylim=ylimDepl, type='l', lwd=lwdDepl, cex.axis=cex.axis, xlim=c(0,nrow(SP))) - points(xpts[ind], SP$Depl[ind], pch=pchDepl, col=colDepl) - axis(4, at=seq(ylimDepl[1], ylimDepl[2], 0.1), cex.axis=cex.axis) - mtext(c("Year","Total mortality catch (mt)", "Depletion"), side=c(1,2,4), line=labelLines, cex=1.5) - - if(!is.null(makePDF)) { - dev.off() - cat("The plot is in pdf file",makePDF,"\n") - } - if(!is.null(makePNG)) { - dev.off() - cat("The plot is in png file",makePNG,"\n") - } - - invisible(SP) -} diff --git a/r/tableGrob_r167_src.R b/r/tableGrob_r167_src.R deleted file mode 100644 index 88b51b8..0000000 --- a/r/tableGrob_r167_src.R +++ /dev/null @@ -1,391 +0,0 @@ -#' create a named cell grob -#' -#' @aliases textii rectii -#' @title textii -#' @param d vector of labels -#' @param gp either gpar() or list of gpar() -#' @param name -#' @param just -#' @return a function of an integer index that returns a named grob -#' @seealso \code{grid.text}, \code{grid.rect} - - -textii <- function(d, gp=gpar(), name="row-label-", just="center"){ - x <- switch(just, "center"=0.5, "right"=0.95, "left"=0.1) -## allow the correct space to fit well in a rectangle - function(ii) -textGrob(x=x, label=d[ii], just=just, gp=gp, name=paste(name, ii, sep="")) -} -rectii <- function(ii, gp, name="row-fill-"){ - function(ii) -rectGrob(gp=gp[[ii]], name=paste(name, ii, sep="")) -} - - -#' create a list of text and fill grobs and calculates the sizes for a table display -#' -#' @aliases makeTableGrobs -#' @title makeTableGrobs -#' @param content vector of text labels -#' @param rnames vector of row names -#' @param cnames vector of col names -#' @param nrow -#' @param ncol -#' @param equal.width logical -#' @param equal.height logical -#' @param gpar.coretext gpar() for inner text -#' @param gpar.corefill gpar() for inner fill -#' @param gpar.coltext gpar() for colnames text -#' @param h.odd.alpha -#' @param h.even.alpha -#' @param v.odd.alpha -#' @param v.even.alpha -#' @param gpar.colfill gpar() for colnames fill -#' @param gpar.rowtext gpar() for rownames text -#' @param gpar.rowfill gpar() for rownames fill -#' @return a list containing lists of grobs, and the dimensions for a rectangular layout - -makeTableGrobs <- function(content, rnames=NULL, cnames=NULL, - nrow, ncol, - row.just="center", col.just="center", core.just="center", - equal.width = FALSE, equal.height=FALSE, - gpar.coretext = gpar(col="black", cex=1), - gpar.coltext = gpar(col="black", cex=1, fontface="bold"), - gpar.rowtext = gpar(col="black", cex=0.8, fontface="italic"), - h.odd.alpha = 1, h.even.alpha = 1, - v.odd.alpha = 1, v.even.alpha = 1, - gpar.corefill = gpar(fill = "grey95", col="white"), - gpar.rowfill = gpar(fill = "grey90", col="white"), - gpar.colfill = gpar(fill = "grey90", col="white")) { - - ncontent <- length(content) # number of labels - nrnames <- length(rnames) # number of row labels - ncnames <- length(cnames) # number of col labels - - - ## define some functions to generate named grobs - makeOneRowname <- textii(d=rnames, gp=gpar.rowtext, name="row-label-", just=row.just) - makeOneColname <- textii(d=cnames, gp=gpar.coltext, name="col-label-", just=col.just) - makeOneLabel <- textii(d=content, gp=gpar.coretext, name="core-label-", just=core.just) - - - gp.corefillee <- gp.corefilleo <- gp.corefilloe <- gp.corefilloo <- gpar.corefill - gp.corefillee[["alpha"]] <- h.even.alpha * v.even.alpha - gp.corefilloe[["alpha"]] <- h.odd.alpha * v.even.alpha - gp.corefilloo[["alpha"]] <- h.odd.alpha * v.odd.alpha - gp.corefilleo[["alpha"]] <- h.even.alpha * v.odd.alpha - - gpar.corefill <- rep(c(rep(c(list(gp.corefillee), list(gp.corefilloe)), length.out=nrow), - rep(c(list(gp.corefilleo), list(gp.corefilloo)), length.out=nrow)), - length.out=ncontent) - - gp.rowfille <- gp.rowfillo <- gpar.rowfill - gp.rowfille[["alpha"]] <- h.even.alpha - gp.rowfillo[["alpha"]] <- h.odd.alpha - - gpar.rowfill <- rep(c(list(gp.rowfille), list(gp.rowfillo)), nrow) - - gp.colfille <- gp.colfillo <- gpar.colfill - gp.colfille[["alpha"]] <- v.even.alpha - gp.colfillo[["alpha"]] <- v.odd.alpha - - gpar.colfill <- rep(c(list(gp.colfille), list(gp.colfillo)), ncol) - - makeOneCell <- rectii(gp=gpar.corefill, name="core-fill-") - makeOneRowfill <- rectii(gp=gpar.rowfill, name="row-fill-") - makeOneColfill <- rectii(gp=gpar.colfill, name="col-fill-") - - ## in case of missing row(col) names, make a list of zeroGrobs - ## else, a list of rectGrobs with incremental names - if(is.null(rnames)){ - lrt <- lrf <- rep.grob(zeroGrob, nrow)} else { - lrt <- lapply(seq_along(rnames), makeOneRowname) # list of text grobs - lrf <- lapply(seq_along(rnames), makeOneRowfill) # list of rect grobs - } - if(is.null(cnames)){ - lct <- lcf <- rep.grob(zeroGrob, ncol)} else { - lct <- lapply(seq_along(cnames), makeOneColname) # list of text grobs - lcf <- lapply(seq_along(cnames), makeOneColfill) # list of rect grobs - } - ## the content consists of textGrobs and rectGrobs - lit <- lapply(seq_along(content), makeOneLabel) # list of text grobs - lif <- lapply(seq_along(content), makeOneCell) # list of rect grobs - - ## here the grobs are arranged and permuted in a list to fill a matrix column by column - lgt <- c(list(zeroGrob), lrt, interleaven(lct, lit, nrow)) # all labels in order - lgf <- c(list(zeroGrob), lrf, interleaven(lcf, lif, nrow)) # all labels in order - - ## retrieve the widths and heights of all textGrobs (including some zeroGrobs) - wg <- lapply(lgt, grobWidth) # list of grob widths - hg <- lapply(lgt, grobHeight) # list of grob heights - - ## concatenate this units - widths.all <- do.call(unit.c, wg) # all grob widths - heights.all <- do.call(unit.c, hg) #all grob heights - - ## matrix-like operations on units to define the table layout - widths <- colMax.units(widths.all, ncol+1) # all column widths - heights <- rowMax.units(heights.all, nrow+1) # all row heights - - ## equal width or equal height (all except rows and cols) - nwidths <- length(widths) - nheights <- length(heights) - if(equal.width) - widths <- unit.c(widths[[1]], rep(max(widths[seq(2, nwidths)]), nwidths-1)) - if(equal.height) - heights <- unit.c(heights[[1]], rep(max(heights[seq(2, nheights)]), nheights-1)) - - ## return a list containing lists of grobs, and the dimensions for a rectangular layout - list(lgt=lgt, lgf=lgf, nrow=nrow, ncol=ncol, widths=widths, heights=heights) -} - - -#' arrange text and fill grobs into a table display -#' -#' @title arrangeTableGrobs -#' @param lgt list of text label grobs -#' @param lgf list of fill label grobs -#' @param nrow nrow -#' @param ncol ncol -#' @param widths -#' @param heights -#' @param padding.h unit of horizontal margin, per cell -#' @param padding.v unit of vertical margin, per cell -#' @param just -#' @param separator colour of the border lines -#' @param show.box logical -#' @param show.csep logical separator for colnames -#' @param show.rsep logical separator for rownames -#' @return side-effect (series of grid.draw calls) - - -arrangeTableGrobs <- function(lgt, lgf, nrow, ncol, widths, heights, - padding.h = unit(4, "mm"), padding.v=unit(4, "mm"), - just=c("center", "center"), separator= "white", - show.box=FALSE, show.csep=FALSE, show.rsep=FALSE){ - - label.ind <- 1 # index running accross labels - - ## loop over columns and rows - for (ii in seq(1, ncol+1, 1)) { - for (jj in seq(1, nrow+1, 1)) { - ## push a viewport for cell (ii,jj) - pushViewport(vp=viewport( layout.pos.row=jj, layout.pos.col=ii, just=just)) - grid.draw( lgf[[label.ind]]) #draw the fill - grid.draw( lgt[[label.ind]]) #draw the text - upViewport() - - label.ind <- label.ind + 1 - } - } - - - ## draw horizontal lines, stopping or not before the names - for (ii in seq(1, nrow, 1)) - grid.segments(0, 0, 1, 0, gp=gpar(col=separator), vp=viewport( layout.pos.row=ii, - layout.pos.col=seq(1+!show.rsep, ncol+1))) - ## draw vertical lines, stopping or not before the names - for (jj in seq(1, ncol, 1)) - grid.segments(1, 0, 1, 1, gp=gpar(col=separator), vp=viewport( layout.pos.col=jj, - layout.pos.row=seq(1+!show.csep, nrow+1))) - ## draw boxes around the content and the names - if(show.box){ - grid.rect(gp=gpar(col=separator), - vp=viewport( layout.pos.col=seq(2, ncol+1), layout.pos.row=seq(2, nrow+1))) - grid.rect(gp=gpar(col=separator), - vp=viewport( layout.pos.col=seq(2, ncol+1), layout.pos.row=1)) - grid.rect(gp=gpar(col=separator), - vp=viewport( layout.pos.row=seq(2, nrow+1), layout.pos.col=1)) - } -} - - - -#' create a list of text and fill grobs and calculates the sizes for a table display -#' -#' @aliases tableGrob grid.table drawDetails.table -#' @title tableGrob -#' @param d data.frame -#' @param rows vector of row names -#' @param cols vector of col names -#' @param row.just justification of labels -#' @param col.just justification of labels -#' @param core.just justification of labels -#' @param separator colour of the border lines -#' @param show.box logical -#' @param show.csep logical separator for colnames -#' @param show.rsep logical separator for rownames -#' @param equal.width logical -#' @param equal.height logical -#' @param padding.h unit of horizontal margin, per cell -#' @param padding.v unit of vertical margin, per cell -#' @param gpar.coretext gpar() for inner text -#' @param gpar.corefill gpar() for inner fill -#' @param gpar.coltext gpar() for colnames text -#' @param h.odd.alpha -#' @param h.even.alpha -#' @param v.odd.alpha -#' @param v.even.alpha -#' @param gpar.colfill gpar() for colnames fill -#' @param gpar.rowtext gpar() for rownames text -#' @param gpar.rowfill gpar() for rownames fill -#' @return a grob of class table -#' @examples -#' -#' -#' grid.table(head(iris), h.even.alpha=1, h.odd.alpha=1, v.even.alpha=0.5, v.odd.alpha=1) -#' grid.newpage() -#' grid.draw(tableGrob(head(iris, 10), name="test")) -#' e = expression(alpha,"testing very large width", hat(beta), integral(f(x)*dx, a, b), "abc") -#' grid.edit("test", cols=e, show.rownames=F, rows=NULL, -#' gpar.corefill = gpar(fill="white", col=NA), -#' grep=TRUE, global=TRUE) -#' grid.newpage() -#' grid.draw(tableGrob(head(iris, 10), -#' show.csep=T, show.rsep=T, show.box=T, separator="grey95", name="test")) -#' grid.edit("test",gp=gpar(fontsize=8, lwd=0.1), equal.width=TRUE, grep=TRUE, global=TRUE) -#' \dontrun{ -#' pdf("test2.pdf", height=50) -#' print(system.time( grid.table(iris)) ) # about 8s here -#' dev.off() -#' } - - -tableGrob <- function(d, rows=rownames(d), cols=colnames(d), - show.rownames=TRUE, show.colnames=TRUE, - row.just="center", col.just="center", core.just="center", - separator="white", show.box=FALSE, show.csep=FALSE, show.rsep=FALSE, - equal.width = FALSE, equal.height=FALSE, - padding.h = unit(4, "mm"), padding.v=unit(4, "mm"), - gp=NULL, - gpar.coretext = gpar(col="black", cex=1), - gpar.coltext = gpar(col="black", cex=1, fontface="bold"), - gpar.rowtext = gpar(col="black", cex=0.8, fontface="italic"), - h.odd.alpha = 1, h.even.alpha = 1, - v.odd.alpha = 1, v.even.alpha = 1, - gpar.corefill = gpar(fill = "grey95", col="white"), - gpar.rowfill = gpar(fill = "grey90", col="white"), - gpar.colfill = gpar(fill = "grey90", col="white"), theme=NULL, - ...) { - - ## this needs to be done later in case a theme is used - ## if(!show.rownames) rows <- NULL - ## if(!show.colnames) cols <- NULL - - with(theme, # params provided as a list - gTree(d=d, rows= if(show.rownames) rows, cols=if(show.colnames) cols, - show.rownames=show.rownames, show.colnames=show.colnames, - row.just = row.just, col.just = col.just, core.just = core.just, - separator=separator, show.box=show.box, - show.csep=show.csep, show.rsep=show.rsep, - equal.width = equal.width, equal.height = equal.height, - padding.h = padding.h, padding.v = padding.v, - gpar.coretext = gpar.coretext, - gpar.coltext = gpar.coltext, - gpar.rowtext = gpar.rowtext, - h.odd.alpha = h.odd.alpha, h.even.alpha = h.even.alpha, - v.odd.alpha = v.odd.alpha, v.even.alpha = v.even.alpha, - gpar.corefill = gpar.corefill, - gpar.rowfill = gpar.rowfill, - gpar.colfill = gpar.colfill, - cl="table", gp=gp, ...)) - -} - - -grid.table <- function(...) - grid.draw(tableGrob(...)) - - -drawDetails.table <- function(x, recording=TRUE){ - - lg <- with(x, makeTableGrobs(as.character(as.matrix(d)), rows, cols, - nrow(d), ncol(d), - row.just = row.just, col.just = col.just, core.just = core.just, - equal.width = equal.width, equal.height = equal.height, - gpar.coretext = gpar.coretext, - gpar.coltext = gpar.coltext, - gpar.rowtext = gpar.rowtext, - h.odd.alpha = h.odd.alpha, h.even.alpha = h.even.alpha, - v.odd.alpha = v.odd.alpha, v.even.alpha = v.even.alpha, - gpar.corefill = gpar.corefill, - gpar.rowfill = gpar.rowfill, - gpar.colfill = gpar.colfill ) ) - - widthsv <- convertUnit(lg$widths + x$padding.h, "mm", valueOnly=TRUE) - heightsv <- convertUnit(lg$heights + x$padding.v, "mm", valueOnly=TRUE) - - widthsv[1] <- widthsv[1] * as.numeric(x$show.rownames) - widths <- unit(widthsv, "mm") - - heightsv[1] <- heightsv[1] * as.numeric(x$show.colnames) - heights <- unit(heightsv, "mm") - - cells = viewport(name="table.cells", layout = - grid.layout(lg$nrow+1, lg$ncol+1, width=widths, height=heights) ) - - pushViewport(cells) - tg <- arrangeTableGrobs(lg$lgt, lg$lgf, lg$nrow, lg$ncol, lg$widths, lg$heights, - padding.h = x$padding.h, padding.v = x$padding.v, - separator=x$separator, show.box=x$show.box, - show.csep=x$show.csep, show.rsep=x$show.rsep) - upViewport() -} - -updatelist <- # from reshape -function (x, y) -{ - common <- intersect(names(x), names(y)) - x[common] <- y[common] - x -} - -theme.list <- function(...) - updatelist( - list(show.rownames=FALSE, show.colnames=FALSE,separator=NA, - core.just="left", gpar.corefill=gpar(col=NA), - show.csep=FALSE, show.rsep=FALSE, - gpar.corefill = gpar(fill = NA, col=NA), - gpar.rowfill = gpar(fill = NA, col=NA), - gpar.colfill = gpar(fill = NA, col=NA)), list(...)) - -theme.blank <- function(...) - updatelist( - list(gpar.corefill=gpar(col=NA),separator=NA, - show.csep=FALSE, show.rsep=FALSE, - gpar.corefill = gpar(fill = NA, col=NA), - gpar.rowfill = gpar(fill = NA, col=NA), - gpar.colfill = gpar(fill = NA, col=NA)), list(...)) - - -theme.default <- function(...) - updatelist( - list(show.rownames=TRUE, show.colnames=TRUE, - row.just="center", col.just="center", core.just="center", - separator="white", show.box=FALSE, show.csep=FALSE, show.rsep=FALSE, - equal.width = FALSE, equal.height=FALSE, - padding.h = unit(4, "mm"), padding.v=unit(4, "mm"), - gpar.coretext = gpar(col="black", cex=1), - gpar.coltext = gpar(col="black", cex=1, fontface="bold"), - gpar.rowtext = gpar(col="black", cex=0.8, fontface="italic"), - h.odd.alpha = 1, h.even.alpha = 1, - v.odd.alpha = 1, v.even.alpha = 1, - gpar.corefill = gpar(fill = "grey95", col="white"), - gpar.rowfill = gpar(fill = "grey90", col="white"), - gpar.colfill = gpar(fill = "grey90", col="white")), list(...)) - -theme.white <- function(...) - updatelist( - list(show.rownames=TRUE, show.colnames=TRUE, - row.just="center", col.just="center", core.just="center", - separator="white", show.box=FALSE, show.csep=FALSE, show.rsep=FALSE, - equal.width = FALSE, equal.height=FALSE, - padding.h = unit(4, "mm"), padding.v=unit(4, "mm"), - gpar.coretext = gpar(col="black", cex=1), - gpar.coltext = gpar(col="black", cex=1, fontface="bold"), - gpar.rowtext = gpar(col="black", cex=0.8, fontface="italic"), - h.odd.alpha = 1, h.even.alpha = 1, - v.odd.alpha = 1, v.even.alpha = 1, - gpar.corefill = gpar(fill = NA, col=NA), - gpar.rowfill = gpar(fill = NA, col=NA), - gpar.colfill = gpar(fill = NA, col=NA)), list(...)) diff --git a/r/tableGrob_r170_dst.R b/r/tableGrob_r170_dst.R deleted file mode 100644 index 61cc1e4..0000000 --- a/r/tableGrob_r170_dst.R +++ /dev/null @@ -1,464 +0,0 @@ -#' create a named cell grob -#' -#' @aliases textii rectii -#' @title textii -#' @param d vector of labels -#' @param gp either gpar() or list of gpar() -#' @param name -#' @param just -#' @return a function of an integer index that returns a named grob -#' @seealso \code{grid.text}, \code{grid.rect} - - -textii <- function(d, gp=gpar(), name="row-label-", just="center"){ - x <- switch(just, "center"=0.5, "right"=0.95, "left"=0.1) -## allow the correct space to fit well in a rectangle - function(ii) -textGrob(x=x, label=d[ii], just=just, gp=gp, name=paste(name, ii, sep="")) -} -rectii <- function(ii, gp, name="row-fill-"){ - function(ii) -rectGrob(gp=gp[[ii]], name=paste(name, ii, sep="")) -} - - -#' create a list of text and fill grobs and calculates the sizes for a table display -#' -#' @aliases makeTableGrobs -#' @title makeTableGrobs -#' @param content vector of text labels -#' @param rnames vector of row names -#' @param cnames vector of col names -#' @param nrow -#' @param ncol -#' @param equal.width logical -#' @param equal.height logical -#' @param gpar.coretext gpar() for inner text -#' @param gpar.corefill gpar() for inner fill -#' @param gpar.coltext gpar() for colnames text -#' @param h.odd.alpha -#' @param h.even.alpha -#' @param v.odd.alpha -#' @param v.even.alpha -#' @param gpar.colfill gpar() for colnames fill -#' @param gpar.rowtext gpar() for rownames text -#' @param gpar.rowfill gpar() for rownames fill -#' @return a list containing lists of grobs, and the dimensions for a rectangular layout - -makeTableGrobs <- function(content, rnames=NULL, cnames=NULL, - nrow, ncol, - row.just="center", col.just="center", core.just="center", - equal.width = FALSE, equal.height=FALSE, - gpar.coretext = gpar(col="black", cex=1), - gpar.coltext = gpar(col="black", cex=1, fontface="bold"), - gpar.rowtext = gpar(col="black", cex=0.8, fontface="italic"), - h.odd.alpha = 1, h.even.alpha = 1, - v.odd.alpha = 1, v.even.alpha = 1, - gpar.corefill = gpar(fill = "grey95", col="white"), - gpar.rowfill = gpar(fill = "grey90", col="white"), - gpar.colfill = gpar(fill = "grey90", col="white")) { - - ncontent <- length(content) # number of labels - nrnames <- length(rnames) # number of row labels - ncnames <- length(cnames) # number of col labels - - - ## define some functions to generate named grobs - makeOneRowname <- textii(d=rnames, gp=gpar.rowtext, name="row-label-", just=row.just) - makeOneColname <- textii(d=cnames, gp=gpar.coltext, name="col-label-", just=col.just) - makeOneLabel <- textii(d=content, gp=gpar.coretext, name="core-label-", just=core.just) - - - gp.corefillee <- gp.corefilleo <- gp.corefilloe <- gp.corefilloo <- gpar.corefill - gp.corefillee[["alpha"]] <- h.even.alpha * v.even.alpha - gp.corefilloe[["alpha"]] <- h.odd.alpha * v.even.alpha - gp.corefilloo[["alpha"]] <- h.odd.alpha * v.odd.alpha - gp.corefilleo[["alpha"]] <- h.even.alpha * v.odd.alpha - - gpar.corefill <- rep(c(rep(c(list(gp.corefillee), list(gp.corefilloe)), length.out=nrow), - rep(c(list(gp.corefilleo), list(gp.corefilloo)), length.out=nrow)), - length.out=ncontent) - - gp.rowfille <- gp.rowfillo <- gpar.rowfill - gp.rowfille[["alpha"]] <- h.even.alpha - gp.rowfillo[["alpha"]] <- h.odd.alpha - - gpar.rowfill <- rep(c(list(gp.rowfille), list(gp.rowfillo)), nrow) - - gp.colfille <- gp.colfillo <- gpar.colfill - gp.colfille[["alpha"]] <- v.even.alpha - gp.colfillo[["alpha"]] <- v.odd.alpha - - gpar.colfill <- rep(c(list(gp.colfille), list(gp.colfillo)), ncol) - - makeOneCell <- rectii(gp=gpar.corefill, name="core-fill-") - makeOneRowfill <- rectii(gp=gpar.rowfill, name="row-fill-") - makeOneColfill <- rectii(gp=gpar.colfill, name="col-fill-") - - ## in case of missing row(col) names, make a list of zeroGrobs - ## else, a list of rectGrobs with incremental names - if(is.null(rnames)){ - lrt <- lrf <- rep.grob(zeroGrob, nrow)} else { - lrt <- lapply(seq_along(rnames), makeOneRowname) # list of text grobs - lrf <- lapply(seq_along(rnames), makeOneRowfill) # list of rect grobs - } - if(is.null(cnames)){ - lct <- lcf <- rep.grob(zeroGrob, ncol)} else { - lct <- lapply(seq_along(cnames), makeOneColname) # list of text grobs - lcf <- lapply(seq_along(cnames), makeOneColfill) # list of rect grobs - } - ## the content consists of textGrobs and rectGrobs - lit <- lapply(seq_along(content), makeOneLabel) # list of text grobs - lif <- lapply(seq_along(content), makeOneCell) # list of rect grobs - - ## here the grobs are arranged and permuted in a list to fill a matrix column by column - lgt <- c(list(zeroGrob), lrt, interleaven(lct, lit, nrow)) # all labels in order - lgf <- c(list(zeroGrob), lrf, interleaven(lcf, lif, nrow)) # all labels in order - - ## retrieve the widths and heights of all textGrobs (including some zeroGrobs) - wg <- lapply(lgt, grobWidth) # list of grob widths - hg <- lapply(lgt, grobHeight) # list of grob heights - - ## concatenate this units - widths.all <- do.call(unit.c, wg) # all grob widths - heights.all <- do.call(unit.c, hg) #all grob heights - - ## matrix-like operations on units to define the table layout - widths <- colMax.units(widths.all, ncol+1) # all column widths - heights <- rowMax.units(heights.all, nrow+1) # all row heights - - ## equal width or equal height (all except rows and cols) - nwidths <- length(widths) - nheights <- length(heights) - if(equal.width) - widths <- unit.c(widths[[1]], rep(max(widths[seq(2, nwidths)]), nwidths-1)) - if(equal.height) - heights <- unit.c(heights[[1]], rep(max(heights[seq(2, nheights)]), nheights-1)) - - ## return a list containing lists of grobs, and the dimensions for a rectangular layout - list(lgt=lgt, lgf=lgf, nrow=nrow, ncol=ncol, widths=widths, heights=heights) -} - - -#' arrange text and fill grobs into a table display -#' -#' @title arrangeTableGrobs -#' @param lgt list of text label grobs -#' @param lgf list of fill label grobs -#' @param nrow nrow -#' @param ncol ncol -#' @param widths -#' @param heights -#' @param padding.h unit of horizontal margin, per cell -#' @param padding.v unit of vertical margin, per cell -#' @param just -#' @param separator colour of the border lines -#' @param show.box logical -#' @param show.csep logical separator for colnames -#' @param show.rsep logical separator for rownames -#' @return side-effect (series of grid.draw calls) - - -arrangeTableGrobs <- function(lgt, lgf, nrow, ncol, widths, heights, - padding.h = unit(4, "mm"), padding.v=unit(4, "mm"), - just=c("center", "center"), separator= "white", - show.box=FALSE, show.csep=FALSE, show.rsep=FALSE){ - - label.ind <- 1 # index running accross labels - - ## loop over columns and rows - for (ii in seq(1, ncol+1, 1)) { - for (jj in seq(1, nrow+1, 1)) { - ## push a viewport for cell (ii,jj) - pushViewport(vp=viewport( layout.pos.row=jj, layout.pos.col=ii, just=just)) - grid.draw( lgf[[label.ind]]) #draw the fill - grid.draw( lgt[[label.ind]]) #draw the text - upViewport() - - label.ind <- label.ind + 1 - } - } - - - ## draw horizontal lines, stopping or not before the names - for (ii in seq(1, nrow, 1)) - grid.segments(0, 0, 1, 0, gp=gpar(col=separator), vp=viewport( layout.pos.row=ii, - layout.pos.col=seq(1+!show.rsep, ncol+1))) - ## draw vertical lines, stopping or not before the names - for (jj in seq(1, ncol, 1)) - grid.segments(1, 0, 1, 1, gp=gpar(col=separator), vp=viewport( layout.pos.col=jj, - layout.pos.row=seq(1+!show.csep, nrow+1))) - ## draw boxes around the content and the names - if(show.box){ - grid.rect(gp=gpar(col=separator), - vp=viewport( layout.pos.col=seq(2, ncol+1), layout.pos.row=seq(2, nrow+1))) - grid.rect(gp=gpar(col=separator), - vp=viewport( layout.pos.col=seq(2, ncol+1), layout.pos.row=1)) - grid.rect(gp=gpar(col=separator), - vp=viewport( layout.pos.row=seq(2, nrow+1), layout.pos.col=1)) - } -} - - - -#' create a list of text and fill grobs and calculates the sizes for a table display -#' -#' @aliases tableGrob grid.table drawDetails.table -#' @title tableGrob -#' @param d data.frame -#' @param rows vector of row names -#' @param cols vector of col names -#' @param row.just justification of labels -#' @param col.just justification of labels -#' @param core.just justification of labels -#' @param separator colour of the border lines -#' @param show.box logical -#' @param show.csep logical separator for colnames -#' @param show.rsep logical separator for rownames -#' @param equal.width logical -#' @param equal.height logical -#' @param padding.h unit of horizontal margin, per cell -#' @param padding.v unit of vertical margin, per cell -#' @param gpar.coretext gpar() for inner text -#' @param gpar.corefill gpar() for inner fill -#' @param gpar.coltext gpar() for colnames text -#' @param h.odd.alpha -#' @param h.even.alpha -#' @param v.odd.alpha -#' @param v.even.alpha -#' @param gpar.colfill gpar() for colnames fill -#' @param gpar.rowtext gpar() for rownames text -#' @param gpar.rowfill gpar() for rownames fill -#' @return a grob of class table -#' @examples -#' -#' -#' grid.table(head(iris), h.even.alpha=1, h.odd.alpha=1, v.even.alpha=0.5, v.odd.alpha=1) -#' grid.newpage() -#' grid.draw(tableGrob(head(iris, 10), name="test")) -#' e = expression(alpha,"testing very large width", hat(beta), integral(f(x)*dx, a, b), "abc") -#' grid.edit("test", cols=e, show.rownames=F, rows=NULL, -#' gpar.corefill = gpar(fill="white", col=NA), -#' grep=TRUE, global=TRUE) -#' grid.newpage() -#' grid.draw(tableGrob(head(iris, 10), -#' show.csep=T, show.rsep=T, show.box=T, separator="grey", name="test")) -#' grid.edit("test",gp=gpar(fontsize=8, lwd=2), equal.width=TRUE, grep=TRUE, global=TRUE) -#' # visualize themes -#' lg <- lapply(c("theme.blank", "theme.default", "theme.white", "theme.vertical", "theme.list", "theme.black"), -#' function(x) tableGrob(head(iris[, 1:3]), theme=get(x)())) -#' grid.newpage() -#' do.call(arrange, lg) -#' \dontrun{ -#' ## timing: a bit slow due to repeated on-the-fly calculations -#' pdf("test2.pdf", height=50) -#' print(system.time( grid.table(iris)) ) # about 12s here -#' dev.off() -#' } - - -tableGrob <- function(d, rows=rownames(d), cols=colnames(d), - show.rownames=TRUE, show.colnames=TRUE, - row.just="center", col.just="center", core.just="center", - separator="white", show.box=FALSE, show.csep=FALSE, show.rsep=FALSE, - equal.width = FALSE, equal.height=FALSE, - padding.h = unit(4, "mm"), padding.v=unit(4, "mm"), - gp=NULL, - gpar.coretext = gpar(col="black", cex=1), - gpar.coltext = gpar(col="black", cex=1, fontface="bold"), - gpar.rowtext = gpar(col="black", cex=0.8, fontface="italic"), - h.odd.alpha = 1, h.even.alpha = 1, - v.odd.alpha = 1, v.even.alpha = 1, - gpar.corefill = gpar(fill = "grey95", col="white"), - gpar.rowfill = gpar(fill = "grey90", col="white"), - gpar.colfill = gpar(fill = "grey90", col="white"), theme=NULL, - ...) { - - ## this needs to be done later in case a theme is used - ## if(!show.rownames) rows <- NULL - ## if(!show.colnames) cols <- NULL - - lg <- - with(theme, - makeTableGrobs(as.character(as.matrix(d)), rows, cols, - nrow(d), ncol(d), - row.just = row.just, col.just = col.just, core.just = core.just, - equal.width = equal.width, equal.height = equal.height, - gpar.coretext = gpar.coretext, - gpar.coltext = gpar.coltext, - gpar.rowtext = gpar.rowtext, - h.odd.alpha = h.odd.alpha, h.even.alpha = h.even.alpha, - v.odd.alpha = v.odd.alpha, v.even.alpha = v.even.alpha, - gpar.corefill = gpar.corefill, - gpar.rowfill = gpar.rowfill, - gpar.colfill = gpar.colfill )) - - with(theme, # params provided as a list - gTree(lg=lg, d=d, rows= if(show.rownames) rows, cols=if(show.colnames) cols, - show.rownames=show.rownames, show.colnames=show.colnames, - row.just = row.just, col.just = col.just, core.just = core.just, - separator=separator, show.box=show.box, - show.csep=show.csep, show.rsep=show.rsep, - equal.width = equal.width, equal.height = equal.height, - padding.h = padding.h, padding.v = padding.v, - gpar.coretext = gpar.coretext, - gpar.coltext = gpar.coltext, - gpar.rowtext = gpar.rowtext, - h.odd.alpha = h.odd.alpha, h.even.alpha = h.even.alpha, - v.odd.alpha = v.odd.alpha, v.even.alpha = v.even.alpha, - gpar.corefill = gpar.corefill, - gpar.rowfill = gpar.rowfill, - gpar.colfill = gpar.colfill, - cl="table", gp=gp, ...)) - -} - - -grid.table <- function(...) - grid.draw(tableGrob(...)) - - -drawDetails.table <- function(x, recording=TRUE){ - - lg <- with(x, makeTableGrobs(as.character(as.matrix(d)), rows, cols, - nrow(d), ncol(d), - row.just = row.just, col.just = col.just, core.just = core.just, - equal.width = equal.width, equal.height = equal.height, - gpar.coretext = gpar.coretext, - gpar.coltext = gpar.coltext, - gpar.rowtext = gpar.rowtext, - h.odd.alpha = h.odd.alpha, h.even.alpha = h.even.alpha, - v.odd.alpha = v.odd.alpha, v.even.alpha = v.even.alpha, - gpar.corefill = gpar.corefill, - gpar.rowfill = gpar.rowfill, - gpar.colfill = gpar.colfill ) ) - - widthsv <- convertUnit(lg$widths + x$padding.h, "mm", valueOnly=TRUE) - heightsv <- convertUnit(lg$heights + x$padding.v, "mm", valueOnly=TRUE) - - widthsv[1] <- widthsv[1] * as.numeric(x$show.rownames) - widths <- unit(widthsv, "mm") - - heightsv[1] <- heightsv[1] * as.numeric(x$show.colnames) - heights <- unit(heightsv, "mm") - - cells = viewport(name="table.cells", layout = - grid.layout(lg$nrow+1, lg$ncol+1, width=widths, height=heights) ) - - pushViewport(cells) - tg <- arrangeTableGrobs(lg$lgt, lg$lgf, lg$nrow, lg$ncol, lg$widths, lg$heights, - padding.h = x$padding.h, padding.v = x$padding.v, - separator=x$separator, show.box=x$show.box, - show.csep=x$show.csep, show.rsep=x$show.rsep) - upViewport() -} -widthDetails.table <- function(x){ - lg <- x$lg - widthsv <- convertUnit(lg$widths + x$padding.h, "mm", valueOnly=TRUE) - widthsv[1] <- widthsv[1] * as.numeric(x$show.rownames) - widths <- unit(widthsv, "mm") - - sum(widths) -} - -heightDetails.table <- function(x){ - lg <- x$lg - heightsv <- convertUnit(lg$heights + x$padding.v, "mm", valueOnly=TRUE) - - heightsv[1] <- heightsv[1] * as.numeric(x$show.colnames) - heights <- unit(heightsv, "mm") - - sum(heights) -} - -updatelist <- # from reshape -function (x, y) -{ - common <- intersect(names(x), names(y)) - x[common] <- y[common] - x -} - - -theme.default <- theme.grey <- function(...) - updatelist(list(show.rownames=TRUE, show.colnames=TRUE, - row.just="center", col.just="center", core.just="center", - separator="white", show.box=FALSE, show.csep=FALSE, show.rsep=FALSE, - equal.width = FALSE, equal.height=FALSE, - padding.h = unit(4, "mm"), padding.v=unit(4, "mm"), - gp=NULL, - gpar.coretext = gpar(col="black", cex=1), - gpar.coltext = gpar(col="black", cex=1, fontface="bold"), - gpar.rowtext = gpar(col="black", cex=0.8, fontface="italic"), - h.odd.alpha = 1, h.even.alpha = 1, - v.odd.alpha = 1, v.even.alpha = 1, - gpar.corefill = gpar(fill = "grey95", col="white"), - gpar.rowfill = gpar(fill = "grey90", col="white"), - gpar.colfill = gpar(fill = "grey90", col="white")), list(...)) - - -theme.list <- function(...) - updatelist( - theme.default(show.rownames=FALSE, show.colnames=FALSE,separator=NA, - core.just="left", gpar.corefill=gpar(col=NA), - show.csep=FALSE, show.rsep=FALSE, - gpar.corefill = gpar(fill = NA, col=NA), - gpar.rowfill = gpar(fill = NA, col=NA), - gpar.colfill = gpar(fill = NA, col=NA)), list(...)) - -theme.black <- function(...) - updatelist( - theme.default(show.rownames=TRUE, show.colnames=TRUE, - separator="white", - h.odd.alpha = 0.8, h.even.alpha = 0.5, - show.csep=TRUE, show.rsep=TRUE, - gpar.coretext = gpar(col="white", cex=1), - gpar.coltext = gpar(col="white", cex=1, fontface="bold"), - gpar.rowtext = gpar(col="white", cex=0.8, fontface="italic"), - gpar.corefill = gpar(fill = "black", col=NA), - gpar.rowfill = gpar(fill = "black", col=NA), - gpar.colfill = gpar(fill = "black", col=NA)), list(...)) - -theme.blank <- function(...) - updatelist( - theme.default(show.rownames=TRUE, show.colnames=TRUE, - gpar.corefill=gpar(col=NA),separator=NA, - show.csep=FALSE, show.rsep=FALSE, - gpar.corefill = gpar(fill = NA, col=NA), - gpar.rowfill = gpar(fill = NA, col=NA), - gpar.colfill = gpar(fill = NA, col=NA)), list(...)) - - -theme.vertical <- function(...) - updatelist( - theme.default(show.rownames=FALSE, show.colnames=TRUE, - row.just="center", col.just="center", core.just="center", - separator="white", show.box=FALSE, show.csep=FALSE, show.rsep=FALSE, - equal.width = FALSE, equal.height=FALSE, - padding.h = unit(4, "mm"), padding.v=unit(4, "mm"), - gpar.coretext = gpar(col="black", cex=1), - gpar.coltext = gpar(col="black", cex=1, fontface="bold"), - gpar.rowtext = gpar(col="black", cex=0.8, fontface="italic"), - h.odd.alpha = 1, h.even.alpha = 1, - v.odd.alpha = 0.5, v.even.alpha = 0, - gpar.corefill = gpar(fill = "grey90", col=NA), - gpar.rowfill = gpar(fill = "grey90", col=NA), - gpar.colfill = gpar(fill = "grey90", col=NA)), list(...)) - - -theme.white <- function(...) - updatelist( - theme.default(show.rownames=FALSE, show.colnames=TRUE, - row.just="center", col.just="center", core.just="center", - separator="white", show.box=FALSE, show.csep=FALSE, show.rsep=FALSE, - equal.width = FALSE, equal.height=FALSE, - padding.h = unit(4, "mm"), padding.v=unit(4, "mm"), - gpar.coretext = gpar(col="black", cex=1), - gpar.coltext = gpar(col="black", cex=1, fontface="bold"), - gpar.rowtext = gpar(col="black", cex=0.8, fontface="italic"), - h.odd.alpha = 0.5, h.even.alpha = 0, - v.odd.alpha = 1, v.even.alpha = 1, - gpar.corefill = gpar(fill = "grey90", col=NA), - gpar.rowfill = gpar(fill = "grey90", col=NA), - gpar.colfill = gpar(fill = "grey90", col=NA)), list(...)) - diff --git a/ruby/diggit_cli_v0.rb b/ruby/diggit_cli_v0.rb deleted file mode 100644 index d8d904e..0000000 --- a/ruby/diggit_cli_v0.rb +++ /dev/null @@ -1,327 +0,0 @@ -require 'thor' -require 'fileutils' - -require_relative 'diggit_core' - -module Diggit - - module Utils - - DONE = '[done]' - WARNING = '[warning]' - ERROR = '[error]' - INFO = '[info]' - - def diggit - @diggit = Diggit.new if @diggit.nil? - return @diggit - end - - def dump_error(e) - { name: e.class.name, message: e.to_s, backtrace: e.backtrace } - end - - def plugin_ok?(name, type) - obj = Object::const_get(name) - return obj < type - rescue NameError - return false - end - - def source_color(source_hash) - if source_hash[:log][:error].empty? - return :blue - else - return :red - end - end - - def status_color(status) - if status == DONE - return :green - else - return :red - end - end - - def say_error(msg) - say_status(ERROR, msg, :red) - end - - def say_info(msg) - say_status(INFO, msg, :blue) - end - - def say_done(msg) - say_status(DONE, msg, :green) - end - - end - - module Cli - - class SourcesCli < Thor - include Thor::Actions - include Utils - - desc 'list', "Display the list of sources." - def list - idx = 1 - diggit.sources.hashes.each do |s| - say_status("[#{s[:log][:state]}]", "#{idx}: #{s[:url]}", source_color(s)) - idx += 1 - end - errors = diggit.sources.get_all(nil, {error: true}).size - status = (errors== 0 && DONE) || ERROR - say_status(status, "listed #{diggit.sources.size} sources including #{errors} errors", status_color(status)) - end - - desc 'info [SOURCE_DEF]', "Display informations on the provided source definition (either source URL or id)." - def info(source_def) - s = diggit.sources.get(source_def) - say_status("[#{s[:log][:state]}]", "#{s[:url]}", source_color(s)) - say_status('[folder]', "#{s[:folder]}", :blue) - unless s[:log][:error].empty? - say_error("#{s[:log][:error][:name]}") - say_status('[message]', "#{s[:log][:error][:message]}", :red) - say_status('[backtrace]', "", :red) - say(s[:log][:error][:backtrace].join("\n")) - end - end - - desc "errors", "Display informations on all source that have encountered an error." - def errors - diggit.sources.get_all(nil, {error: true}).each{|s| info s[:url] } - end - - desc 'import [FILE]', "Import a list of sources from a file (one URL per line)." - def import(urls_file) - IO.readlines(urls_file).each{ |line| diggit.sources.add(line.strip) } - end - - desc "add [URL*]", "Add the provided urls to the list of sources." - def add(*urls) - urls.each{ |u| diggit.sources.add(u) } - end - - desc "rem [SOURCE_DEF*]", "Remove the sources correspondign to the provided source definitions (id or URL) from the list of sources." - def rem(*sources_defs) - sources_defs.each { |s| diggit.sources.rem(s) } - end - end - - class AddonsCli < Thor - include Thor::Actions - include Utils - - desc "add [ADDON*]", "Add the provided addons to the list of active addons." - def add(*addons) - addons.each do |a| - if plugin_ok?(a, Addon) - diggit.config.add_addon(a) - else - say_error("error loading addon #{a}") - end - end - end - - desc "rem [ADDON*]", "Remove the provided addons from the list of active addons." - def rem(*addons) - addons.each{ |a| diggit.config.rem_addon(a) } - end - - end - - class JoinsCli < Thor - include Thor::Actions - include Utils - - desc "add [JOIN*]", "Add the provided joins to the list of active joins." - def add(*joins) - joins.each do |j| - if plugin_ok?(j, Join) - diggit.config.add_join(j) - else - say_error("error loading join #{j}") - end - end - end - - desc "rem [JOIN*]", "Remove the provided joins from the list of active joins." - def rem(*joins) - joins.each{ |j| diggit.config.rem_join(j) } - end - - end - - class AnalysesCli < Thor - include Thor::Actions - include Utils - - desc "add [ANALYSIS*]", "Add the provided analyses to the list of active analyses." - def add(*analyses) - analyses.each do |a| - if plugin_ok?(a, Analysis) - diggit.config.add_analysis(a) - else - say_error("error loading analysis #{a}") - end - end - end - - desc "rem [ANALYSIS*]", "Remove the provided analyses from the list of active analyses." - def rem(*analyses) - analyses.each{ |a| diggit.config.rem_analysis(a) } - end - - end - - class PerformCli < Thor - include Thor::Actions - include Utils - - desc "clones [SOURCE_DEFS*]", "Clone the sources corresponding to the provided source definitions (id or URL). Clone all sources if no source definitions are provided." - def clones(*source_defs) - diggit.sources.get_all(source_defs, {state: :new}).each do |s| - begin - if File.exist?(s[:folder]) - Rugged::Repository::new(s[:folder]) - else - Rugged::Repository::clone_at(s[:url], s[:folder]) - end - rescue => e - s[:log][:error] = dump_error(e) - say_error("error cloning #{s[:url]}") - else - s[:log][:state] = :cloned - s[:log][:error] = {} - say_done("#{s[:url]} cloned") - ensure - diggit.sources.update(s) - end - end - end - - desc "analyses [SOURCE_DEFS*]", "Perform the configured analyses to the sources corresponding to the provided source definitions (id or URL). Analyze all sources if no source definitions are provided." - def analyses(*source_defs) - addons = diggit.config.load_addons - diggit.sources.get_all(source_defs, {state: :cloned}).each do |s| - FileUtils.cd(s[:folder]) - globs = {} - performed_analyses = [] - begin - repo = Rugged::Repository.new('.') - diggit.config.load_analyses(s[:url], repo, addons, globs).each do |a| - performed_analyses << a.class.to_s - a.run - end - rescue => e - s[:log][:error] = dump_error(e) - s[:log][:analyses] = performed_analyses[1..-2] - say_error("error performing #{performed_analyses.last} on #{s[:url]}") - else - s[:log][:analyses] = performed_analyses - s[:log][:state] = :finished - s[:log][:error] = {} - say_done("source #{s[:url]} analyzed") - ensure - FileUtils.cd(diggit.root) - diggit.sources.update(s) - end - end - end - - desc "joins", "Perform the configured joins." - def joins - addons = diggit.config.load_addons - globs = {} - diggit.config.load_joins(diggit.sources.get_all([], {state: :finished, error: false}), addons, globs).each{ |j| j.run } - say_done("joins performed") - end - - end - - class CleanCli < Thor - include Thor::Actions - include Utils - - desc "analyses", "Clean the configured analyzes on the provided source definitions (id or URL). Clean all sources if no source definitions are provided." - def analyses(*source_defs) - addons = diggit.config.load_addons - diggit.sources.get_all(source_defs, {state: :finished}).each do |s| - globs = {} - diggit.config.load_analyses(s[:url], nil, addons, globs).each{ |a| a.clean} - s[:log][:state] = :cloned - s[:log][:analyses] = [] - s[:log][:error] = {} - diggit.sources.update(s) - say_done("cleaned analyses on #{s[:url]}") - end - end - - desc "joins", "Clean the configured joins." - def joins - addons = diggit.config.load_addons - globs = {} - diggit.config.load_joins(diggit.sources.get_all([], {state: :finished, error: false}), addons, globs).each{ |j| j.clean } - end - - end - - class DiggitCli < Thor - include Thor::Actions - include Utils - - def initialize(*args) - super - cmd = args[2][:current_command].name - unless 'init'.eql?(cmd) || 'help'.eql?(cmd) - unless File.exist?(DIGGIT_RC) - say_error("this is not a diggit directory") - else - diggit - end - end - end - - desc "init", "Initialize the current folder as a diggit folder." - def init - FileUtils.touch(DIGGIT_SOURCES) - Oj.to_file(DIGGIT_LOG, {}) - Oj.to_file(DIGGIT_RC, { addons: [], analyses: [], joins: [], options: {} }) - say_done("Diggit folder successfully initialized") - end - - desc 'status', "Display the status of the current diggit folder." - def status - color = (diggit.sources.get_all(nil, {error: true}).size > 0 && :red) || :blue - say_status('[sources]', "#{diggit.sources.get_all([], {state: :new}).size} new (#{diggit.sources.get_all([], {state: :new, error: true}).size} errors), #{diggit.sources.get_all([], {state: :cloned}).size} cloned (#{diggit.sources.get_all([], {state: :cloned, error: true}).size} errors), #{diggit.sources.get_all([], {state: :finished}).size} finished", color) - say_status('[addons]', "#{diggit.config.addons.join(', ')}", :blue) - say_status('[analyses]', "#{diggit.config.analyses.join(', ')}", :blue) - say_status('[joins]', "#{diggit.config.joins.join(', ')}", :blue) - say_status('[options]', "#{diggit.config.options}", :blue) - end - - desc "sources SUBCOMMAND ...ARGS", "manage sources for the current diggit folder." - subcommand "sources", SourcesCli - - desc "joins SUBCOMMAND ...ARGS", "manage joins for the current diggit folder." - subcommand "joins", JoinsCli - - desc "analyses SUBCOMMAND ...ARGS", "manage analyses for the current diggit folder." - subcommand "analyses", AnalysesCli - - desc "addons SUBCOMMAND ...ARGS", "manage addons for the current diggit folder." - subcommand "addons", AddonsCli - - desc "perform SUBCOMMAND ...ARGS", "perform actions in the current diggit folder." - subcommand "perform", PerformCli - - desc "clean SUBCOMMAND ...ARGS", "clean the current diggit folder." - subcommand "clean", CleanCli - - end - - end - -end diff --git a/ruby/diggit_cli_v1.rb b/ruby/diggit_cli_v1.rb deleted file mode 100644 index 57bcc5e..0000000 --- a/ruby/diggit_cli_v1.rb +++ /dev/null @@ -1,334 +0,0 @@ -require 'thor' -require 'fileutils' - -require_relative 'diggit_core' - -module Diggit - - module Utils - - DONE = '[done]' - WARNING = '[warning]' - ERROR = '[error]' - INFO = '[info]' - - def diggit - @diggit = Diggit.new if @diggit.nil? - return @diggit - end - - def dump_error(e) - { name: e.class.name, message: e.to_s, backtrace: e.backtrace } - end - - def plugin_ok?(name, type) - obj = Object::const_get(name) - return obj < type - rescue NameError - return false - end - - def source_color(source_hash) - if source_hash[:log][:error].empty? - return :blue - else - return :red - end - end - - def status_color(status) - if status == DONE - return :green - else - return :red - end - end - - def say_error(msg) - say_status(ERROR, msg, :red) - end - - def say_info(msg) - say_status(INFO, msg, :blue) - end - - def say_done(msg) - say_status(DONE, msg, :green) - end - - end - - module Cli - - class SourcesCli < Thor - include Thor::Actions - include Utils - - desc 'list', "Display the list of sources." - def list - idx = 1 - diggit.sources.hashes.each do |s| - say_status("[#{s[:log][:state]}]", "#{idx}: #{s[:url]}", source_color(s)) - idx += 1 - end - errors = diggit.sources.get_all(nil, {error: true}).size - status = (errors== 0 && DONE) || ERROR - say_status(status, "listed #{diggit.sources.size} sources including #{errors} errors", status_color(status)) - end - - desc 'info [SOURCE_DEF]', "Display informations on the provided source definition (either source URL or id)." - def info(source_def) - s = diggit.sources.get(source_def) - say_status("[#{s[:log][:state]}]", "#{s[:url]}", source_color(s)) - say_status('[folder]', "#{s[:folder]}", :blue) - unless s[:log][:error].empty? - say_error("#{s[:log][:error][:name]}") - say_status('[message]', "#{s[:log][:error][:message]}", :red) - say_status('[backtrace]', "", :red) - say(s[:log][:error][:backtrace].join("\n")) - end - end - - desc "errors", "Display informations on all source that have encountered an error." - def errors - diggit.sources.get_all(nil, {error: true}).each{|s| info s[:url] } - end - - desc 'import [FILE]', "Import a list of sources from a file (one URL per line)." - def import(urls_file) - IO.readlines(urls_file).each{ |line| diggit.sources.add(line.strip) } - end - - desc "add [URL*]", "Add the provided urls to the list of sources." - def add(*urls) - urls.each{ |u| diggit.sources.add(u) } - end - - desc "rem [SOURCE_DEF*]", "Remove the sources correspondign to the provided source definitions (id or URL) from the list of sources." - def rem(*sources_defs) - sources_defs.each { |s| diggit.sources.rem(s) } - end - end - - class AddonsCli < Thor - include Thor::Actions - include Utils - - desc "add [ADDON*]", "Add the provided addons to the list of active addons." - def add(*addons) - addons.each do |a| - if plugin_ok?(a, Addon) - diggit.config.add_addon(a) - else - say_error("error loading addon #{a}") - end - end - end - - desc "rem [ADDON*]", "Remove the provided addons from the list of active addons." - def rem(*addons) - addons.each{ |a| diggit.config.rem_addon(a) } - end - - end - - class JoinsCli < Thor - include Thor::Actions - include Utils - - desc "add [JOIN*]", "Add the provided joins to the list of active joins." - def add(*joins) - joins.each do |j| - if plugin_ok?(j, Join) - diggit.config.add_join(j) - else - say_error("error loading join #{j}") - end - end - end - - desc "rem [JOIN*]", "Remove the provided joins from the list of active joins." - def rem(*joins) - joins.each{ |j| diggit.config.rem_join(j) } - end - - end - - class AnalysesCli < Thor - include Thor::Actions - include Utils - - desc "add [ANALYSIS*]", "Add the provided analyses to the list of active analyses." - def add(*analyses) - analyses.each do |a| - if plugin_ok?(a, Analysis) - diggit.config.add_analysis(a) - else - say_error("error loading analysis #{a}") - end - end - end - - desc "rem [ANALYSIS*]", "Remove the provided analyses from the list of active analyses." - def rem(*analyses) - analyses.each{ |a| diggit.config.rem_analysis(a) } - end - - end - - class PerformCli < Thor - include Thor::Actions - include Utils - - desc "clones [SOURCE_DEFS*]", "Clone the sources corresponding to the provided source definitions (id or URL). Clone all sources if no source definitions are provided." - def clones(*source_defs) - diggit.sources.get_all(source_defs, {state: :new}).each do |s| - begin - if File.exist?(s[:folder]) - Rugged::Repository::new(s[:folder]) - else - Rugged::Repository::clone_at(s[:url], s[:folder], { - transfer_progress: lambda { |total_objects, indexed_objects, received_objects, local_objects, total_deltas, indexed_deltas, received_bytes| - msg = "Clone of #{s[:url]} in progress : #{received_objects}/#{total_objects} objects received.\r" - $stderr.print msg - @last_message_length = msg.length - } - }) - print " " * @last_message_length + "\r" # clean the line used to output transfer progress - end - rescue => e - s[:log][:error] = dump_error(e) - say_error("error cloning #{s[:url]}") - else - s[:log][:state] = :cloned - s[:log][:error] = {} - say_done("#{s[:url]} cloned") - ensure - diggit.sources.update(s) - end - end - end - - desc "analyses [SOURCE_DEFS*]", "Perform the configured analyses to the sources corresponding to the provided source definitions (id or URL). Analyze all sources if no source definitions are provided." - def analyses(*source_defs) - addons = diggit.config.load_addons - diggit.sources.get_all(source_defs, {state: :cloned}).each do |s| - FileUtils.cd(s[:folder]) - globs = {} - performed_analyses = [] - begin - repo = Rugged::Repository.new('.') - diggit.config.load_analyses(s[:url], repo, addons, globs).each do |a| - performed_analyses << a.class.to_s - a.run - end - rescue => e - s[:log][:error] = dump_error(e) - s[:log][:analyses] = performed_analyses[1..-2] - say_error("error performing #{performed_analyses.last} on #{s[:url]}") - else - s[:log][:analyses] = performed_analyses - s[:log][:state] = :finished - s[:log][:error] = {} - say_done("source #{s[:url]} analyzed") - ensure - FileUtils.cd(diggit.root) - diggit.sources.update(s) - end - end - end - - desc "joins", "Perform the configured joins." - def joins - addons = diggit.config.load_addons - globs = {} - diggit.config.load_joins(diggit.sources.get_all([], {state: :finished, error: false}), addons, globs).each{ |j| j.run } - say_done("joins performed") - end - - end - - class CleanCli < Thor - include Thor::Actions - include Utils - - desc "analyses", "Clean the configured analyzes on the provided source definitions (id or URL). Clean all sources if no source definitions are provided." - def analyses(*source_defs) - addons = diggit.config.load_addons - diggit.sources.get_all(source_defs, {state: :finished}).each do |s| - globs = {} - diggit.config.load_analyses(s[:url], nil, addons, globs).each{ |a| a.clean} - s[:log][:state] = :cloned - s[:log][:analyses] = [] - s[:log][:error] = {} - diggit.sources.update(s) - say_done("cleaned analyses on #{s[:url]}") - end - end - - desc "joins", "Clean the configured joins." - def joins - addons = diggit.config.load_addons - globs = {} - diggit.config.load_joins(diggit.sources.get_all([], {state: :finished, error: false}), addons, globs).each{ |j| j.clean } - end - - end - - class DiggitCli < Thor - include Thor::Actions - include Utils - - def initialize(*args) - super - cmd = args[2][:current_command].name - unless 'init'.eql?(cmd) || 'help'.eql?(cmd) - unless File.exist?(DIGGIT_RC) - say_error("this is not a diggit directory") - else - diggit - end - end - end - - desc "init", "Initialize the current folder as a diggit folder." - def init - FileUtils.touch(DIGGIT_SOURCES) - Oj.to_file(DIGGIT_LOG, {}) - Oj.to_file(DIGGIT_RC, { addons: [], analyses: [], joins: [], options: {} }) - say_done("Diggit folder successfully initialized") - end - - desc 'status', "Display the status of the current diggit folder." - def status - color = (diggit.sources.get_all(nil, {error: true}).size > 0 && :red) || :blue - say_status('[sources]', "#{diggit.sources.get_all([], {state: :new}).size} new (#{diggit.sources.get_all([], {state: :new, error: true}).size} errors), #{diggit.sources.get_all([], {state: :cloned}).size} cloned (#{diggit.sources.get_all([], {state: :cloned, error: true}).size} errors), #{diggit.sources.get_all([], {state: :finished}).size} finished", color) - say_status('[addons]', "#{diggit.config.addons.join(', ')}", :blue) - say_status('[analyses]', "#{diggit.config.analyses.join(', ')}", :blue) - say_status('[joins]', "#{diggit.config.joins.join(', ')}", :blue) - say_status('[options]', "#{diggit.config.options}", :blue) - end - - desc "sources SUBCOMMAND ...ARGS", "manage sources for the current diggit folder." - subcommand "sources", SourcesCli - - desc "joins SUBCOMMAND ...ARGS", "manage joins for the current diggit folder." - subcommand "joins", JoinsCli - - desc "analyses SUBCOMMAND ...ARGS", "manage analyses for the current diggit folder." - subcommand "analyses", AnalysesCli - - desc "addons SUBCOMMAND ...ARGS", "manage addons for the current diggit folder." - subcommand "addons", AddonsCli - - desc "perform SUBCOMMAND ...ARGS", "perform actions in the current diggit folder." - subcommand "perform", PerformCli - - desc "clean SUBCOMMAND ...ARGS", "clean the current diggit folder." - subcommand "clean", CleanCli - - end - - end - -end diff --git a/xml/directory_v0.xml b/xml/directory_v0.xml deleted file mode 100644 index 96bee3d..0000000 --- a/xml/directory_v0.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/xml/directory_v1.xml b/xml/directory_v1.xml deleted file mode 100644 index 99a2912..0000000 --- a/xml/directory_v1.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From ac3dcc65f1ef1456fd7cd064787cc3d5086fd3a0 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Wed, 25 Sep 2019 08:55:51 -0400 Subject: [PATCH 02/19] remove conflict --- Example_v0.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/Example_v0.java b/Example_v0.java index d15e3ec..01fe7b1 100644 --- a/Example_v0.java +++ b/Example_v0.java @@ -10,26 +10,16 @@ public void hello() { System.out.println("Adds 10"); System.out.println("Multiplies by 10"); System.out.println("And displays it"); -<<<<<<< HEAD int i = random(); System.out.println(i); } public int random() { -======= ->>>>>>> 450f97f58b5d67956d06bd9848b426a40fbdb90e Random r = new Random(); int i = r.nextInt(); i += 10; i *= 10; -<<<<<<< HEAD return i; } -} -======= - System.out.println(i); - } - -} ->>>>>>> 450f97f58b5d67956d06bd9848b426a40fbdb90e +} \ No newline at end of file From 8b2f8eb2e1234ebee9caac2a92c0db3c8332ea59 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Wed, 25 Sep 2019 09:14:56 -0400 Subject: [PATCH 03/19] Update Example_v0.java --- Example_v0.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Example_v0.java b/Example_v0.java index 01fe7b1..e763736 100644 --- a/Example_v0.java +++ b/Example_v0.java @@ -10,8 +10,8 @@ public void hello() { System.out.println("Adds 10"); System.out.println("Multiplies by 10"); System.out.println("And displays it"); - int i = random(); - System.out.println(i); + int k = random(); + System.out.println(k); } public int random() { @@ -22,4 +22,4 @@ public int random() { return i; } -} \ No newline at end of file +} From faa2edcd1933d287033d864d07e9d21c0758cf97 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Sun, 10 Nov 2019 20:51:13 -0500 Subject: [PATCH 04/19] Update Example_v0.java --- Example_v0.java | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/Example_v0.java b/Example_v0.java index e763736..36235a2 100644 --- a/Example_v0.java +++ b/Example_v0.java @@ -1,25 +1,16 @@ -import java.util.Random; +public class A { + private static int X; + private static int Y = 5; -public class Example { + public A(){ + A.X = 5; + } - public void hello() { - System.out.println("Hello everybody!"); - System.out.println("This code is a magnificent example"); - System.out.println("For the ASE 2014 conference"); - System.out.println("It draws a number at random"); - System.out.println("Adds 10"); - System.out.println("Multiplies by 10"); - System.out.println("And displays it"); - int k = random(); - System.out.println(k); - } - - public int random() { - Random r = new Random(); - int i = r.nextInt(); - i += 10; - i *= 10; - return i; - } + public int fcn(){ + return A.X * A.Y; + } + public int test(){ + return A.X * A.Y; + } } From 224a1e8681aa673570637ff67868178d362403c4 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Mon, 11 Nov 2019 19:56:54 -0500 Subject: [PATCH 05/19] Update Example_v0.java --- Example_v0.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Example_v0.java b/Example_v0.java index c696b4b..413cf83 100644 --- a/Example_v0.java +++ b/Example_v0.java @@ -5,12 +5,12 @@ public class A { public A(){ A.X = 5; } - - public int fcn(){ + + public int test(){ return A.X * A.Y; } - public int test(){ + public int fcn(){ return A.X * A.Y; } -} \ No newline at end of file +} From 5685108570ae6e7ff29f2e1e1d693644aa06d562 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Mon, 11 Nov 2019 19:59:16 -0500 Subject: [PATCH 06/19] Update Example_v0.java --- Example_v0.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Example_v0.java b/Example_v0.java index 413cf83..9fb13cd 100644 --- a/Example_v0.java +++ b/Example_v0.java @@ -6,11 +6,15 @@ public A(){ A.X = 5; } - public int test(){ + public int fcn(){ return A.X * A.Y; } - - public int fcn(){ + + public int test(){ return A.X * A.Y; } + + public int test2(){ + return 1 + 2; + } } From e51c1afa007aa43737603f01b421e5d19c342f84 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Tue, 12 Nov 2019 11:03:07 -0500 Subject: [PATCH 07/19] Update Example_v0.java --- Example_v0.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Example_v0.java b/Example_v0.java index 9fb13cd..b453957 100644 --- a/Example_v0.java +++ b/Example_v0.java @@ -13,8 +13,4 @@ public int fcn(){ public int test(){ return A.X * A.Y; } - - public int test2(){ - return 1 + 2; - } } From 1e64b7a4278ac29b97b683feb371905fa974a07a Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Tue, 12 Nov 2019 11:42:09 -0500 Subject: [PATCH 08/19] Update Example_v0.java --- Example_v0.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Example_v0.java b/Example_v0.java index b453957..7faddb3 100644 --- a/Example_v0.java +++ b/Example_v0.java @@ -13,4 +13,8 @@ public int fcn(){ public int test(){ return A.X * A.Y; } + + public int test(){ + return 15 + 26; + } } From 78ba7ea9d2a3ffbe60bce8eb5bdf39663cf67833 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Tue, 12 Nov 2019 15:21:16 -0500 Subject: [PATCH 09/19] Update Example_v0.java --- Example_v0.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Example_v0.java b/Example_v0.java index 7faddb3..b54b384 100644 --- a/Example_v0.java +++ b/Example_v0.java @@ -17,4 +17,8 @@ public int test(){ public int test(){ return 15 + 26; } + + public int test3(){ + return 999 - 25; + } } From 2d773bf7e6bd3352921fb078323c016fcc9875cb Mon Sep 17 00:00:00 2001 From: Phillip Pavlich Date: Mon, 30 Dec 2019 18:01:18 -0500 Subject: [PATCH 10/19] Create Example V2 Trying to test diffs between multiple files --- Example_v1.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Example_v1.java diff --git a/Example_v1.java b/Example_v1.java new file mode 100644 index 0000000..8680ab6 --- /dev/null +++ b/Example_v1.java @@ -0,0 +1,12 @@ +public class B { + private static int first; + private static int second = 5; + + public B(){ + B.first = 21; + } + + public int mult(){ + return B.first * B.second; + } +} From 24c9a4bee826a28637614fe130c24e6ca50dee65 Mon Sep 17 00:00:00 2001 From: Phillip Pavlich Date: Mon, 30 Dec 2019 18:05:42 -0500 Subject: [PATCH 11/19] alter example v2 changing 2nd file --- Example_v1.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Example_v1.java b/Example_v1.java index 8680ab6..69e97d8 100644 --- a/Example_v1.java +++ b/Example_v1.java @@ -1,11 +1,16 @@ public class B { private static int first; private static int second = 5; + private static int third = 52; public B(){ B.first = 21; } + public int add(){ + return B.first + B.second; + } + public int mult(){ return B.first * B.second; } From dd083e40b770f8961720212cac485c946f84e2c1 Mon Sep 17 00:00:00 2001 From: Phillip Pavlich Date: Mon, 30 Dec 2019 18:08:38 -0500 Subject: [PATCH 12/19] modify 1st file in patch --- Example_v0.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Example_v0.java b/Example_v0.java index b54b384..05dc9ea 100644 --- a/Example_v0.java +++ b/Example_v0.java @@ -21,4 +21,8 @@ public int test(){ public int test3(){ return 999 - 25; } + + public int test4(){ + return 999 - 25; + } } From 6f7cceb76aab17ec5228c250304c18559a27bf22 Mon Sep 17 00:00:00 2001 From: Phillip Pavlich Date: Tue, 17 Mar 2020 22:46:40 -0400 Subject: [PATCH 13/19] create A example --- AExample | 1 + 1 file changed, 1 insertion(+) create mode 100644 AExample diff --git a/AExample b/AExample new file mode 100644 index 0000000..aa90cfc --- /dev/null +++ b/AExample @@ -0,0 +1 @@ +public int x = 6; From 3483da3d15db3375ca4f89ebe021acf33f83ee39 Mon Sep 17 00:00:00 2001 From: Phillip Pavlich Date: Tue, 17 Mar 2020 22:49:07 -0400 Subject: [PATCH 14/19] Create BExample.java --- BExample.java | 1 + 1 file changed, 1 insertion(+) create mode 100644 BExample.java diff --git a/BExample.java b/BExample.java new file mode 100644 index 0000000..2252546 --- /dev/null +++ b/BExample.java @@ -0,0 +1 @@ +public String cool = "new comment"; From f9463cd0e209def463649034027cea97d2a16208 Mon Sep 17 00:00:00 2001 From: Phillip Pavlich Date: Tue, 17 Mar 2020 22:49:53 -0400 Subject: [PATCH 15/19] Create CExample.java --- Other Files/CExample.java | 1 + 1 file changed, 1 insertion(+) create mode 100644 Other Files/CExample.java diff --git a/Other Files/CExample.java b/Other Files/CExample.java new file mode 100644 index 0000000..f590cfc --- /dev/null +++ b/Other Files/CExample.java @@ -0,0 +1 @@ +public int phil =9; From 6f5bbda58e8eb253f8ea95e8fe0cadcbac340f88 Mon Sep 17 00:00:00 2001 From: Nikhil <12703092+patel-nikhil@users.noreply.github.com> Date: Sat, 11 Apr 2020 00:04:14 -0400 Subject: [PATCH 16/19] Update Example_v0.java --- Example_v0.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Example_v0.java b/Example_v0.java index 05dc9ea..5f99d41 100644 --- a/Example_v0.java +++ b/Example_v0.java @@ -6,6 +6,7 @@ public A(){ A.X = 5; } + /** Javadoc for fcn **/ public int fcn(){ return A.X * A.Y; } From 04f1ce3d0ac5c7d2e804768e5c43f81a16e609da Mon Sep 17 00:00:00 2001 From: Phillip Pavlich Date: Sat, 11 Apr 2020 12:24:02 -0400 Subject: [PATCH 17/19] v0 update so no two identical methods --- Example_v0.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Example_v0.java b/Example_v0.java index 5f99d41..0d3ec69 100644 --- a/Example_v0.java +++ b/Example_v0.java @@ -15,7 +15,7 @@ public int test(){ return A.X * A.Y; } - public int test(){ + public int test2(){ return 15 + 26; } From 30259e639ddaab018932afca6506f6721dce7624 Mon Sep 17 00:00:00 2001 From: Phillip Pavlich Date: Sat, 11 Apr 2020 12:41:32 -0400 Subject: [PATCH 18/19] v0 tweaks --- Example_v0.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Example_v0.java b/Example_v0.java index 0d3ec69..bb8f944 100644 --- a/Example_v0.java +++ b/Example_v0.java @@ -1,3 +1,5 @@ +package mypack; + public class A { private static int X; private static int Y = 5; @@ -26,4 +28,8 @@ public int test3(){ public int test4(){ return 999 - 25; } + + public String printHello(){ + return "Hello World!"; + } } From d025c54ee5e83bf563a1789efdccae45e61ae351 Mon Sep 17 00:00:00 2001 From: Phillip Pavlich Date: Sat, 11 Apr 2020 17:16:08 -0400 Subject: [PATCH 19/19] v0 import mods --- Example_v1.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Example_v1.java b/Example_v1.java index 69e97d8..4e3d4a6 100644 --- a/Example_v1.java +++ b/Example_v1.java @@ -1,3 +1,6 @@ +import java.util.List; +import java.util.regex.*; + public class B { private static int first; private static int second = 5;